/** Default constructor. Init key maps for all constraints */ public AlphaNumericInputMode() { String upperInLine = Resource.getString(ResourceConstants.LCDUI_TF_CAPS_ALPHA_KEY_MAP); upperKeyMap = getMapByLine(upperInLine); String lowerInLine = Resource.getString(ResourceConstants.LCDUI_TF_ALPHA_KEY_MAP); lowerKeyMap = getMapByLine(lowerInLine); String longInLine = Resource.getString(ResourceConstants.LCDUI_TF_ALPHA_DIGIT_KEY_MAP); longPressKeyMap = getMapByLine(longInLine); keyMaps = new char[3][][]; keyMaps[0] = upperKeyMap; keyMaps[1] = lowerKeyMap; keyMaps[2] = upperKeyMap; }
/** * Update URL and gauge of the progress form. * * @param url new URL, null to remove, "" to not change * @param size 0 if unknown, else size of object to download in K bytes * @param gaugeLabel label for progress gauge */ private void updateProgressForm(String url, int size, String gaugeLabel) { Gauge oldProgressGauge; Gauge progressGauge; StringItem urlItem; // We need to prevent "flashing" on fast development platforms. while (System.currentTimeMillis() - lastDisplayChange < GraphicalInstaller.ALERT_TIMEOUT) ; if (size <= 0) { progressGauge = new Gauge(gaugeLabel, false, Gauge.INDEFINITE, Gauge.CONTINUOUS_RUNNING); } else { progressGauge = new Gauge(gaugeLabel, false, size, 0); } oldProgressGauge = (Gauge) progressForm.get(progressGaugeIndex); progressForm.set(progressGaugeIndex, progressGauge); // this ends the background thread of gauge. oldProgressGauge.setValue(Gauge.CONTINUOUS_IDLE); if (url == null) { urlItem = new StringItem("", ""); progressForm.set(progressUrlIndex, urlItem); } else if (url.length() != 0) { urlItem = new StringItem(Resource.getString(ResourceConstants.AMS_WEBSITE) + ": ", url); progressForm.set(progressUrlIndex, urlItem); } lastDisplayChange = System.currentTimeMillis(); }
/** * Display the connecting form to the user, let call set actions. * * @param action action to put in the form's title * @param name name to in the form's title * @param url URL of a JAD * @param size 0 if unknown, else size of object to download in K bytes * @param gaugeLabel label for progress gauge * @return displayed form */ private Form displayProgressForm( String action, String name, String url, int size, String gaugeLabel) { Gauge progressGauge; StringItem urlItem; progressForm = new Form(null); progressForm.setTitle(action + " " + name); if (size <= 0) { progressGauge = new Gauge(gaugeLabel, false, Gauge.INDEFINITE, Gauge.CONTINUOUS_RUNNING); } else { progressGauge = new Gauge(gaugeLabel, false, size, 0); } progressGaugeIndex = progressForm.append(progressGauge); if (url == null) { urlItem = new StringItem("", ""); } else { urlItem = new StringItem(Resource.getString(ResourceConstants.AMS_WEBSITE) + ": ", url); } progressUrlIndex = progressForm.append(urlItem); display.setCurrent(progressForm); lastDisplayChange = System.currentTimeMillis(); return progressForm; }
/** Save the URL setting the user entered in to the urlTextBox. */ private void saveURLSetting() { String temp; Exception ex; temp = urlTextBox.getString(); ex = GraphicalInstaller.saveSettings(temp, MIDletSuite.INTERNAL_SUITE_ID); if (ex != null) { displayException(Resource.getString(ResourceConstants.EXCEPTION), ex.toString()); return; } defaultInstallListUrl = temp; displaySuccessMessage(Resource.getString(ResourceConstants.AMS_MGR_SAVED)); }
/** Ask the user for the URL. */ private void getUrl() { try { if (urlTextBox == null) { urlTextBox = new TextBox( Resource.getString(ResourceConstants.AMS_DISC_APP_WEBSITE_INSTALL), defaultInstallListUrl, 1024, TextField.ANY); urlTextBox.addCommand(endCmd); urlTextBox.addCommand(saveCmd); urlTextBox.addCommand(discoverCmd); urlTextBox.setCommandListener(this); } display.setCurrent(urlTextBox); } catch (Exception ex) { displayException(Resource.getString(ResourceConstants.EXCEPTION), ex.toString()); } }
/** * Install a suite. * * @param selectedSuite index into the installList */ private void installSuite(int selectedSuite) { MIDletStateHandler midletStateHandler = MIDletStateHandler.getMidletStateHandler(); MIDletSuite midletSuite = midletStateHandler.getMIDletSuite(); SuiteDownloadInfo suite; String displayName; suite = (SuiteDownloadInfo) installList.elementAt(selectedSuite); midletSuite.setTempProperty(null, "arg-0", "I"); midletSuite.setTempProperty(null, "arg-1", suite.url); midletSuite.setTempProperty(null, "arg-2", suite.label); displayName = Resource.getString(ResourceConstants.INSTALL_APPLICATION); try { midletStateHandler.startMIDlet("com.sun.midp.installer.GraphicalInstaller", displayName); /* * Give the create MIDlet notification 1 second to get to * AMS. */ Thread.sleep(1000); notifyDestroyed(); } catch (Exception ex) { StringBuffer sb = new StringBuffer(); sb.append(displayName); sb.append("\n"); sb.append(Resource.getString(ResourceConstants.ERROR)); sb.append(": "); sb.append(ex.toString()); Alert a = new Alert( Resource.getString(ResourceConstants.AMS_CANNOT_START), sb.toString(), null, AlertType.ERROR); a.setTimeout(Alert.FOREVER); display.setCurrent(a, urlTextBox); } }
/** Processes an execute MIDlet event outside of the event thread. */ public void run() { try { MIDletSuiteUtils.executeWithArgs( classSecurityToken, externalAppId, id, midlet, displayName, arg0, arg1, arg2); } catch (Throwable t) { if (Logging.TRACE_ENABLED) { Logging.trace(t, "Exception calling MIDletSuiteLoader.execute"); } MIDletSuiteUtils.displayException( displayEventHandler, Resource.getString(ResourceConstants.AMS_MIDLETSUITELDR_CANT_EXE_NEXT_MIDLET) + "\n\n" + t.getMessage()); } }
/** * The Graphical MIDlet suite Discovery Application. * * <p>Let the user install a suite from a list of suites obtained using an HTML URL given by the * user. This list is derived by extracting the links with hrefs that are in quotes and end with * ".jad" from the HTML page. An href in an extracted link is assumed to be an absolute URL for a * MIDP application descriptor. The selected URL is then passed to graphical Installer. */ public class DiscoveryApp extends MIDlet implements CommandListener { /** Display for this MIDlet. */ private Display display; /** Contains the default URL for the install list. */ private String defaultInstallListUrl = "http://"; /** Contains the URL the user typed in. */ private TextBox urlTextBox; /** Displays the progress of the install. */ private Form progressForm; /** Gauge for progress form index. */ private int progressGaugeIndex; /** URL for progress form index. */ private int progressUrlIndex; /** Keeps track of when the display last changed, in milliseconds. */ private long lastDisplayChange; /** Displays a list of suites to install to the user. */ private List installListBox; /** Contains a list of suites to install. */ private Vector installList; /** Command object for URL screen to go and discover available suites. */ private Command discoverCmd = new Command(Resource.getString(ResourceConstants.GOTO), Command.SCREEN, 1); /** Command object for "Install" command in the suite list form . */ private Command installCmd = new Command(Resource.getString(ResourceConstants.INSTALL), Command.ITEM, 1); /** Command object for "Back" command in the suite list form. */ private Command backCmd = new Command(Resource.getString(ResourceConstants.BACK), Command.BACK, 1); /** Command object for URL screen to save the URL for suites. */ private Command saveCmd = new Command(Resource.getString(ResourceConstants.SAVE), Command.SCREEN, 2); /** Command object for "Back" command in the URL form. */ private Command endCmd = new Command(Resource.getString(ResourceConstants.BACK), Command.BACK, 1); /** * Create and initialize a new discovery application MIDlet. The saved URL is retrieved and the * list of MIDlets are retrieved. */ public DiscoveryApp() { String storageName; display = Display.getDisplay(this); GraphicalInstaller.initSettings(); restoreSettings(); // get the URL of a list of suites to install getUrl(); } /** Start. */ public void startApp() {} /** Pause; there are no resources that need to be released. */ public void pauseApp() {} /** * Destroy cleans up. * * @param unconditional is ignored; this object always destroys itself when requested. */ public void destroyApp(boolean unconditional) {} /** * Respond to a command issued on any Screen. * * @param c command activated by the user * @param s the Displayable the command was on. */ public void commandAction(Command c, Displayable s) { if (c == discoverCmd) { // user wants to discover the suites that can be installed discoverSuitesToInstall(urlTextBox.getString()); } else if (s == installListBox && (c == List.SELECT_COMMAND || c == installCmd)) { installSuite(installListBox.getSelectedIndex()); } else if (c == backCmd) { display.setCurrent(urlTextBox); } else if (c == saveCmd) { saveURLSetting(); } else if (c == endCmd || c == Alert.DISMISS_COMMAND) { // goto back to the manager midlet notifyDestroyed(); } } /** Get the settings the Manager saved for the user. */ private void restoreSettings() { ByteArrayInputStream bas; DataInputStream dis; byte[] data; RecordStore settings = null; try { settings = RecordStore.openRecordStore(GraphicalInstaller.SETTINGS_STORE, false); data = settings.getRecord(1); if (data != null) { bas = new ByteArrayInputStream(data); dis = new DataInputStream(bas); defaultInstallListUrl = dis.readUTF(); } } catch (RecordStoreException e) { if (Logging.REPORT_LEVEL <= Logging.WARNING) { Logging.report( Logging.WARNING, LogChannels.LC_AMS, "restoreSettings threw a RecordStoreException"); } } catch (IOException e) { if (Logging.REPORT_LEVEL <= Logging.WARNING) { Logging.report(Logging.WARNING, LogChannels.LC_AMS, "restoreSettings threw an IOException"); } } finally { if (settings != null) { try { settings.closeRecordStore(); } catch (RecordStoreException e) { if (Logging.REPORT_LEVEL <= Logging.WARNING) { Logging.report( Logging.WARNING, LogChannels.LC_AMS, "closeRecordStore threw a RecordStoreException"); } } } } } /** Save the URL setting the user entered in to the urlTextBox. */ private void saveURLSetting() { String temp; Exception ex; temp = urlTextBox.getString(); ex = GraphicalInstaller.saveSettings(temp, MIDletSuite.INTERNAL_SUITE_ID); if (ex != null) { displayException(Resource.getString(ResourceConstants.EXCEPTION), ex.toString()); return; } defaultInstallListUrl = temp; displaySuccessMessage(Resource.getString(ResourceConstants.AMS_MGR_SAVED)); } /** * Alert the user that an action was successful. * * @param successMessage message to display to user */ private void displaySuccessMessage(String successMessage) { Image icon; Alert successAlert; icon = GraphicalInstaller.getImageFromInternalStorage("_dukeok8"); successAlert = new Alert(null, successMessage, icon, null); successAlert.setTimeout(GraphicalInstaller.ALERT_TIMEOUT); // We need to prevent "flashing" on fast development platforms. while (System.currentTimeMillis() - lastDisplayChange < GraphicalInstaller.ALERT_TIMEOUT) ; lastDisplayChange = System.currentTimeMillis(); display.setCurrent(successAlert); } /** * Let the user select a suite to install. The suites that are listed are the links on a web page * that end with .jad. * * @param url where to get the list of suites to install. */ private void discoverSuitesToInstall(String url) { new Thread(new BackgroundInstallListGetter(this, url)).start(); } /** * Display the connecting form to the user, let call set actions. * * @param action action to put in the form's title * @param name name to in the form's title * @param url URL of a JAD * @param size 0 if unknown, else size of object to download in K bytes * @param gaugeLabel label for progress gauge * @return displayed form */ private Form displayProgressForm( String action, String name, String url, int size, String gaugeLabel) { Gauge progressGauge; StringItem urlItem; progressForm = new Form(null); progressForm.setTitle(action + " " + name); if (size <= 0) { progressGauge = new Gauge(gaugeLabel, false, Gauge.INDEFINITE, Gauge.CONTINUOUS_RUNNING); } else { progressGauge = new Gauge(gaugeLabel, false, size, 0); } progressGaugeIndex = progressForm.append(progressGauge); if (url == null) { urlItem = new StringItem("", ""); } else { urlItem = new StringItem(Resource.getString(ResourceConstants.AMS_WEBSITE) + ": ", url); } progressUrlIndex = progressForm.append(urlItem); display.setCurrent(progressForm); lastDisplayChange = System.currentTimeMillis(); return progressForm; } /** * Install a suite. * * @param selectedSuite index into the installList */ private void installSuite(int selectedSuite) { MIDletStateHandler midletStateHandler = MIDletStateHandler.getMidletStateHandler(); MIDletSuite midletSuite = midletStateHandler.getMIDletSuite(); SuiteDownloadInfo suite; String displayName; suite = (SuiteDownloadInfo) installList.elementAt(selectedSuite); midletSuite.setTempProperty(null, "arg-0", "I"); midletSuite.setTempProperty(null, "arg-1", suite.url); midletSuite.setTempProperty(null, "arg-2", suite.label); displayName = Resource.getString(ResourceConstants.INSTALL_APPLICATION); try { midletStateHandler.startMIDlet("com.sun.midp.installer.GraphicalInstaller", displayName); /* * Give the create MIDlet notification 1 second to get to * AMS. */ Thread.sleep(1000); notifyDestroyed(); } catch (Exception ex) { StringBuffer sb = new StringBuffer(); sb.append(displayName); sb.append("\n"); sb.append(Resource.getString(ResourceConstants.ERROR)); sb.append(": "); sb.append(ex.toString()); Alert a = new Alert( Resource.getString(ResourceConstants.AMS_CANNOT_START), sb.toString(), null, AlertType.ERROR); a.setTimeout(Alert.FOREVER); display.setCurrent(a, urlTextBox); } } /** * Update URL and gauge of the progress form. * * @param url new URL, null to remove, "" to not change * @param size 0 if unknown, else size of object to download in K bytes * @param gaugeLabel label for progress gauge */ private void updateProgressForm(String url, int size, String gaugeLabel) { Gauge oldProgressGauge; Gauge progressGauge; StringItem urlItem; // We need to prevent "flashing" on fast development platforms. while (System.currentTimeMillis() - lastDisplayChange < GraphicalInstaller.ALERT_TIMEOUT) ; if (size <= 0) { progressGauge = new Gauge(gaugeLabel, false, Gauge.INDEFINITE, Gauge.CONTINUOUS_RUNNING); } else { progressGauge = new Gauge(gaugeLabel, false, size, 0); } oldProgressGauge = (Gauge) progressForm.get(progressGaugeIndex); progressForm.set(progressGaugeIndex, progressGauge); // this ends the background thread of gauge. oldProgressGauge.setValue(Gauge.CONTINUOUS_IDLE); if (url == null) { urlItem = new StringItem("", ""); progressForm.set(progressUrlIndex, urlItem); } else if (url.length() != 0) { urlItem = new StringItem(Resource.getString(ResourceConstants.AMS_WEBSITE) + ": ", url); progressForm.set(progressUrlIndex, urlItem); } lastDisplayChange = System.currentTimeMillis(); } /** Ask the user for the URL. */ private void getUrl() { try { if (urlTextBox == null) { urlTextBox = new TextBox( Resource.getString(ResourceConstants.AMS_DISC_APP_WEBSITE_INSTALL), defaultInstallListUrl, 1024, TextField.ANY); urlTextBox.addCommand(endCmd); urlTextBox.addCommand(saveCmd); urlTextBox.addCommand(discoverCmd); urlTextBox.setCommandListener(this); } display.setCurrent(urlTextBox); } catch (Exception ex) { displayException(Resource.getString(ResourceConstants.EXCEPTION), ex.toString()); } } /** * Display an exception to the user, with a done command. * * @param title exception form's title * @param message exception message */ private void displayException(String title, String message) { Alert a = new Alert(title, message, null, AlertType.ERROR); a.setTimeout(Alert.FOREVER); a.setCommandListener(this); display.setCurrent(a); } /** A class to get the install list in a background thread. */ private class BackgroundInstallListGetter implements Runnable { /** Parent application. */ private DiscoveryApp parent; /** URL of the list. */ private String url; /** * Construct a BackgroundInstallListGetter. * * @param theParent parent of this object * @param theUrl where to get the list of suites to install. */ private BackgroundInstallListGetter(DiscoveryApp theParent, String theUrl) { parent = theParent; url = theUrl; } /** * Get the list of suites for the user to install. The suites that are listed are the links on a * web page that end with .jad. */ public void run() { StreamConnection conn = null; InputStreamReader in = null; String errorMessage; long startTime; startTime = System.currentTimeMillis(); try { parent.displayProgressForm( Resource.getString(ResourceConstants.AMS_DISC_APP_GET_INSTALL_LIST), "", url, 0, Resource.getString(ResourceConstants.AMS_GRA_INTLR_CONN_GAUGE_LABEL)); conn = (StreamConnection) Connector.open(url, Connector.READ); in = new InputStreamReader(conn.openInputStream()); try { parent.updateProgressForm( "", 0, Resource.getString(ResourceConstants.AMS_DISC_APP_GAUGE_LABEL_DOWNLOAD)); parent.installList = SuiteDownloadInfo.getDownloadInfoFromPage(in); if (parent.installList.size() > 0) { parent.installListBox = new List( Resource.getString(ResourceConstants.AMS_DISC_APP_SELECT_INSTALL), Choice.IMPLICIT); // Add each suite for (int i = 0; i < parent.installList.size(); i++) { SuiteDownloadInfo suite = (SuiteDownloadInfo) installList.elementAt(i); parent.installListBox.append(suite.label, (Image) null); } parent.installListBox.addCommand(parent.backCmd); parent.installListBox.addCommand(parent.installCmd); parent.installListBox.setCommandListener(parent); /* * We need to prevent "flashing" on fast development * platforms. */ while (System.currentTimeMillis() - parent.lastDisplayChange < GraphicalInstaller.ALERT_TIMEOUT) ; parent.display.setCurrent(parent.installListBox); return; } errorMessage = Resource.getString(ResourceConstants.AMS_DISC_APP_CHECK_URL_MSG); } catch (IllegalArgumentException ex) { errorMessage = Resource.getString(ResourceConstants.AMS_DISC_APP_URL_FORMAT_MSG); } catch (Exception ex) { errorMessage = ex.getMessage(); } } catch (Exception ex) { errorMessage = Resource.getString(ResourceConstants.AMS_DISC_APP_CONN_FAILED_MSG); } finally { if (parent.progressForm != null) { // end the background thread of progress gauge. Gauge progressGauge = (Gauge) parent.progressForm.get(parent.progressGaugeIndex); progressGauge.setValue(Gauge.CONTINUOUS_IDLE); } try { conn.close(); in.close(); } catch (Exception e) { if (Logging.REPORT_LEVEL <= Logging.WARNING) { Logging.report(Logging.WARNING, LogChannels.LC_AMS, "close threw an Exception"); } } } Alert a = new Alert( Resource.getString(ResourceConstants.ERROR), errorMessage, null, AlertType.ERROR); a.setTimeout(Alert.FOREVER); parent.display.setCurrent(a, parent.urlTextBox); } } }
/** * Get the list of suites for the user to install. The suites that are listed are the links on a * web page that end with .jad. */ public void run() { StreamConnection conn = null; InputStreamReader in = null; String errorMessage; long startTime; startTime = System.currentTimeMillis(); try { parent.displayProgressForm( Resource.getString(ResourceConstants.AMS_DISC_APP_GET_INSTALL_LIST), "", url, 0, Resource.getString(ResourceConstants.AMS_GRA_INTLR_CONN_GAUGE_LABEL)); conn = (StreamConnection) Connector.open(url, Connector.READ); in = new InputStreamReader(conn.openInputStream()); try { parent.updateProgressForm( "", 0, Resource.getString(ResourceConstants.AMS_DISC_APP_GAUGE_LABEL_DOWNLOAD)); parent.installList = SuiteDownloadInfo.getDownloadInfoFromPage(in); if (parent.installList.size() > 0) { parent.installListBox = new List( Resource.getString(ResourceConstants.AMS_DISC_APP_SELECT_INSTALL), Choice.IMPLICIT); // Add each suite for (int i = 0; i < parent.installList.size(); i++) { SuiteDownloadInfo suite = (SuiteDownloadInfo) installList.elementAt(i); parent.installListBox.append(suite.label, (Image) null); } parent.installListBox.addCommand(parent.backCmd); parent.installListBox.addCommand(parent.installCmd); parent.installListBox.setCommandListener(parent); /* * We need to prevent "flashing" on fast development * platforms. */ while (System.currentTimeMillis() - parent.lastDisplayChange < GraphicalInstaller.ALERT_TIMEOUT) ; parent.display.setCurrent(parent.installListBox); return; } errorMessage = Resource.getString(ResourceConstants.AMS_DISC_APP_CHECK_URL_MSG); } catch (IllegalArgumentException ex) { errorMessage = Resource.getString(ResourceConstants.AMS_DISC_APP_URL_FORMAT_MSG); } catch (Exception ex) { errorMessage = ex.getMessage(); } } catch (Exception ex) { errorMessage = Resource.getString(ResourceConstants.AMS_DISC_APP_CONN_FAILED_MSG); } finally { if (parent.progressForm != null) { // end the background thread of progress gauge. Gauge progressGauge = (Gauge) parent.progressForm.get(parent.progressGaugeIndex); progressGauge.setValue(Gauge.CONTINUOUS_IDLE); } try { conn.close(); in.close(); } catch (Exception e) { if (Logging.REPORT_LEVEL <= Logging.WARNING) { Logging.report(Logging.WARNING, LogChannels.LC_AMS, "close threw an Exception"); } } } Alert a = new Alert( Resource.getString(ResourceConstants.ERROR), errorMessage, null, AlertType.ERROR); a.setTimeout(Alert.FOREVER); parent.display.setCurrent(a, parent.urlTextBox); }
/** * Construct PIN dialog. * * @param token security token with the permission to peempt the foreground display * @param action PIN entry operation identifier. * @param attr1 1st PIN attributes. * @param attr2 2nd PIN attributes. * @exception InterruptedException if another thread interrupts the calling thread while this * method is waiting to preempt the display. */ public PINEntryDialog(SecurityToken token, int action, PINAttributes attr1, PINAttributes attr2) throws InterruptedException { String title = null; String label1 = attr1.label; String label2 = null; pin1 = attr1; pin2 = null; switch (action) { case ACLPermissions.CMD_VERIFY: { // "PIN verification" title = Resource.getString(ResourceConstants.JSR177_PINDIALOG_TITLE_VERIFY); break; } case ACLPermissions.CMD_CHANGE: { // "Change PIN" title = Resource.getString(ResourceConstants.JSR177_PINDIALOG_TITLE_CHANGE); // "New value" -> "Enter new PIN" label2 = Resource.getString(ResourceConstants.JSR177_PINDIALOG_ENTERPIN); pin2 = attr1; break; } case ACLPermissions.CMD_DISABLE: { // "Disable PIN" title = Resource.getString(ResourceConstants.JSR177_PINDIALOG_TITLE_DISABLE); break; } case ACLPermissions.CMD_ENABLE: { // "Enable PIN"; title = Resource.getString(ResourceConstants.JSR177_PINDIALOG_TITLE_ENABLE); break; } case ACLPermissions.CMD_UNBLOCK: { // "Unblock PIN" title = Resource.getString(ResourceConstants.JSR177_PINDIALOG_TITLE_UNBLOCK); label1 = attr2.label; label2 = attr1.label + " - " + // "new value" Resource.getString(ResourceConstants.JSR177_PINDIALOG_NEWVALUE); pin1 = attr2; pin2 = attr1; break; } } Form form = new Form(title); int flags = TextField.PASSWORD; if (pin1.isNumeric()) { flags |= TextField.NUMERIC; } tf1 = new TextField(label1, "", pin1.getMaxLength(), flags); form.append(tf1); if (pin2 != null) { flags = TextField.SENSITIVE | TextField.NON_PREDICTIVE; if (pin2.isNumeric()) { flags |= TextField.NUMERIC; } tf2 = new TextField(label2, "", pin2.getMaxLength(), flags); form.append(tf2); } form.addCommand(cancelCmd); form.addCommand(okCmd); form.setCommandListener(this); if (displayEventHandler == null) { displayEventHandler = DisplayEventHandlerFactory.getDisplayEventHandler(token); } preemptToken = displayEventHandler.preemptDisplay(form, true); }
/** Implements PIN entry dialog. */ public class PINEntryDialog implements CommandListener { /** Answer that indicates that the dialog was cancelled. */ private static final int CANCELLED = -1; /** Answer that indicates successful completion. */ private static final int CONFIRMED = 1; /** Caches the display manager reference. */ private DisplayEventHandler displayEventHandler; /** Command object for "OK" command. */ private Command okCmd = new Command(Resource.getString(ResourceConstants.OK), Command.OK, 1); /** Command object for "Cancel" command. */ private Command cancelCmd = new Command(Resource.getString(ResourceConstants.CANCEL), Command.CANCEL, 1); /** Holds the preempt token so the form can end. */ private Object preemptToken; /** Holds the answer to the security question. */ private int answer = CANCELLED; /** PIN entry text field. */ private TextField tf1; /** PIN entry text field. */ private TextField tf2; /** Attributes of the 1st PIN. */ private PINAttributes pin1; /** Attributes of the 2nd PIN. */ private PINAttributes pin2; /** 1st PIN data. */ private byte[] data1; /** 2nd PIN data. */ private byte[] data2; /** * Construct PIN dialog. * * @param token security token with the permission to peempt the foreground display * @param action PIN entry operation identifier. * @param attr1 1st PIN attributes. * @param attr2 2nd PIN attributes. * @exception InterruptedException if another thread interrupts the calling thread while this * method is waiting to preempt the display. */ public PINEntryDialog(SecurityToken token, int action, PINAttributes attr1, PINAttributes attr2) throws InterruptedException { String title = null; String label1 = attr1.label; String label2 = null; pin1 = attr1; pin2 = null; switch (action) { case ACLPermissions.CMD_VERIFY: { // "PIN verification" title = Resource.getString(ResourceConstants.JSR177_PINDIALOG_TITLE_VERIFY); break; } case ACLPermissions.CMD_CHANGE: { // "Change PIN" title = Resource.getString(ResourceConstants.JSR177_PINDIALOG_TITLE_CHANGE); // "New value" -> "Enter new PIN" label2 = Resource.getString(ResourceConstants.JSR177_PINDIALOG_ENTERPIN); pin2 = attr1; break; } case ACLPermissions.CMD_DISABLE: { // "Disable PIN" title = Resource.getString(ResourceConstants.JSR177_PINDIALOG_TITLE_DISABLE); break; } case ACLPermissions.CMD_ENABLE: { // "Enable PIN"; title = Resource.getString(ResourceConstants.JSR177_PINDIALOG_TITLE_ENABLE); break; } case ACLPermissions.CMD_UNBLOCK: { // "Unblock PIN" title = Resource.getString(ResourceConstants.JSR177_PINDIALOG_TITLE_UNBLOCK); label1 = attr2.label; label2 = attr1.label + " - " + // "new value" Resource.getString(ResourceConstants.JSR177_PINDIALOG_NEWVALUE); pin1 = attr2; pin2 = attr1; break; } } Form form = new Form(title); int flags = TextField.PASSWORD; if (pin1.isNumeric()) { flags |= TextField.NUMERIC; } tf1 = new TextField(label1, "", pin1.getMaxLength(), flags); form.append(tf1); if (pin2 != null) { flags = TextField.SENSITIVE | TextField.NON_PREDICTIVE; if (pin2.isNumeric()) { flags |= TextField.NUMERIC; } tf2 = new TextField(label2, "", pin2.getMaxLength(), flags); form.append(tf2); } form.addCommand(cancelCmd); form.addCommand(okCmd); form.setCommandListener(this); if (displayEventHandler == null) { displayEventHandler = DisplayEventHandlerFactory.getDisplayEventHandler(token); } preemptToken = displayEventHandler.preemptDisplay(form, true); } /** * Waits for the user's answer. * * @return user's answer */ public int waitForAnswer() { synchronized (this) { if (preemptToken == null) { return CANCELLED; } try { wait(); } catch (Throwable t) { return CANCELLED; } return answer; } } /** * Sets the user's answer and notifies waitForAnswer and ends the form. * * @param theAnswer user's answer or CANCEL if system cancelled the screen */ private void setAnswer(int theAnswer) { synchronized (this) { answer = theAnswer; displayEventHandler.donePreempting(preemptToken); notify(); } } /** * Respond to a command issued on form. * * @param c command activiated by the user * @param s the Displayable the command was on. */ public void commandAction(Command c, Displayable s) { if (c == okCmd) { if (!checkInput()) { return; } setAnswer(CONFIRMED); } else { setAnswer(CANCELLED); } } /** * Verifies that the values entered are acceptable. * * @return true if the values entered are acceptable. */ private boolean checkInput() { if (tf1.getString().trim().equals("")) { return false; } data1 = pin1.transform(tf1.getString()); if (data1 == null) { // PIN can't be formatted, pass empty PIN to update counter data1 = new byte[8]; } if (pin2 != null) { data2 = pin2.transform(tf2.getString()); if (data2 == null) { tf2.setString(""); return false; } } else { data2 = null; } return true; } /** * Get the entered values. * * @return null if PIN entry was cancelled by user, otherwise an array containing PIN value(s). */ public Object[] getPINs() { if (answer == CANCELLED) { return null; } if (pin2 == null) { return new Object[] {data1}; } return new Object[] {data1, data2}; } }
/** An InputMode instance which processes the numeric 0-9 keys as their literal numeric values. */ public class AlphaNumericInputMode extends BasicInputMode { /** set of chars for alpha upper-case input */ private static char[][] upperKeyMap; /** set of chars for alpha low-case input */ private static char[][] lowerKeyMap; /** set of chars for long key press */ private static char[][] longPressKeyMap; /** array of sub-inputModes supported by this inputMode */ protected static final int[] CAPS_MODES = {CAPS_SENTENCE, CAPS_OFF, CAPS_ON}; /** array of sub-inputModes labels, corresponding to CAPS_MODES array */ private static final String[] CAPS_MODES_LABELS = { Resource.getString(ResourceConstants.LCDUI_TF_CAPS_SENTENCE), Resource.getString(ResourceConstants.LCDUI_TF_CAPS_OFF), Resource.getString(ResourceConstants.LCDUI_TF_CAPS_ON) }; /** the possible key maps for this input mode */ private static char[][][] keyMaps; /** points to an element of CAPS_MODES which is the current sub-inputMode */ protected int capsModePointer = 0; /** Default constructor. Init key maps for all constraints */ public AlphaNumericInputMode() { String upperInLine = Resource.getString(ResourceConstants.LCDUI_TF_CAPS_ALPHA_KEY_MAP); upperKeyMap = getMapByLine(upperInLine); String lowerInLine = Resource.getString(ResourceConstants.LCDUI_TF_ALPHA_KEY_MAP); lowerKeyMap = getMapByLine(lowerInLine); String longInLine = Resource.getString(ResourceConstants.LCDUI_TF_ALPHA_DIGIT_KEY_MAP); longPressKeyMap = getMapByLine(longInLine); keyMaps = new char[3][][]; keyMaps[0] = upperKeyMap; keyMaps[1] = lowerKeyMap; keyMaps[2] = upperKeyMap; } /** * Set the corresponding key map. * * @param constraints text input constraints. The semantics of the constraints value are defined * in the TextField API. * @param longPress return true if it's long key press otherwise false * @return true if the key map has been changed otherwise false */ protected boolean setKeyMap(int constraints, boolean longPress) { char[][] oldKeyMap = keyMap; keyMap = longPress ? longPressKeyMap : keyMaps[capsModePointer]; return oldKeyMap != keyMap; } /** * This method is called to determine if this InputMode supports the given text input constraints. * The semantics of the constraints value are defined in the javax.microedition.lcdui.TextField * API. If this InputMode returns false, this InputMode must not be used to process key input for * the selected text component. * * @param constraints text input constraints. The semantics of the constraints value are defined * in the TextField API. * @return true if this InputMode supports the given text component constraints, as defined in the * MIDP TextField API */ public boolean supportsConstraints(int constraints) { switch (constraints & TextField.CONSTRAINT_MASK) { case TextField.NUMERIC: case TextField.DECIMAL: case TextField.PHONENUMBER: return false; default: return true; } } /** * Returns the display name which will represent this InputMode to the user, such as in a * selection list or the softbutton bar. * * @return the locale-appropriate name to represent this InputMode to the user */ public String getName() { return CAPS_MODES_LABELS[capsModePointer]; } /** * Returns the command name which will represent this InputMode in the input menu * * @return the locale-appropriate name to represent this InputMode to the user */ public String getCommandName() { return getName(); } /** Set the next capital mode for this input method */ protected void nextCapsMode() { if (Logging.REPORT_LEVEL <= Logging.INFORMATION) { Logging.report(Logging.INFORMATION, LogChannels.LC_HIGHUI, "[A.nextCapsMode]"); } capsModePointer++; if (capsModePointer == CAPS_MODES.length) { capsModePointer = 0; } if (CAPS_MODES[capsModePointer] == CAPS_OFF) { keyMap = lowerKeyMap; } else { keyMap = upperKeyMap; } mediator.subInputModeChanged(); } /** * Gets the possible matches for the key code * * @param lastKey the key code * @return returns the set of options. Return null if matches are not found. */ protected char[] getCharOptions(int lastKey) { char[] chars = null; switch (lastKey) { case Canvas.KEY_NUM0: chars = keyMap[0]; break; case Canvas.KEY_NUM1: chars = keyMap[1]; break; case Canvas.KEY_NUM2: chars = keyMap[2]; break; case Canvas.KEY_NUM3: chars = keyMap[3]; break; case Canvas.KEY_NUM4: chars = keyMap[4]; break; case Canvas.KEY_NUM5: chars = keyMap[5]; break; case Canvas.KEY_NUM6: chars = keyMap[6]; break; case Canvas.KEY_NUM7: chars = keyMap[7]; break; case Canvas.KEY_NUM8: chars = keyMap[8]; break; case Canvas.KEY_NUM9: chars = keyMap[9]; break; case Canvas.KEY_POUND: chars = keyMap[10]; break; case Canvas.KEY_STAR: nextCapsMode(); break; default: // This can actually happen if the Timer went off without // a pending key, which can sometimes happen. break; } return chars; } /** * This method is used to immediately commit the pending character because a new character is now * pending. * * @return true if char has been committed otherwise false */ protected boolean commitPendingChar() { boolean committed = super.commitPendingChar(); if (committed) { if (CAPS_MODES[capsModePointer] == CAPS_SENTENCE) { nextCapsMode(); } } return committed; } /** input subset x constraint map */ private static final boolean[][] isMap = { // |ANY|EMAILADDR|NUMERIC|PHONENUMBER|URL|DECIMAL {false, false, false, false, false, false}, // IS_FULLWIDTH_DIGITS {true, true, false, false, true, false}, // IS_FULLWIDTH_LATIN {false, false, false, false, false, false}, // IS_HALFWIDTH_KATAKANA {false, false, false, false, false, false}, // IS_HANJA {false, false, false, false, false, false}, // IS_KANJI {true, true, false, false, true, false}, // IS_LATIN {true, true, false, false, true, false}, // IS_LATIN_DIGITS {false, false, false, false, false, false}, // IS_SIMPLIFIED_HANZI {false, false, false, false, false, false}, // IS_TRADITIONAL_HANZI {true, true, false, false, true, false}, // MIDP_UPPERCASE_LATIN {true, true, false, false, true, false}, // MIDP_LOWERCASE_LATIN {true, true, false, false, true, false} // NULL }; /** * Returns the map specifying this input mode is proper one for the particular pair of input * subset and constraint. The form of the map is * * <p>|ANY|EMAILADDR|NUMERIC|PHONENUMBER|URL|DECIMAL| * --------------------------------------------------------------------- IS_FULLWIDTH_DIGITS |t|f| * t|f | t|f | t|f |t|f| t|f | IS_FULLWIDTH_LATIN |t|f| t|f | t|f | t|f |t|f| t|f | * IS_HALFWIDTH_KATAKANA |t|f| t|f | t|f | t|f |t|f| t|f | IS_HANJA |t|f| t|f | t|f | t|f |t|f| * t|f | IS_KANJI |t|f| t|f | t|f | t|f |t|f| t|f | IS_LATIN |t|f| t|f | t|f | t|f |t|f| t|f | * IS_LATIN_DIGITS |t|f| t|f | t|f | t|f |t|f| t|f | IS_SIMPLIFIED_HANZI |t|f| t|f | t|f | t|f * |t|f| t|f | IS_TRADITIONAL_HANZI |t|f| t|f | t|f | t|f |t|f| t|f | MIDP_UPPERCASE_LATIN |t|f| * t|f | t|f | t|f |t|f| t|f | MIDP_LOWERCASE_LATIN |t|f| t|f | t|f | t|f |t|f| t|f | NULL |t|f| * t|f | t|f | t|f |t|f| t|f | * * @return input subset x constraint map */ public boolean[][] getIsConstraintsMap() { return isMap; } /** * Notify about current input subset * * @param inputSubset current input subset */ protected void setInputSubset(String inputSubset) { int mode = -1; if ("MIDP_UPPERCASE_LATIN".equals(inputSubset)) { mode = CAPS_ON; } else if ("MIDP_LOWERCASE_LATIN".equals(inputSubset)) { mode = CAPS_OFF; } for (int i = CAPS_MODES.length - 1; i >= 0; i--) { if (CAPS_MODES[i] == mode) { capsModePointer = i; break; } } } }