排他的キーイベントの取得

キーイベントを排他的に取得するためのサンプルコード。

 

BD-JではEventManagerを通じて、インプットフォーカスを得ていないXletがキーイベントを取得する機能を提供している。しかし、万が一不正なアプリがまぎれこんでしまった場合、この機能によりユーザのキー入力がこっそり盗まれてしまう危険性をはらんでいる。
この問題を解決するため、指定したキーイベントについて、インプットフォーカスを得ているXletが排他的に取得できる。言い換えるとフォーカスを得ていないXletからは取得できなくする手段が用意されている。

 

本サンプルは、取得したキーイベントを表示する2個のJavaプログラムで構成されている。数字キーイベントのみ画面の左半分にしか表示されないことに注目。
  • Main.java: 正規のアプリ。数字キーを排他的に取得。画面の左半分
  • Monitor.java: 不正なアプリ。EventManagerを使って、数字キー・カラーキー・カーソルキーを取得。画面の右半分

 

Main.java

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
 
import javax.tv.xlet.Xlet;
import javax.tv.xlet.XletContext;
import org.davic.resources.ResourceClient;
import org.davic.resources.ResourceProxy;
import org.dvb.event.EventManager;
import org.dvb.event.UserEventRepository;
import org.havi.ui.HScene;
import org.havi.ui.HSceneFactory;
import org.havi.ui.HSceneTemplate;
import org.havi.ui.event.HRcCapabilities;
 
public class Main implements Xlet, KeyListener, ResourceClient{
    Graphics g = null;
    int x = 100, y = 50;
    public void initXlet(XletContext xc){
        try {
            HSceneFactory hsf= HSceneFactory.getInstance();
            HSceneTemplate hst = new HSceneTemplate();
            hst.setPreference(HSceneTemplate.SCENE_PIXEL_DIMENSION,
                    new Dimension(960, 1080),
                    HSceneTemplate.REQUIRED);
            hst.setPreference(HSceneTemplate.SCENE_PIXEL_LOCATION,
                    new Point(0, 0),
                    HSceneTemplate.REQUIRED);
            HScene hs = hsf.getBestScene(hst);
            hs.setVisible(true);
            g = hs.getGraphics();
            g.setColor(Color.blue);
            g.fillRect(0, 0, hs.getWidth(), hs.getHeight());
            g.setFont(new Font(null, Font.PLAIN, 32));
            g.setColor(Color.white);
            g.drawString("[Legitimate Application]", x, y); y+=35;
            // 数字キーを排他取得するよう設定
            UserEventRepository uer = new UserEventRepository("test");
            uer.addAllNumericKeys();
            EventManager.getInstance().addExclusiveAccessToAWTEvent(this, uer);
            // KeyListnerの登録とフォーカスの取得
            hs.addKeyListener(this);
            hs.requestFocus();
        } catch (Throwable thr){
        }
    }
    public void startXlet(){}
    public void pauseXlet(){}
    public void destroyXlet(boolean unconditional){}
    // KeyListenerを実装
    public void keyPressed(KeyEvent e) {}
    public void keyReleased(KeyEvent e) {
        g.drawString("KeyEvent:"+HRcCapabilities.getRepresentation(e.getKeyCode()).getString(), x, y); y+=35;
    }
    public void keyTyped(KeyEvent e) {}
    // ResourceClientを実装
    public void notifyRelease(ResourceProxy arg0) {}
    public void release(ResourceProxy arg0) {}
    public boolean requestRelease(ResourceProxy arg0, Object arg1) {return false;}
 
}

 

Monitor.java

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
 
import javax.tv.service.SIManager;
import javax.tv.service.selection.ServiceContextFactory;
import javax.tv.xlet.Xlet;
import javax.tv.xlet.XletContext;
import org.bluray.net.BDLocator;
import org.bluray.ti.Title;
import org.bluray.ti.selection.TitleContext;
import org.bluray.ui.event.HRcEvent;
import org.dvb.event.EventManager;
import org.dvb.event.UserEvent;
import org.dvb.event.UserEventListener;
import org.dvb.event.UserEventRepository;
import org.havi.ui.HScene;
import org.havi.ui.HSceneFactory;
import org.havi.ui.HSceneTemplate;
import org.havi.ui.event.HRcCapabilities;
 
public class Monitor implements Xlet, UserEventListener {
    int x=100, y=50;
    Graphics g = null;
    public void initXlet(XletContext xc){
        try {
            HSceneFactory hsf= HSceneFactory.getInstance();
            HSceneTemplate hst = new HSceneTemplate();
            hst.setPreference(HSceneTemplate.SCENE_PIXEL_DIMENSION,
                    new Dimension(960, 1080),
                    HSceneTemplate.REQUIRED);
            hst.setPreference(HSceneTemplate.SCENE_PIXEL_LOCATION,
                    new Point(960, 0),
                    HSceneTemplate.REQUIRED);
            HScene hs = hsf.getBestScene(hst);
            Font font = new Font(null, java.awt.Font.BOLD, 48);
            hs.setFont(font);
            hs.setVisible(true);
            g = hs.getGraphics();
            g.setColor(Color.red);
            g.fillRect(0, 0, hs.getWidth(), hs.getHeight());
            g.setFont(new Font(null, Font.PLAIN, 32));
            g.setColor(Color.white);
            g.drawString("[Malicious Application]", x, y); y+=35;
            // 数字キー、カラーキー、矢印キーの横取りを試みる
            UserEventRepository uer = new UserEventRepository("test");
            uer.addAllArrowKeys();
            uer.addAllColourKeys();
            uer.addAllNumericKeys();
            EventManager.getInstance().addUserEventListener(this, uer);
            // Title 1へ切り替え
            TitleContext tc = (TitleContext) ServiceContextFactory.getInstance().getServiceContext(xc);
            SIManager sim = SIManager.createInstance();
            Title t = (Title)sim.getService(new BDLocator("bd://1"));
            tc.select(t);
        } catch (Throwable thr){
        }
    }
    public void startXlet(){    }
    public void pauseXlet(){    }
    public void destroyXlet(boolean unconditional){}
    // UserEventListenerを実装
    public void userEventReceived(UserEvent e) {
        if( e.getType() == HRcEvent.KEY_RELEASED ){
            g.drawString("UserEvent:"+HRcCapabilities.getRepresentation(e.getCode()).getString(), x, y); y+=35;
        }
    }
}

関連する項目

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください