Package nfc.sample.nfctransaction.ui

Source Code of nfc.sample.nfctransaction.ui.NfcTransScreen

package nfc.sample.nfctransaction.ui;

/*
* Copyright (c) 2012 Research In Motion Limited.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import net.rim.device.api.command.Command;
import net.rim.device.api.io.nfc.NFCException;
import net.rim.device.api.io.nfc.NFCManager;
import net.rim.device.api.io.nfc.se.SecureElement;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.Display;
import net.rim.device.api.system.RuntimeStore;
import net.rim.device.api.ui.Color;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.FocusChangeListener;
import net.rim.device.api.ui.MenuItem;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.BitmapField;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.container.AbsoluteFieldManager;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.decor.Background;
import net.rim.device.api.ui.decor.BackgroundFactory;
import net.rim.device.api.util.StringProvider;
import nfc.sample.nfctransaction.Constants;
import nfc.sample.nfctransaction.NfcTransHandlerApp;
import nfc.sample.nfctransaction.Settings;
import nfc.sample.nfctransaction.Utilities;
import nfc.sample.nfctransaction.commands.ClearCommand;
import nfc.sample.nfctransaction.commands.CloseCommand;
import nfc.sample.nfctransaction.commands.KillCommand;
import nfc.sample.nfctransaction.commands.Iso7816Command;
import nfc.sample.nfctransaction.commands.SettingsCommand;
import nfc.sample.nfctransaction.commands.ToggleCeCommand;
import nfc.sample.nfctransaction.nfc.CardEmulation;
import nfc.sample.nfctransaction.nfc.MyNfcStatusListener;
import nfc.sample.nfctransaction.nfc.NfcService;
import nfc.sample.nfctransaction.ui.buttons.MsbConfig;
import nfc.sample.nfctransaction.ui.buttons.MsbState;
import nfc.sample.nfctransaction.ui.buttons.MultiStateButtonField;

public final class NfcTransScreen extends MainScreen implements Runnable {

    private static NfcTransScreen screen;
    private static MyNfcStatusListener nfc_status_listener = new MyNfcStatusListener();
    private Settings settings = Settings.getInstance();

    private NfcService nfc_service = NfcService.getInstance();
    private CardEmulation ce = CardEmulation.getInstance();

    private AbsoluteFieldManager mgr = new AbsoluteFieldManager();

    private Bitmap ce_on_focused = Bitmap.getBitmapResource("ce_on_focused.png");
    private Bitmap ce_on_unfocused = Bitmap.getBitmapResource("ce_on_unfocused.png");
    private Bitmap ce_on_clicked = Bitmap.getBitmapResource("ce_on_clicked.png");
    private Bitmap ce_on_unclicked = Bitmap.getBitmapResource("ce_on_focused.png");

    private Bitmap ce_off_focused = Bitmap.getBitmapResource("ce_off_focused.png");
    private Bitmap ce_off_unfocused = Bitmap.getBitmapResource("ce_off_unfocused.png");
    private Bitmap ce_off_clicked = Bitmap.getBitmapResource("ce_off_clicked.png");
    private Bitmap ce_off_unclicked = Bitmap.getBitmapResource("ce_off_focused.png");

    private Bitmap clear_focused = Bitmap.getBitmapResource("clear_focused.png");
    private Bitmap clear_unfocused = Bitmap.getBitmapResource("clear_unfocused.png");
    private Bitmap clear_clicked = Bitmap.getBitmapResource("clear_clicked.png");
    private Bitmap clear_unclicked = Bitmap.getBitmapResource("clear_focused.png");

    private Bitmap select_on_focused = Bitmap.getBitmapResource("select_focused.png");
    private Bitmap select_on_unfocused = Bitmap.getBitmapResource("select_unfocused.png");
    private Bitmap select_on_clicked = Bitmap.getBitmapResource("select_clicked.png");
    private Bitmap select_on_unclicked = Bitmap.getBitmapResource("select_focused.png");

    private Bitmap select_off_focused = Bitmap.getBitmapResource("select_disabled_focused.png");
    private Bitmap select_off_unfocused = Bitmap.getBitmapResource("select_disabled.png");
    private Bitmap select_off_clicked = Bitmap.getBitmapResource("select_disabled.png");
    private Bitmap select_off_unclicked = Bitmap.getBitmapResource("select_disabled.png");

    private Bitmap close_focused = Bitmap.getBitmapResource("close_focused.png");
    private Bitmap close_unfocused = Bitmap.getBitmapResource("close_unfocused.png");
    private Bitmap close_clicked = Bitmap.getBitmapResource("close_clicked.png");
    private Bitmap close_unclicked = Bitmap.getBitmapResource("close_focused.png");

    private Bitmap bmp_nfc_led_on = Bitmap.getBitmapResource("nfc_led_on.png");
    private Bitmap bmp_nfc_led_off = Bitmap.getBitmapResource("nfc_led_off.png");
    private Bitmap bmp_nfc_led_err = Bitmap.getBitmapResource("nfc_led_err.png");

    private Bitmap bmp_ce_led_on = Bitmap.getBitmapResource("ce_led_on.png");
    private Bitmap bmp_ce_led_off = Bitmap.getBitmapResource("ce_led_off.png");
    private Bitmap bmp_ce_led_err = Bitmap.getBitmapResource("ce_led_err.png");

    private BitmapField nfc_led = new BitmapField(bmp_nfc_led_off);
    private BitmapField cem_led = new BitmapField(bmp_ce_led_off);

    private LabelFieldColoured last_aids = new LabelFieldColoured("", Color.RED, Field.FIELD_HCENTER);
    private int last_aids_y;

    private TimedLabelField user_message = new TimedLabelField("", Field.FIELD_HCENTER);
    private int user_message_x;
    private int user_message_y;

    private Background focus_bg = BackgroundFactory.createSolidBackground(Color.LIGHTBLUE);

    private MenuItem mi_kill = new MenuItem(new StringProvider("Kill"), 110, 10);

    private MenuItem mi_settings = new MenuItem(new StringProvider("Settings"), 110, 10);

    private MultiStateButtonField msbf_ce_on;
    private MultiStateButtonField msbf_clear;
    private MultiStateButtonField msbf_select;
    private MultiStateButtonField msbf_close;

    private int focused_button = 0;

    boolean ce_enabled = false;
    boolean cem_led_err = false;
    boolean nfc_led_err = false;
   
    private FocusChangeListener focus_listener = new FocusChangeListener() {

        public void focusChanged(Field field, int eventType) {
            if(field == msbf_ce_on) {
                focused_button = 0;
            }
            if(field == msbf_clear) {
                focused_button = 1;
            }
            if(field == msbf_select) {
                focused_button = 2;
            }
            if(field == msbf_close) {
                focused_button = 3;
            }
        }
    };
   
    private FieldChangeListener centre_text_listener = new FieldChangeListener() {
        public void fieldChanged(Field field, int context) {
            if (field == user_message || field == last_aids) {
                LabelField label = (LabelField) field;
                String content = label.getText();
                int msg_width = Utilities.getTextWidth(content);
                int x = (Display.getWidth() - msg_width) / 2;
                int y=0;
                if (field == user_message) {
                    y = user_message_y;
                } else {
                    y = last_aids_y;
                }
                Utilities.log("XXXX " + Thread.currentThread().getName() + " repositioning user message:" + x+","+user_message_y);
                mgr.setPosChild(field, x, y);
            }
        }
    };

    public static synchronized NfcTransScreen getInstance() {
        if(screen == null) {
            screen = new NfcTransScreen();
        }
        return screen;
    }

    private NfcTransScreen() {
        super(USE_ALL_HEIGHT | USE_ALL_WIDTH | FIELD_HCENTER | NO_VERTICAL_SCROLL);
        Utilities.log("XXXX " + Thread.currentThread().getName() + " constructing NfcTransScreen");
        setTitle("NFCTransactionHandler V" + Constants.VERSION);

        clearLastAIDs();
       
        user_message.setChangeListener(centre_text_listener);
        last_aids.setChangeListener(centre_text_listener);

        mi_kill.setCommandContext(this);
        mi_kill.setCommand(new Command(new KillCommand()));
        addMenuItem(mi_kill);

        mi_settings.setCommandContext(this);
        mi_settings.setCommand(new Command(new SettingsCommand()));
        addMenuItem(mi_settings);

        try {
            if(nfc_service.isNfcEnabled()) {
                nfc_led = new BitmapField(bmp_nfc_led_on);
            } else {
                nfc_led = new BitmapField(bmp_nfc_led_off);
            }
        } catch(NFCException e2) {
            Utilities.log("XXXX " + Thread.currentThread().getName() + " from isNfcEnabled()");
            nfc_led = new BitmapField(bmp_nfc_led_err);
        }
        nfc_led.setPadding(7, 0, 0, 0);

        try {
            ce.initCe(ce.getCurrentSecureElement());
            if(!ce.isSe_obtained()) {
                Utilities.log("XXXX " + Thread.currentThread().getName() + " SecureElement(SIM) not available");
                setUserMessage("Error: could not acquire SE");
                cem_led_err = true;
            } else {
                try {
                    ce_enabled = ce.isCeEnabled(SecureElement.BATTERY_ON_MODE);
                    if(ce_enabled) {
                        cem_led = new BitmapField(bmp_ce_led_on);
                    } else {
                        cem_led = new BitmapField(bmp_ce_led_off);
                    }
                } catch(Exception e) {
                    Utilities.log("XXXX " + Thread.currentThread().getName() + " exception when enabling CE: " + e.getClass().getName() + ":" + e.getMessage());
                    cem_led = new BitmapField(bmp_ce_led_err);
                }
            }
        } catch(NFCException e1) {
            Utilities.log("XXXX " + Thread.currentThread().getName() + " exception when getting SE: " + e1.getClass().getName() + ":" + e1.getMessage());
            setUserMessage("Error: could not acquire SE");
            nfc_led_err = true;
            cem_led_err = true;
        }
        cem_led.setPadding(7, 0, 0, 0);

        // bitmaps are 120 x 120
        int hgap = (int) ((Display.getWidth() - 240) / 3);
        int vgap = (int) (Display.getHeight() - 240) / 6;
        int x1 = hgap;
        int x2 = x1 + 120 + hgap;
        int y1 = bmp_nfc_led_on.getHeight() + 4;
        int y2 = y1 + 120 + (vgap / 4);
        int y3 = y2 + 120 + 10;
        last_aids_y = y3;
        user_message_y = y3 + vgap;
        user_message_x = (Display.getWidth() - Utilities.getTextWidth(Constants.READY)) / 2;
        int x_centre_1 = x1 + 60;
        int x_centre_2 = x2 + 60;
        int last_aids_x = (Display.getWidth() - Utilities.getTextWidth(Constants.AID_SPACE)) / 2;

        // centre LEDs over the button columns
        mgr.add(nfc_led, x_centre_1 - (bmp_nfc_led_on.getWidth() / 2), 0);
        mgr.add(cem_led, x_centre_2 - (bmp_ce_led_on.getWidth() / 2), 0);
       
        MsbConfig config1 = new MsbConfig();
        MsbState ce_off = new MsbState(Constants.BTN_CE_OFF, "Switch card emulation OFF", "CE OFF");
        ce_off.setbmp_focused(ce_off_focused);
        ce_off.setbmp_unfocused(ce_off_unfocused);
        ce_off.setbmp_clicked(ce_off_clicked);
        ce_off.setbmp_unclicked(ce_off_unclicked);
        config1.addState(ce_off);
        MsbState ce_on = new MsbState(Constants.BTN_CE_ON, "Switch card emulation ON", "CE ON");
        ce_on.setbmp_focused(ce_on_focused);
        ce_on.setbmp_unfocused(ce_on_unfocused);
        ce_on.setbmp_clicked(ce_on_clicked);
        ce_on.setbmp_unclicked(ce_on_unclicked);
        config1.addState(ce_on);
        msbf_ce_on = new MultiStateButtonField(config1, new ToggleCeCommand(), 0, Field.FIELD_HCENTER);
        mgr.add(msbf_ce_on, x1, y1);

        MsbConfig config2 = new MsbConfig();
        MsbState clear = new MsbState(Constants.BTN_DEFAULT, "Clear last AID received field", "Clear");
        clear.setbmp_focused(clear_focused);
        clear.setbmp_unfocused(clear_unfocused);
        clear.setbmp_clicked(clear_clicked);
        clear.setbmp_unclicked(clear_unclicked);
        config2.addState(clear);
        msbf_clear = new MultiStateButtonField(config2, new ClearCommand(), 0, Field.FIELD_HCENTER);
        mgr.add(msbf_clear, x2, y1);

        MsbConfig config3 = new MsbConfig();
        MsbState select_on = new MsbState(Constants.BTN_DEFAULT, "Select applet", "Select");
        select_on.setbmp_focused(select_on_focused);
        select_on.setbmp_unfocused(select_on_unfocused);
        select_on.setbmp_clicked(select_on_clicked);
        select_on.setbmp_unclicked(select_on_unclicked);
        config3.addState(select_on);
        MsbState select_off = new MsbState(Constants.BTN_SELECT_OFF, "Select applet", "Select");
        select_off.setbmp_focused(select_off_focused);
        select_off.setbmp_unfocused(select_off_unfocused);
        select_off.setbmp_clicked(select_off_clicked);
        select_off.setbmp_unclicked(select_off_unclicked);
        config3.addState(select_off);
        Iso7816Command select_command = new Iso7816Command();
        msbf_select = new MultiStateButtonField(config3, select_command, 0, Field.FIELD_HCENTER);
        mgr.add(msbf_select, x1, y2);

        MsbConfig config4 = new MsbConfig();
        MsbState close = new MsbState(0, "Send to background", "Close");
        close.setbmp_focused(close_focused);
        close.setbmp_unfocused(close_unfocused);
        close.setbmp_clicked(close_clicked);
        close.setbmp_unclicked(close_unclicked);
        config4.addState(close);
        msbf_close = new MultiStateButtonField(config4, new CloseCommand(), 0, Field.FIELD_HCENTER);
        mgr.add(msbf_close, x2, y2);
       
        mgr.add(last_aids, last_aids_x, last_aids_y);
        mgr.add(user_message, user_message_x, user_message_y);

        add(mgr);

        msbf_ce_on.setFocusListener(focus_listener);
        msbf_clear.setFocusListener(focus_listener);
        msbf_select.setFocusListener(focus_listener);
        msbf_close.setFocusListener(focus_listener);

        screen = this;
        setUiRunningIndication();
    }

    public void init() {
        setCeButtonState(ce_enabled);
        try {
            NFCManager.addNFCStatusListener(nfc_status_listener);
        } catch(NFCException e) {
            Utilities.log("XXXX exception when adding NFCStatusListener: " + e.getClass().getName() + ":" + e.getMessage());
        }
        focused_button = 0;
        msbf_ce_on.setFocus();
        msbf_ce_on.setImage();

    }

    private void setUiRunningIndication() {
        Object ui_running_token = new Object();
        RuntimeStore rts = RuntimeStore.getRuntimeStore();
        rts.replace(Constants.UI_IS_RUNNING, ui_running_token);
    }

    public void startRtsMonitorThread() {
        Thread thread = new Thread(this);
        thread.start();
    }

    public boolean onClose() {
        closeScreen();
        return false;
    }

    public void setAidsReceived(String aids) {
        Utilities.log("XXXX " + Thread.currentThread().getName() + " updating UI with AID:" + aids);
        synchronized(UiApplication.getUiApplication().getEventLock()) {
            last_aids.setText(aids);
        }
    }

    public void run() {
        boolean running = true;
        Utilities.log("XXXX " + Thread.currentThread().getName() + " Starting RuntimeStore monitoring for screen");
        while(running) {
            try {
                RuntimeStore rts = RuntimeStore.getRuntimeStore();
                try {
                    Utilities.log("XXXX " + Thread.currentThread().getName() + " waiting for object from RTS");
                    Object obj = rts.waitFor(NfcTransHandlerApp.PASSED_TO_UI_DATA_ID);
                    Utilities.log("XXXX " + Thread.currentThread().getName() + " got object from RTS=" + obj);
                    if(obj != null) {
                        String aids_received = (String) rts.remove(NfcTransHandlerApp.PASSED_TO_UI_DATA_ID);
                        Utilities.log("XXXX " + Thread.currentThread().getName() + " AIDs received are:" + aids_received);
                        setAidsReceived(Utilities.hexPresentation(aids_received));
                        UiApplication.getApplication().requestForeground();

                    }
                } catch(RuntimeException e) {
                    Utilities.log("XXXX " + Thread.currentThread().getName() + " RunTimeException - probably timed out waiting for object in RTS");
                }

            } catch(Exception e) {
                Utilities.log("XXXX " + Thread.currentThread().getName() + " Exception in RTS loop: " + e.getClass().getName() + ":" + e.getMessage());
                System.out.println("XXXX " + Thread.currentThread().getName() + " Exception in RTS loop: " + e.getClass().getName() + ":" + e.getMessage());
            }
        }
    }

    public void clearLastAIDs() {
        last_aids.setText(Constants.AID_SPACE);
        Utilities.log("XXXX " + Thread.currentThread().getName() + " AID field cleared");
    }

    public void closeScreen() {
        // don't actually close otherwise our thread which is receiving the NFC transactions will exit as the app will be fully
        // closed
        UiApplication.getUiApplication().requestBackground();
    }

    public void setNfcLed(int state) {
        synchronized(UiApplication.getEventLock()) {
            switch(state) {
            case Constants.LED_OFF:
                nfc_led.setBitmap(bmp_nfc_led_off);
                break;
            case Constants.LED_ON:
                nfc_led.setBitmap(bmp_nfc_led_on);
                break;
            case Constants.LED_ERR:
                Utilities.log("XXXX " + Thread.currentThread().getName() + " NFC LED set to ERR state");
                nfc_led.setBitmap(bmp_nfc_led_err);
                break;
            }
        }
    }

    public void setCemLed(final int state) {
        UiApplication.getUiApplication().invokeAndWait(new Runnable() {
            public void run() {
                switch(state) {
                case Constants.LED_OFF:
                    cem_led.setBitmap(bmp_ce_led_off);
                    break;
                case Constants.LED_ON:
                    cem_led.setBitmap(bmp_ce_led_on);
                    break;
                case Constants.LED_ERR:
                    Utilities.log("XXXX " + Thread.currentThread().getName() + " CEM LED set to ERR state");
                    cem_led.setBitmap(bmp_ce_led_err);
                    break;
                }
            }
        });
    }

    public void nfcStateChanged(boolean nfc_on, boolean ce_on) {
        if(nfc_on) {
            setNfcLed(Constants.LED_ON);
            if(ce_on) {
                setCemLed(Constants.LED_ON);
                setCeButtonState(true);
                setSelectButtonState(true);
            }
        } else {
            setNfcLed(Constants.LED_OFF);
            setCemLed(Constants.LED_OFF);
            setCeButtonState(false);
            setSelectButtonState(false);
            try {
                ce.setRoutingOff();
            } catch(NFCException e) {
            }
        }
    }

    public void setUserMessage(final String message) {
        UiApplication.getUiApplication().invokeAndWait(new Runnable() {
            public void run() {
                user_message.setLabelText(message);
            }
        });
    }

    public void setCeButtonState(final boolean on) {
        Utilities.log("XXXX " + Thread.currentThread().getName() + " setting CE button state to on=" + on);
        UiApplication.getUiApplication().invokeAndWait(new Runnable() {
            public void run() {
                if(on) {
                    msbf_ce_on.setMsbState(Constants.BTN_CE_OFF);
                } else {
                    msbf_ce_on.setMsbState(Constants.BTN_CE_ON);
                }
            }
        });
    }

    public void setSelectButtonState(final boolean on) {
        UiApplication.getUiApplication().invokeAndWait(new Runnable() {
            public void run() {
                if(on) {
                    msbf_select.setMsbState(Constants.BTN_SELECT_ON);
                } else {
                    msbf_select.setMsbState(Constants.BTN_SELECT_OFF);
                }
            }
        });
    }

    protected boolean navigationMovement(int dx, int dy, int status, int time) {

        int x_dir = 0;
        int y_dir = 0;

        if(dx > 0) {
            x_dir = 1;
        }
        if(dx < 0) {
            x_dir = -1;
        }

        if(dy > 0) {
            y_dir = 1;
        }
        if(dy < 0) {
            y_dir = -1;
        }
        setFocusedButton(x_dir, y_dir);
        return true;
    }

    private void setFocusedButton(int x_dir, int y_dir) {
        switch(focused_button) {
        case 0:
            if(x_dir == 1 && y_dir == 0) {
                focused_button = 1;
                msbf_clear.setFocus();
                return;
            }
            if(x_dir == 0 && y_dir == 1) {
                focused_button = 2;
                msbf_select.setFocus();
                return;
            }
            if(x_dir == 1 && y_dir == 1) {
                focused_button = 3;
                msbf_close.setFocus();
                return;
            }
            break;
        case 1:
            if(x_dir == -1 && y_dir == 0) {
                focused_button = 0;
                msbf_ce_on.setFocus();
                return;
            }
            if(x_dir == 0 && y_dir == 1) {
                focused_button = 3;
                msbf_close.setFocus();
                return;
            }
            if(x_dir == -1 && y_dir == 1) {
                focused_button = 2;
                msbf_select.setFocus();
                return;
            }
            break;
        case 2:
            if(x_dir == 1 && y_dir == 0) {
                focused_button = 3;
                msbf_close.setFocus();
                return;
            }
            if(x_dir == 0 && y_dir == -1) {
                focused_button = 0;
                msbf_ce_on.setFocus();
                return;
            }
            if(x_dir == 1 && y_dir == -1) {
                focused_button = 1;
                msbf_clear.setFocus();
                return;
            }
            break;
        case 3:
            if(x_dir == -1 && y_dir == 0) {
                focused_button = 2;
                msbf_select.setFocus();
                return;
            }
            if(x_dir == 0 && y_dir == -1) {
                focused_button = 1;
                msbf_clear.setFocus();
                return;
            }
            if(x_dir == -1 && y_dir == -1) {
                focused_button = 0;
                msbf_ce_on.setFocus();
                return;
            }
            break;
        }
    }

}
TOP

Related Classes of nfc.sample.nfctransaction.ui.NfcTransScreen

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.