Source Code Cross Referenced for AppManagerUI.java in  » 6.0-JDK-Modules » j2me » com » sun » midp » appmanager » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » j2me » com.sun.midp.appmanager 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *
0003:         *
0004:         * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved.
0005:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
0006:         * 
0007:         * This program is free software; you can redistribute it and/or
0008:         * modify it under the terms of the GNU General Public License version
0009:         * 2 only, as published by the Free Software Foundation.
0010:         * 
0011:         * This program is distributed in the hope that it will be useful, but
0012:         * WITHOUT ANY WARRANTY; without even the implied warranty of
0013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0014:         * General Public License version 2 for more details (a copy is
0015:         * included at /legal/license.txt).
0016:         * 
0017:         * You should have received a copy of the GNU General Public License
0018:         * version 2 along with this work; if not, write to the Free Software
0019:         * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0020:         * 02110-1301 USA
0021:         * 
0022:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
0023:         * Clara, CA 95054 or visit www.sun.com if you need additional
0024:         * information or have any questions.
0025:         */
0026:
0027:        package com.sun.midp.appmanager;
0028:
0029:        import javax.microedition.lcdui.*;
0030:
0031:        import com.sun.midp.configurator.Constants;
0032:
0033:        import com.sun.midp.installer.*;
0034:        import com.sun.midp.main.*;
0035:        import com.sun.midp.midletsuite.*;
0036:        import com.sun.midp.midlet.MIDletSuite;
0037:        import com.sun.midp.io.j2me.push.PushRegistryInternal;
0038:
0039:        import com.sun.midp.i18n.Resource;
0040:        import com.sun.midp.i18n.ResourceConstants;
0041:
0042:        import com.sun.midp.log.Logging;
0043:        import com.sun.midp.log.LogChannels;
0044:
0045:        import com.sun.midp.payment.PAPICleanUp;
0046:
0047:        import java.io.*;
0048:        import javax.microedition.rms.*;
0049:        import java.util.*;
0050:
0051:        /**
0052:         * The Graphical MIDlet selector Screen.
0053:         * <p>
0054:         * It displays a list (or grid to be exact) of currently installed
0055:         * MIDlets/MIDlet suites (including the Installer MIDlet). Each MIDlet or
0056:         * MIDlet suite is represented by an icon with a name under it.
0057:         * An icon from a jad file for the MIDlet/MIDlet suite representation
0058:         * is used if possible, otherwise a default icon is used.
0059:         *
0060:         * There is a a set of commands per MIDlet/MIDlet suite. Note that
0061:         * the set of commands can change depending on the corresponding MIDlet state.
0062:         * For MIDlets/MIDlet suites that are not running the following commands are
0063:         * available:
0064:         * <ul>
0065:         * <li><b>Launch</b>: Launch the MIDlet or the MIDlet Selector
0066:         *      if it is a suite.
0067:         * <li><b>Remove</b>: Remove the MIDlet/MIDlet suite teh user selected
0068:         *      (with confirmation). </li>
0069:         * <li><b>Update</b>: Update the MIDlet/MIDlet suite the user selected.</li>
0070:         * <li><b>Info</b>: Show the user general information
0071:         *    of the selected MIDlet/MIdlet suite. </li>
0072:         * <li><b>Settings</b>: Let the user change the manager's settings.
0073:         * </ul>
0074:         *
0075:         * For MIDlets/MIDlet suites that are running the following commands are
0076:         * available:
0077:         * <ul>
0078:         * <li><b>Bring to foreground</b>: Bring the running MIDlet to foreground
0079:         * <li><b>End</b>: Terminate the running MIDlet
0080:         * <li><b>Remove</b>: Remove the MIDlet/MIDlet suite teh user selected
0081:         *      (with confirmation). </li>
0082:         * <li><b>Update</b>: Update the MIDlet/MIDlet suite the user selected.</li>
0083:         * <li><b>Info</b>: Show the user general information
0084:         *    of the selected MIDlet/MIdlet suite. </li>
0085:         * <li><b>Settings</b>: Let the user change the manager's settings.
0086:         * </ul>
0087:         *
0088:         * Exactly one MIDlet from a MIDlet suite could be run at the same time.
0089:         * Each MIDlet/MIDlet suite representation corresponds to an instance of
0090:         * MidletCustomItem which in turn maintains a reference to a MIDletSuiteInfo
0091:         * object (that contains info about this MIDlet/MIDlet suite).
0092:         * When a MIDlet is launched or a MIDlet form a MIDlet suite is launched
0093:         * the proxy instance in the corresponding MidletCustomItem is set to
0094:         * a running MIDletProxy value. It is set back to null when MIDlet exits.
0095:         *
0096:         * Running midlets can be distinguished from non-running MIdlets/MIDlet suites
0097:         * by the color of their name.
0098:         */
0099:        class AppManagerUI extends Form implements  ItemCommandListener,
0100:                CommandListener {
0101:
0102:            /** Constant for the discovery application class name. */
0103:            private static final String DISCOVERY_APP = "com.sun.midp.installer.DiscoveryApp";
0104:
0105:            /** Constant for the certificate manager class name */
0106:            private static final String CA_MANAGER = "com.sun.midp.appmanager.CaManager";
0107:
0108:            /** Constant for the graphical installer class name. */
0109:            private static final String INSTALLER = "com.sun.midp.installer.GraphicalInstaller";
0110:
0111:            /** Constant for the graphical installer class name. */
0112:            private static final String SUITE_SELECTOR = "com.sun.midp.midletsuite.Selector";
0113:
0114:            /**
0115:             * The font used to paint midlet names in the AppSelector.
0116:             * Inner class cannot have static variables thus it has to be here.
0117:             */
0118:            private static final Font ICON_FONT = Font.getFont(
0119:                    Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_SMALL);
0120:
0121:            /**
0122:             * The image used to draw background for the midlet representation.
0123:             * IMPL NOTE: it is assumed that background image is larger or equal
0124:             * than all other images that are painted over it
0125:             */
0126:            private static final Image ICON_BG = GraphicalInstaller
0127:                    .getImageFromInternalStorage("_ch_hilight_bg");
0128:
0129:            /**
0130:             * Cashed background image width.
0131:             */
0132:            private static final int bgIconW = ICON_BG.getWidth();
0133:
0134:            /**
0135:             * Cashed background image height.
0136:             */
0137:            private static final int bgIconH = ICON_BG.getHeight();
0138:
0139:            /**
0140:             * The icon used to display that user attention is requested
0141:             * and that midlet needs to brought into foreground.
0142:             */
0143:            private static final Image FG_REQUESTED = GraphicalInstaller
0144:                    .getImageFromInternalStorage("_ch_fg_requested");
0145:
0146:            /**
0147:             * The image used to draw disable midlet representation.
0148:             */
0149:            private static final Image DISABLED_IMAGE = GraphicalInstaller
0150:                    .getImageFromInternalStorage("_ch_disabled");
0151:
0152:            /**
0153:             * The color used to draw midlet name
0154:             * for the hilighted non-running running midlet representation.
0155:             */
0156:            private static final int ICON_HL_TEXT = 0x000B2876;
0157:
0158:            /**
0159:             * The color used to draw the shadow of the midlet name
0160:             * for the non hilighted non-running midlet representation.
0161:             */
0162:            private static final int ICON_TEXT = 0x003177E2;
0163:
0164:            /**
0165:             * The color used to draw the midlet name
0166:             * for the non hilighted running midlet representation.
0167:             */
0168:            private static final int ICON_RUNNING_TEXT = 0xbb0000;
0169:
0170:            /**
0171:             * The color used to draw the midlet name
0172:             * for the hilighted running midlet representation.
0173:             */
0174:            private static final int ICON_RUNNING_HL_TEXT = 0xff0000;
0175:
0176:            /**
0177:             * Tha pad between custom item's icon and text
0178:             */
0179:            private static final int ITEM_PAD = 2;
0180:
0181:            /**
0182:             * Cashed truncation mark
0183:             */
0184:            private static final char truncationMark = Resource.getString(
0185:                    ResourceConstants.TRUNCATION_MARK).charAt(0);
0186:
0187:            /** Command object for "Exit" command for splash screen. */
0188:            private Command exitCmd = new Command(Resource
0189:                    .getString(ResourceConstants.EXIT), Command.BACK, 1);
0190:
0191:            /** Command object for "Launch" install app. */
0192:            private Command launchInstallCmd = new Command(Resource
0193:                    .getString(ResourceConstants.LAUNCH), Command.ITEM, 1);
0194:
0195:            /** Command object for "Launch" CA manager app. */
0196:            private Command launchCaManagerCmd = new Command(Resource
0197:                    .getString(ResourceConstants.LAUNCH), Command.ITEM, 1);
0198:
0199:            /** Command object for "Launch". */
0200:            private Command launchCmd = new Command(Resource
0201:                    .getString(ResourceConstants.LAUNCH), Command.ITEM, 1);
0202:            /** Command object for "Info". */
0203:            private Command infoCmd = new Command(Resource
0204:                    .getString(ResourceConstants.INFO), Command.ITEM, 2);
0205:            /** Command object for "Remove". */
0206:            private Command removeCmd = new Command(Resource
0207:                    .getString(ResourceConstants.REMOVE), Command.ITEM, 3);
0208:            /** Command object for "Update". */
0209:            private Command updateCmd = new Command(Resource
0210:                    .getString(ResourceConstants.UPDATE), Command.ITEM, 4);
0211:            /** Command object for "Application settings". */
0212:            private Command appSettingsCmd = new Command(Resource
0213:                    .getString(ResourceConstants.APPLICATION_SETTINGS),
0214:                    Command.ITEM, 5);
0215:
0216:            /** Command object for "Cancel" command for the remove form. */
0217:            private Command cancelCmd = new Command(Resource
0218:                    .getString(ResourceConstants.CANCEL), Command.CANCEL, 1);
0219:            /** Command object for "Remove" command for the remove form. */
0220:            private Command removeOkCmd = new Command(Resource
0221:                    .getString(ResourceConstants.REMOVE), Command.SCREEN, 1);
0222:
0223:            /** Command object for "Back" command for back to the AppSelector. */
0224:            Command backCmd = new Command(Resource
0225:                    .getString(ResourceConstants.BACK), Command.BACK, 1);
0226:
0227:            /** Command object for "Bring to foreground". */
0228:            private Command fgCmd = new Command(Resource
0229:                    .getString(ResourceConstants.FOREGROUND), Command.ITEM, 1);
0230:
0231:            /** Command object for "End" midlet. */
0232:            private Command endCmd = new Command(Resource
0233:                    .getString(ResourceConstants.END), Command.ITEM, 1);
0234:
0235:            /** Command object for "Yes" command. */
0236:            private Command runYesCmd = new Command(Resource
0237:                    .getString(ResourceConstants.YES), Command.OK, 1);
0238:
0239:            /** Command object for "No" command. */
0240:            private Command runNoCmd = new Command(Resource
0241:                    .getString(ResourceConstants.NO), Command.BACK, 1);
0242:
0243:            /** Display for the Manager MIDlet. */
0244:            ApplicationManager manager;
0245:
0246:            /** MIDlet Suite storage object. */
0247:            private MIDletSuiteStorage midletSuiteStorage;
0248:
0249:            /** Display for the Manager MIDlet. */
0250:            Display display; // = null
0251:
0252:            /** Keeps track of when the display last changed, in milliseconds. */
0253:            private long lastDisplayChange;
0254:
0255:            /** MIDlet to be removed after confirmation screen was accepted */
0256:            private RunningMIDletSuiteInfo removeMsi;
0257:
0258:            /** last Item that was selected */
0259:            private RunningMIDletSuiteInfo lastSelectedMsi;
0260:
0261:            /**
0262:             * There are several Application Manager
0263:             * midlets from the same "internal" midlet suite
0264:             * that should not be running in the background.
0265:             * appManagerMidlet helps to destroy them
0266:             * (see MidletCustomItem.showNotify).
0267:             */
0268:            private MIDletProxy appManagerMidlet;
0269:
0270:            /** UI used to display error messages. */
0271:            private DisplayError displayError;
0272:
0273:            /** True, if the CA manager is included. */
0274:            private boolean caManagerIncluded;
0275:
0276:            private MIDletSwitcher midletSwitcher;
0277:
0278:            /**
0279:             * Creates and populates the Application Selector Screen.
0280:             * @param manager - The application manager that invoked it
0281:             * @param displayError - The UI used to display error messages
0282:             * @param display - The display instance associated with the manager
0283:             * @param first - true if this is the first time AppSelector is being
0284:             *                shown
0285:             * @param ms - MidletSuiteInfo that should be selected. For the internal
0286:             *             suites midletToRun should be set, for the other suites
0287:             *             suiteId is enough to find the corresponding item.
0288:             */
0289:            AppManagerUI(ApplicationManager manager, Display display,
0290:                    DisplayError displayError, boolean first, MIDletSuiteInfo ms) {
0291:                super (null);
0292:
0293:                try {
0294:                    caManagerIncluded = Class.forName(CA_MANAGER) != null;
0295:                } catch (ClassNotFoundException e) {
0296:                    // keep caManagerIncluded false
0297:                }
0298:
0299:                this .manager = manager;
0300:                this .display = display;
0301:                this .displayError = displayError;
0302:
0303:                midletSwitcher = new MIDletSwitcher(this , manager, display);
0304:
0305:                midletSuiteStorage = MIDletSuiteStorage.getMIDletSuiteStorage();
0306:
0307:                setTitle(Resource.getString(ResourceConstants.AMS_MGR_TITLE));
0308:                updateContent();
0309:
0310:                addCommand(exitCmd);
0311:                setCommandListener(this );
0312:
0313:                if (first) {
0314:                    display.setCurrent(new SplashScreen(display, this ));
0315:                } else {
0316:                    // if a MIDlet was just installed
0317:                    // getLastInstalledMidletItem() will return MidletCustomItem
0318:                    // corresponding to this suite, then we have to prompt
0319:                    // the user if he want to launch a midlet from the suite.
0320:                    MidletCustomItem mci = getLastInstalledMidletItem();
0321:                    if (mci != null) {
0322:                        askUserIfLaunchMidlet();
0323:                    } else {
0324:                        display.setCurrent(this );
0325:                        if (ms != null) {
0326:                            // Find item to select
0327:                            if (ms.suiteId == MIDletSuite.INTERNAL_SUITE_ID) {
0328:                                for (int i = 0; i < size(); i++) {
0329:                                    MidletCustomItem mi = (MidletCustomItem) get(i);
0330:                                    if ((mi.msi.suiteId == MIDletSuite.INTERNAL_SUITE_ID)
0331:                                            && (mi.msi.midletToRun
0332:                                                    .equals(ms.midletToRun))) {
0333:                                        display.setCurrentItem(mi);
0334:                                        break;
0335:                                    }
0336:                                }
0337:                            } else {
0338:                                for (int i = 0; i < size(); i++) {
0339:                                    MidletCustomItem mi = (MidletCustomItem) get(i);
0340:                                    if (mi.msi.suiteId == ms.suiteId) {
0341:                                        display.setCurrentItem(mi);
0342:                                        break;
0343:                                    }
0344:                                }
0345:                            }
0346:                        } // ms != null
0347:                    }
0348:                }
0349:            }
0350:
0351:            /**
0352:             * Called when midlet selector needed.
0353:             *
0354:             * @param onlyFromLaunchedList true if midlet should
0355:             *        be selected from the list of already launched midlets,
0356:             *        if false then possibility to launch midlet is needed.
0357:             */
0358:            public void showMidletSwitcher(boolean onlyFromLaunchedList) {
0359:                if (onlyFromLaunchedList && midletSwitcher.hasItems()) {
0360:                    display.setCurrent(midletSwitcher);
0361:                } else {
0362:                    display.setCurrent(this );
0363:                }
0364:            }
0365:
0366:            /**
0367:             * Called to determine MidletSuiteInfo of the last selected Item.
0368:             *
0369:             * @return last selected MidletSuiteInfo
0370:             */
0371:            public RunningMIDletSuiteInfo getSelectedMIDletSuiteInfo() {
0372:                return lastSelectedMsi;
0373:            }
0374:
0375:            /**
0376:             * Respond to a command issued on any Screen.
0377:             *
0378:             * @param c command activated by the user
0379:             * @param s the Displayable the command was on.
0380:             */
0381:            public void commandAction(Command c, Displayable s) {
0382:
0383:                if (c == exitCmd) {
0384:                    if (s == this ) {
0385:                        manager.shutDown();
0386:                    }
0387:                    return;
0388:                }
0389:
0390:                // for the rest of the commands
0391:                // we will have to request AppSelector to be displayed
0392:                if (c == removeOkCmd) {
0393:
0394:                    // suite to remove was set in confirmRemove()
0395:                    try {
0396:                        remove(removeMsi);
0397:                    } catch (Throwable t) {
0398:                        if (Logging.REPORT_LEVEL <= Logging.WARNING) {
0399:                            Logging.report(Logging.WARNING, LogChannels.LC_AMS,
0400:                                    "Throwable in removeSuitee");
0401:                        }
0402:                    }
0403:                    return;
0404:
0405:                } else if (c == cancelCmd) {
0406:
0407:                    // null out removeMsi in remove confirmation screen
0408:                    removeMsi = null;
0409:
0410:                } else if (c == runYesCmd) {
0411:
0412:                    // user decided run the midlet suite after installation
0413:                    MidletCustomItem mciToRun = getLastInstalledMidletItem();
0414:                    if (mciToRun != null) {
0415:                        display.setCurrentItem(mciToRun);
0416:                        launchMidlet(mciToRun.msi);
0417:                        return;
0418:                    }
0419:
0420:                } else if (c == runNoCmd) {
0421:
0422:                    /*
0423:                     * user decided not to run the newly installed midlet suite
0424:                     *
0425:                     * if a MIDlet was just installed
0426:                     * displayLastInstalledMidlet() will return true and
0427:                     * make "this" visible with
0428:                     * the right MIDlet icon hilighted.
0429:                     */
0430:                    if (displayLastInstalledMidlet()) {
0431:                        // Last installed midlet was set as the current item
0432:                        return;
0433:                    }
0434:
0435:                } else if (c != backCmd) {
0436:                    return;
0437:                }
0438:
0439:                // for back we just need to display AppSelector
0440:                display.setCurrent(this );
0441:            }
0442:
0443:            /**
0444:             * Respond to a command issued on an Item in AppSelector
0445:             *
0446:             * @param c command activated by the user
0447:             * @param item the Item the command was on.
0448:             */
0449:            public void commandAction(Command c, Item item) {
0450:                RunningMIDletSuiteInfo msi = ((MidletCustomItem) item).msi;
0451:                if (msi == null) {
0452:                    return;
0453:                }
0454:
0455:                if (c == launchInstallCmd) {
0456:
0457:                    manager.installSuite();
0458:
0459:                } else if (c == launchCaManagerCmd) {
0460:
0461:                    manager.launchCaManager();
0462:
0463:                } else if (c == launchCmd) {
0464:
0465:                    launchMidlet(msi);
0466:
0467:                } else if (c == infoCmd) {
0468:
0469:                    try {
0470:                        AppInfo appInfo = new AppInfo(msi.suiteId);
0471:                        appInfo.addCommand(backCmd);
0472:                        appInfo.setCommandListener(this );
0473:                        display.setCurrent(appInfo);
0474:                    } catch (Throwable t) {
0475:                        displayError.showErrorAlert(msi.displayName, t, null,
0476:                                null);
0477:                    }
0478:
0479:                } else if (c == removeCmd) {
0480:
0481:                    confirmRemove(msi);
0482:
0483:                } else if (c == updateCmd) {
0484:
0485:                    manager.updateSuite(msi);
0486:                    display.setCurrent(this );
0487:
0488:                } else if (c == appSettingsCmd) {
0489:
0490:                    try {
0491:                        AppSettings appSettings = new AppSettings(msi.suiteId,
0492:                                display, displayError, this );
0493:                        display.setCurrent(appSettings);
0494:
0495:                    } catch (Throwable t) {
0496:                        displayError.showErrorAlert(msi.displayName, t, null,
0497:                                null);
0498:                    }
0499:
0500:                } else if (c == fgCmd) {
0501:
0502:                    manager.moveToForeground(msi);
0503:                    display.setCurrent(this );
0504:
0505:                } else if (c == endCmd) {
0506:                    manager.exitMidlet(msi);
0507:                    display.setCurrent(this );
0508:
0509:                }
0510:            }
0511:
0512:            /**
0513:             * Called when a new midlet was launched.
0514:             *
0515:             * @param midlet proxy of a newly added MIDlet
0516:             */
0517:            void notifyMidletStarted(MIDletProxy midlet) {
0518:                String midletClassName = midlet.getClassName();
0519:
0520:                if (midletClassName.equals(manager.getClass().getName())) {
0521:                    return;
0522:                }
0523:
0524:                if (midlet.getSuiteId() == MIDletSuite.INTERNAL_SUITE_ID
0525:                        && !midletClassName.equals(DISCOVERY_APP)
0526:                        && !midletClassName.equals(INSTALLER)
0527:                        && !midletClassName.equals(CA_MANAGER)) {
0528:                    appManagerMidlet = midlet;
0529:                } else {
0530:                    MidletCustomItem ci;
0531:                    for (int i = 0; i < size(); i++) {
0532:                        ci = (MidletCustomItem) get(i);
0533:
0534:                        if (ci.msi.equals(midlet)) {
0535:                            ci.removeCommand(launchCmd);
0536:                            ci.removeCommand(launchInstallCmd);
0537:
0538:                            if (caManagerIncluded) {
0539:                                ci.removeCommand(launchCaManagerCmd);
0540:                            }
0541:
0542:                            ci.setDefaultCommand(fgCmd);
0543:                            ci.addCommand(endCmd);
0544:                            if (ci.msi.proxy == null) {
0545:                                // add item to midlet switcher
0546:                                midletSwitcher.append(ci.msi);
0547:                            }
0548:                            ci.msi.proxy = midlet;
0549:                            return;
0550:                        }
0551:                    }
0552:                }
0553:            }
0554:
0555:            /**
0556:             * Called when state of a running midlet was changed.
0557:             *
0558:             * @param midlet proxy of a newly added MIDlet
0559:             */
0560:            void notifyMidletStateChanged(MIDletProxy midlet) {
0561:                MidletCustomItem mci = null;
0562:
0563:                for (int i = 0; i < size(); i++) {
0564:                    mci = (MidletCustomItem) get(i);
0565:                    if (mci.msi.proxy == midlet) {
0566:                        mci.update();
0567:                    }
0568:                }
0569:            }
0570:
0571:            /**
0572:             * Called when a running midlet exited.
0573:             *
0574:             * @param midlet proxy of a newly added MIDlet
0575:             */
0576:            void notifyMidletExited(MIDletProxy midlet) {
0577:                String midletClassName = midlet.getClassName();
0578:
0579:                if (midlet.getSuiteId() == MIDletSuite.INTERNAL_SUITE_ID
0580:                        && !midletClassName.equals(DISCOVERY_APP)
0581:                        && !midletClassName.equals(INSTALLER)
0582:                        && !midletClassName.equals(CA_MANAGER)) {
0583:                    appManagerMidlet = null;
0584:                } else {
0585:                    MidletCustomItem ci;
0586:
0587:                    for (int i = 0; i < size(); i++) {
0588:                        ci = (MidletCustomItem) get(i);
0589:
0590:                        if (ci.msi.equals(midlet)) {
0591:                            ci.removeCommand(fgCmd);
0592:                            ci.removeCommand(endCmd);
0593:
0594:                            if (ci.msi.midletToRun != null
0595:                                    && ci.msi.midletToRun.equals(DISCOVERY_APP)) {
0596:                                ci.setDefaultCommand(launchInstallCmd);
0597:                            } else if (caManagerIncluded
0598:                                    && ci.msi.midletToRun != null
0599:                                    && ci.msi.midletToRun.equals(CA_MANAGER)) {
0600:                                ci.setDefaultCommand(launchCaManagerCmd);
0601:                            } else {
0602:                                if (ci.msi.enabled) {
0603:                                    ci.setDefaultCommand(launchCmd);
0604:                                }
0605:                            }
0606:
0607:                            midletSwitcher.remove(ci.msi);
0608:                            ci.msi.proxy = null;
0609:
0610:                            if (removeMsi != null && removeMsi.equals(midlet)) {
0611:                                remove(removeMsi);
0612:                            }
0613:
0614:                            /*
0615:                             * When the Installer midlet quites
0616:                             * (it is removed from the running apps list)
0617:                             * this is a good time to see if any new MIDlet suites
0618:                             * where added
0619:                             * Also the CA manager could have disabled a MIDlet.
0620:                             */
0621:                            if (INSTALLER.equals(midletClassName)) {
0622:                                updateContent();
0623:                                /*
0624:                                 * After a MIDlet suite is successfully installed on the
0625:                                 * device, ask the user whether or not to launch
0626:                                 * a MIDlet from the suite.
0627:                                 */
0628:                                MidletCustomItem mci = getLastInstalledMidletItem();
0629:                                if (mci != null) {
0630:                                    askUserIfLaunchMidlet();
0631:                                    return;
0632:                                }
0633:                            } else {
0634:                                if (CA_MANAGER.equals(midletClassName)) {
0635:                                    updateContent();
0636:                                }
0637:                                ci.update();
0638:                            }
0639:
0640:                            return;
0641:                        }
0642:                    }
0643:                }
0644:
0645:                // Midlet quited; display the application Selector
0646:                display.setCurrent(this );
0647:            }
0648:
0649:            /**
0650:             * Called when a midlet could not be launched.
0651:             *
0652:             * @param suiteId suite ID of the MIDlet
0653:             * @param className class name of the MIDlet
0654:             * @param errorCode error code
0655:             * @param errorDetails error code details
0656:             */
0657:            void notifyMidletStartError(int suiteId, String className,
0658:                    int errorCode, String errorDetails) {
0659:                Alert a;
0660:                String errorMsg;
0661:
0662:                switch (errorCode) {
0663:                case Constants.MIDLET_SUITE_NOT_FOUND:
0664:                    errorMsg = Resource
0665:                            .getString(ResourceConstants.AMS_MIDLETSUITELDR_MIDLETSUITE_NOTFOUND);
0666:                    break;
0667:
0668:                case Constants.MIDLET_CLASS_NOT_FOUND:
0669:                    errorMsg = Resource
0670:                            .getString(ResourceConstants.AMS_MIDLETSUITELDR_CANT_LAUNCH_MISSING_CLASS);
0671:                    break;
0672:
0673:                case Constants.MIDLET_INSTANTIATION_EXCEPTION:
0674:                    errorMsg = Resource
0675:                            .getString(ResourceConstants.AMS_MIDLETSUITELDR_CANT_LAUNCH_ILL_OPERATION);
0676:                    break;
0677:
0678:                case Constants.MIDLET_ILLEGAL_ACCESS_EXCEPTION:
0679:                    errorMsg = Resource
0680:                            .getString(ResourceConstants.AMS_MIDLETSUITELDR_CANT_LAUNCH_ILL_OPERATION);
0681:                    break;
0682:
0683:                case Constants.MIDLET_OUT_OF_MEM_ERROR:
0684:                    errorMsg = Resource
0685:                            .getString(ResourceConstants.AMS_MIDLETSUITELDR_QUIT_OUT_OF_MEMORY);
0686:                    break;
0687:
0688:                case Constants.MIDLET_RESOURCE_LIMIT:
0689:                case Constants.MIDLET_ISOLATE_RESOURCE_LIMIT:
0690:                    errorMsg = Resource
0691:                            .getString(ResourceConstants.AMS_MIDLETSUITELDR_RESOURCE_LIMIT_ERROR);
0692:                    break;
0693:
0694:                case Constants.MIDLET_ISOLATE_CONSTRUCTOR_FAILED:
0695:                    errorMsg = Resource
0696:                            .getString(ResourceConstants.AMS_MIDLETSUITELDR_CANT_EXE_NEXT_MIDLET);
0697:                    break;
0698:
0699:                case Constants.MIDLET_SUITE_DISABLED:
0700:                    errorMsg = Resource
0701:                            .getString(ResourceConstants.AMS_MIDLETSUITELDR_MIDLETSUITE_DISABLED);
0702:                    break;
0703:
0704:                case Constants.MIDLET_INSTALLER_RUNNING:
0705:                    String[] values = new String[1];
0706:                    values[0] = className;
0707:                    errorMsg = Resource
0708:                            .getString(
0709:                                    ResourceConstants.AMS_MGR_UPDATE_IS_RUNNING,
0710:                                    values);
0711:                    break;
0712:
0713:                default:
0714:                    errorMsg = Resource
0715:                            .getString(ResourceConstants.AMS_MIDLETSUITELDR_UNEXPECTEDLY_QUIT);
0716:                }
0717:
0718:                if (errorDetails != null) {
0719:                    errorMsg += "\n\n" + errorDetails;
0720:                }
0721:
0722:                displayError.showErrorAlert(null, null, Resource
0723:                        .getString(ResourceConstants.EXCEPTION), errorMsg);
0724:            }
0725:
0726:            // ------------------------------------------------------------------
0727:
0728:            /**
0729:             * Read in and create a MIDletInfo for newly added MIDlet suite and
0730:             * check enabled state of currently added MIDlet suites.
0731:             */
0732:            private void updateContent() {
0733:                int[] suiteIds;
0734:                RunningMIDletSuiteInfo msi = null;
0735:                boolean newlyAdded;
0736:
0737:                suiteIds = midletSuiteStorage.getListOfSuites();
0738:
0739:                // Add the Installer as the first installed midlet
0740:                if (size() > 0) {
0741:                    msi = ((MidletCustomItem) get(0)).msi;
0742:                }
0743:
0744:                if (msi == null || msi.midletToRun == null
0745:                        || !msi.midletToRun.equals(DISCOVERY_APP)) {
0746:
0747:                    msi = new RunningMIDletSuiteInfo(
0748:                            MIDletSuite.INTERNAL_SUITE_ID,
0749:                            DISCOVERY_APP,
0750:                            Resource
0751:                                    .getString(ResourceConstants.INSTALL_APPLICATION),
0752:                            true) {
0753:                        public boolean equals(MIDletProxy midlet) {
0754:                            if (super .equals(midlet)) {
0755:                                return true;
0756:                            }
0757:
0758:                            // there is one exception when 2 midlets belong to the
0759:                            // same icon: Discovery app & Graphical installer.
0760:                            // Graphical Installer can be launched by Discover app
0761:                            // or when MIdlet update is needed.
0762:                            // In such cases we simply need to set the proxy on
0763:                            // corresponding icon (MidletCustomItem).
0764:                            // Note that when Discovery app exits and
0765:                            // Installer is launched
0766:                            // notifyMidletExited() will not find corresponding
0767:                            // icon in the list of MidletCustomItems.
0768:                            // (that midlet exit will be ignored).
0769:                            return (INSTALLER.equals(midlet.getClassName()));
0770:                        }
0771:                    };
0772:
0773:                    append(msi);
0774:                }
0775:
0776:                if (caManagerIncluded) {
0777:                    // Add the CA manager as the second installed midlet
0778:                    if (size() > 1) {
0779:                        msi = ((MidletCustomItem) get(1)).msi;
0780:                    }
0781:
0782:                    if (msi == null || msi.midletToRun == null
0783:                            || !msi.midletToRun.equals(CA_MANAGER)) {
0784:                        msi = new RunningMIDletSuiteInfo(
0785:                                MIDletSuite.INTERNAL_SUITE_ID,
0786:                                CA_MANAGER,
0787:                                Resource
0788:                                        .getString(ResourceConstants.CA_MANAGER_APP),
0789:                                true);
0790:                        append(msi);
0791:                    }
0792:                }
0793:
0794:                // Add the rest of the installed midlets
0795:                for (int lowest, i = 0; i < suiteIds.length; i++) {
0796:
0797:                    lowest = i;
0798:
0799:                    for (int k = i + 1; k < suiteIds.length; k++) {
0800:                        if (suiteIds[k] < suiteIds[lowest]) {
0801:                            lowest = k;
0802:                        }
0803:                    }
0804:
0805:                    try {
0806:                        MIDletSuiteInfo temp = midletSuiteStorage
0807:                                .getMIDletSuiteInfo(suiteIds[lowest]);
0808:
0809:                        RunningMIDletSuiteInfo suiteInfo = new RunningMIDletSuiteInfo(
0810:                                temp, midletSuiteStorage);
0811:
0812:                        newlyAdded = true;
0813:                        for (int k = 0; k < size(); k++) {
0814:                            MidletCustomItem mci = (MidletCustomItem) get(k);
0815:
0816:                            if (suiteIds[lowest] == mci.msi.suiteId) {
0817:                                newlyAdded = false;
0818:                                boolean isEnabled = suiteInfo.enabled;
0819:
0820:                                if (mci.msi.enabled != isEnabled) {
0821:                                    mci.msi.enabled = isEnabled;
0822:
0823:                                    // MIDlet suite being enabled
0824:                                    if (isEnabled) {
0825:                                        mci.setDefaultCommand(launchCmd);
0826:                                    } else { // MIDlet suite is being disabled
0827:
0828:                                        if (mci.msi.proxy == null) { // Not running
0829:                                            mci.removeCommand(launchCmd);
0830:
0831:                                        }
0832:
0833:                                        // running MIDlets will continue to run
0834:                                        // even when disabled
0835:                                    }
0836:                                }
0837:
0838:                                // Update all information about the suite;
0839:                                // if the suite's icon was changed, reload it.
0840:                                String oldIconName = mci.msi.iconName;
0841:                                int oldNumberOfMidlets = mci.msi.numberOfMidlets;
0842:                                MIDletProxy oldProxy = mci.msi.proxy;
0843:
0844:                                mci.msi = suiteInfo;
0845:                                mci.msi.proxy = oldProxy;
0846:
0847:                                if ((suiteInfo.iconName != null && !suiteInfo.iconName
0848:                                        .equals(oldIconName))
0849:                                        || (suiteInfo.iconName == null && suiteInfo.numberOfMidlets != oldNumberOfMidlets)) {
0850:                                    mci.msi.icon = null;
0851:                                    mci.msi.loadIcon(midletSuiteStorage);
0852:                                    mci.icon = mci.msi.icon;
0853:                                }
0854:
0855:                                break;
0856:                            }
0857:                        }
0858:
0859:                        if (newlyAdded) {
0860:                            append(suiteInfo);
0861:                        }
0862:
0863:                    } catch (Exception e) {
0864:                        // move on to the next suite
0865:                    }
0866:
0867:                    suiteIds[lowest] = suiteIds[i];
0868:                }
0869:            }
0870:
0871:            /**
0872:             * Appends a MidletCustomItem to the App Selector Screen
0873:             *
0874:             * @param suiteInfo the midlet suite info
0875:             *                  of the recently started midlet
0876:             */
0877:            private void append(RunningMIDletSuiteInfo suiteInfo) {
0878:
0879:                MidletCustomItem ci = new MidletCustomItem(suiteInfo);
0880:
0881:                if (suiteInfo.midletToRun != null
0882:                        && suiteInfo.midletToRun.equals(DISCOVERY_APP)) {
0883:                    // setDefaultCommand will add default command first
0884:                    ci.setDefaultCommand(launchInstallCmd);
0885:                } else if (caManagerIncluded && suiteInfo.midletToRun != null
0886:                        && suiteInfo.midletToRun.equals(CA_MANAGER)) {
0887:                    // setDefaultCommand will add default command first
0888:                    ci.setDefaultCommand(launchCaManagerCmd);
0889:                } else {
0890:                    ci.addCommand(infoCmd);
0891:                    ci.addCommand(removeCmd);
0892:                    ci.addCommand(updateCmd);
0893:                    ci.addCommand(appSettingsCmd);
0894:
0895:                    if (suiteInfo.enabled) {
0896:                        // setDefaultCommand will add default command first
0897:                        ci.setDefaultCommand(launchCmd);
0898:                    }
0899:                }
0900:
0901:                ci.setItemCommandListener(this );
0902:                append(ci);
0903:                ci.setOwner(this );
0904:            }
0905:
0906:            /**
0907:             * Removes a midlet from the App Selector Screen
0908:             *
0909:             * @param suiteInfo the midlet suite info of a recently removed MIDlet
0910:             */
0911:            private void remove(RunningMIDletSuiteInfo suiteInfo) {
0912:                RunningMIDletSuiteInfo msi;
0913:
0914:                if (suiteInfo == null) {
0915:                    // Invalid parameter, should not happen.
0916:                    return;
0917:                }
0918:
0919:                // the last item in AppSelector is time
0920:                for (int i = 0; i < size(); i++) {
0921:                    msi = (RunningMIDletSuiteInfo) ((MidletCustomItem) get(i)).msi;
0922:                    if (msi == suiteInfo) {
0923:                        PAPICleanUp.removeMissedTransaction(suiteInfo.suiteId);
0924:
0925:                        if (msi.proxy != null) {
0926:                            msi.proxy.destroyMidlet();
0927:                        }
0928:
0929:                        try {
0930:                            midletSuiteStorage.remove(suiteInfo.suiteId);
0931:                        } catch (Throwable t) {
0932:                            if (t instanceof  MIDletSuiteLockedException) {
0933:                                String[] val = new String[1];
0934:                                val[0] = suiteInfo.displayName;
0935:                                displayError
0936:                                        .showErrorAlert(
0937:                                                suiteInfo.displayName,
0938:                                                null,
0939:                                                Resource
0940:                                                        .getString(ResourceConstants.ERROR),
0941:                                                Resource
0942:                                                        .getString(
0943:                                                                ResourceConstants.AMS_MGR_REMOVE_LOCKED_SUITE,
0944:                                                                val), this );
0945:                            } else {
0946:                                displayError
0947:                                        .showErrorAlert(
0948:                                                suiteInfo.displayName,
0949:                                                t,
0950:                                                Resource
0951:                                                        .getString(ResourceConstants.ERROR),
0952:                                                null, this );
0953:                            }
0954:
0955:                            return;
0956:                        }
0957:
0958:                        try {
0959:                            PushRegistryInternal
0960:                                    .unregisterConnections(suiteInfo.suiteId);
0961:                        } catch (Throwable t) {
0962:                            // Intentionally ignored: suite has been removed already,
0963:                            // we can't do anything meaningful at this point.
0964:                        }
0965:
0966:                        delete(i);
0967:                        removeMsi = null;
0968:                        break;
0969:                    }
0970:                }
0971:
0972:                display.setCurrent(this );
0973:            }
0974:
0975:            /**
0976:             * Alert the user that an action was successful.
0977:             * @param successMessage message to display to user
0978:             */
0979:            private void displaySuccessMessage(String successMessage) {
0980:                Image icon;
0981:                Alert successAlert;
0982:
0983:                icon = GraphicalInstaller
0984:                        .getImageFromInternalStorage("_dukeok8");
0985:
0986:                successAlert = new Alert(null, successMessage, icon, null);
0987:
0988:                successAlert.setTimeout(GraphicalInstaller.ALERT_TIMEOUT);
0989:
0990:                // We need to prevent "flashing" on fast development platforms.
0991:                while (System.currentTimeMillis() - lastDisplayChange < GraphicalInstaller.ALERT_TIMEOUT)
0992:                    ;
0993:
0994:                display.setCurrent(successAlert, this );
0995:                lastDisplayChange = System.currentTimeMillis();
0996:            }
0997:
0998:            /**
0999:             * Confirm the removal of a suite.
1000:             *
1001:             * @param suiteInfo information for suite to remove
1002:             */
1003:            private void confirmRemove(RunningMIDletSuiteInfo suiteInfo) {
1004:                Form confirmForm;
1005:                StringBuffer temp = new StringBuffer(40);
1006:                Item item;
1007:                String extraConfirmMsg;
1008:                String[] values = new String[1];
1009:                MIDletSuiteImpl midletSuite = null;
1010:
1011:                try {
1012:                    midletSuite = midletSuiteStorage.getMIDletSuite(
1013:                            suiteInfo.suiteId, false);
1014:                    confirmForm = new Form(null);
1015:
1016:                    confirmForm.setTitle(Resource
1017:                            .getString(ResourceConstants.AMS_CONFIRMATION));
1018:
1019:                    if (suiteInfo.hasSingleMidlet()) {
1020:                        values[0] = suiteInfo.displayName;
1021:                    } else {
1022:                        values[0] = midletSuite
1023:                                .getProperty(MIDletSuiteImpl.SUITE_NAME_PROP);
1024:                    }
1025:
1026:                    item = new StringItem(null, Resource.getString(
1027:                            ResourceConstants.AMS_MGR_REMOVE_QUE, values));
1028:                    item.setLayout(Item.LAYOUT_NEWLINE_AFTER | Item.LAYOUT_2);
1029:                    confirmForm.append(item);
1030:
1031:                    extraConfirmMsg = PAPICleanUp
1032:                            .checkMissedTransactions(midletSuite.getID());
1033:                    if (extraConfirmMsg != null) {
1034:                        temp.setLength(0);
1035:                        temp.append(" \n");
1036:                        temp.append(extraConfirmMsg);
1037:                        item = new StringItem(null, temp.toString());
1038:                        item.setLayout(Item.LAYOUT_NEWLINE_AFTER
1039:                                | Item.LAYOUT_2);
1040:                        confirmForm.append(item);
1041:                    }
1042:
1043:                    extraConfirmMsg = midletSuite
1044:                            .getProperty("MIDlet-Delete-Confirm");
1045:                    if (extraConfirmMsg != null) {
1046:                        temp.setLength(0);
1047:                        temp.append(" \n");
1048:                        temp.append(extraConfirmMsg);
1049:                        item = new StringItem(null, temp.toString());
1050:                        item.setLayout(Item.LAYOUT_NEWLINE_AFTER
1051:                                | Item.LAYOUT_2);
1052:                        confirmForm.append(item);
1053:                    }
1054:
1055:                    if (!suiteInfo.hasSingleMidlet()) {
1056:                        temp.setLength(0);
1057:                        temp
1058:                                .append(Resource
1059:                                        .getString(ResourceConstants.AMS_MGR_SUITE_CONTAINS));
1060:                        temp.append(": ");
1061:                        item = new StringItem(temp.toString(), "");
1062:                        item.setLayout(Item.LAYOUT_NEWLINE_AFTER
1063:                                | Item.LAYOUT_2);
1064:                        confirmForm.append(item);
1065:                        appendMIDletsToForm(midletSuite, confirmForm);
1066:                    }
1067:
1068:                    String[] recordStores = midletSuiteStorage
1069:                            .listRecordStores(suiteInfo.suiteId);
1070:                    if (recordStores != null) {
1071:                        temp.setLength(0);
1072:                        temp
1073:                                .append(Resource
1074:                                        .getString(ResourceConstants.AMS_MGR_SUITE_RECORD_STORES));
1075:                        temp.append(": ");
1076:                        item = new StringItem(temp.toString(), "");
1077:                        item.setLayout(Item.LAYOUT_NEWLINE_AFTER
1078:                                | Item.LAYOUT_2);
1079:                        confirmForm.append(item);
1080:                        appendRecordStoresToForm(recordStores, confirmForm);
1081:                    }
1082:
1083:                    temp.setLength(0);
1084:                    temp.append(" \n");
1085:                    temp.append(Resource.getString(
1086:                            ResourceConstants.AMS_MGR_REM_REINSTALL, values));
1087:                    item = new StringItem("", temp.toString());
1088:                    confirmForm.append(item);
1089:                } catch (Throwable t) {
1090:                    displayError
1091:                            .showErrorAlert(
1092:                                    suiteInfo.displayName,
1093:                                    t,
1094:                                    Resource
1095:                                            .getString(ResourceConstants.AMS_CANT_ACCESS),
1096:                                    null);
1097:                    return;
1098:                } finally {
1099:                    if (midletSuite != null) {
1100:                        midletSuite.close();
1101:                    }
1102:                }
1103:
1104:                confirmForm.addCommand(cancelCmd);
1105:                confirmForm.addCommand(removeOkCmd);
1106:                confirmForm.setCommandListener(this );
1107:                removeMsi = suiteInfo;
1108:                display.setCurrent(confirmForm);
1109:            }
1110:
1111:            /**
1112:             * Appends a names of all the MIDlets in a suite to a Form, one per line.
1113:             *
1114:             * @param midletSuite information of a suite of MIDlets
1115:             * @param form form to append to
1116:             */
1117:            private void appendMIDletsToForm(MIDletSuiteImpl midletSuite,
1118:                    Form form) {
1119:                int numberOfMidlets;
1120:                MIDletInfo midletInfo;
1121:                StringItem item;
1122:
1123:                numberOfMidlets = midletSuite.getNumberOfMIDlets();
1124:                for (int i = 1; i <= numberOfMidlets; i++) {
1125:                    midletInfo = new MIDletInfo(midletSuite
1126:                            .getProperty("MIDlet-" + i));
1127:
1128:                    item = new StringItem(null, midletInfo.name);
1129:                    item.setLayout(Item.LAYOUT_NEWLINE_AFTER | Item.LAYOUT_2);
1130:                    form.append(item);
1131:                }
1132:            }
1133:
1134:            /**
1135:             * Appends names of the record stores owned by the midlet suite
1136:             * to a Form, one per line.
1137:             *
1138:             * @param recordStores list of the record store names
1139:             * @param form form to append to
1140:             */
1141:            private void appendRecordStoresToForm(String[] recordStores,
1142:                    Form form) {
1143:                StringItem item;
1144:
1145:                for (int i = 0; i < recordStores.length; i++) {
1146:                    item = new StringItem(null, recordStores[i]);
1147:                    item.setLayout(Item.LAYOUT_NEWLINE_AFTER | Item.LAYOUT_2);
1148:                    form.append(item);
1149:                }
1150:            }
1151:
1152:            /**
1153:             * Open the settings database and retreive an id of the midlet suite
1154:             * that was installed last.
1155:             *
1156:             * @return ID of the midlet suite that was installed last or
1157:             * MIDletSuite.UNUSED_SUITE_ID.
1158:             */
1159:            private int getLastInstalledMIDlet() {
1160:                ByteArrayInputStream bas;
1161:                DataInputStream dis;
1162:                byte[] data;
1163:                RecordStore settings = null;
1164:                int ret = MIDletSuite.UNUSED_SUITE_ID;
1165:
1166:                try {
1167:                    settings = RecordStore.openRecordStore(
1168:                            GraphicalInstaller.SETTINGS_STORE, false);
1169:
1170:                    /** we should be guaranteed that this is always the case! */
1171:                    if (settings.getNumRecords() > 0) {
1172:
1173:                        data = settings
1174:                                .getRecord(GraphicalInstaller.SELECTED_MIDLET_RECORD_ID);
1175:
1176:                        if (data != null) {
1177:                            bas = new ByteArrayInputStream(data);
1178:                            dis = new DataInputStream(bas);
1179:                            ret = dis.readInt();
1180:                        }
1181:                    }
1182:
1183:                } catch (RecordStoreException e) {
1184:                    // ignore
1185:                } catch (IOException e) {
1186:                    // ignore
1187:                } finally {
1188:                    if (settings != null) {
1189:                        try {
1190:                            settings.closeRecordStore();
1191:                        } catch (RecordStoreException e) {
1192:                            // ignore
1193:                        }
1194:                    }
1195:                }
1196:
1197:                return ret;
1198:            }
1199:
1200:            /**
1201:             * Finds a MidletCustomItem corresponding to the last installed
1202:             * midlet suite.
1203:             * @return the midlet custom item if it was found, null otherwise
1204:             */
1205:            private MidletCustomItem getLastInstalledMidletItem() {
1206:                int installedMidlet = getLastInstalledMIDlet();
1207:
1208:                if (installedMidlet != MIDletSuite.UNUSED_SUITE_ID
1209:                        && installedMidlet != MIDletSuite.INTERNAL_SUITE_ID) {
1210:                    for (int i = 0; i < size(); i++) {
1211:                        MidletCustomItem ci = (MidletCustomItem) get(i);
1212:                        if (ci.msi.suiteId == installedMidlet) {
1213:                            return ci;
1214:                        }
1215:                    }
1216:                }
1217:
1218:                return null;
1219:            }
1220:
1221:            /**
1222:             * Displayas AppManagerUI with a recently installed midlet hilighted.
1223:             * @return true if display.setCurrentItem() was called,
1224:             *              false - otherwise
1225:             */
1226:            private boolean displayLastInstalledMidlet() {
1227:                MidletCustomItem ci = getLastInstalledMidletItem();
1228:
1229:                if (ci != null) {
1230:                    display.setCurrentItem(ci);
1231:                    return true;
1232:                }
1233:
1234:                return false;
1235:            }
1236:
1237:            /**
1238:             * Launches the midlet suite described by the given MIDletSuiteInfo.
1239:             * @param msi a structure with information about the midlet suite
1240:             * that must be launched
1241:             */
1242:            private void launchMidlet(RunningMIDletSuiteInfo msi) {
1243:                if (msi.hasSingleMidlet()) {
1244:                    manager.launchSuite(msi, msi.midletToRun);
1245:                    display.setCurrent(this );
1246:                } else {
1247:                    try {
1248:                        new MIDletSelector(msi, display, this , manager);
1249:                    } catch (Throwable t) {
1250:                        displayError.showErrorAlert(msi.displayName, t, null,
1251:                                null);
1252:                    }
1253:                }
1254:            }
1255:
1256:            /**
1257:             * Prompts the user to specify whether to launch a midlet from
1258:             * the midlet suite that was just installed.
1259:             */
1260:            private void askUserIfLaunchMidlet() {
1261:                // Ask the user if he wants to run a midlet from
1262:                // the newly installed midlet suite
1263:                String title = Resource
1264:                        .getString(
1265:                                ResourceConstants.AMS_MGR_RUN_THE_NEW_SUITE_TITLE,
1266:                                null);
1267:                String msg = Resource.getString(
1268:                        ResourceConstants.AMS_MGR_RUN_THE_NEW_SUITE, null);
1269:
1270:                Alert alert = new Alert(title, msg, null,
1271:                        AlertType.CONFIRMATION);
1272:                alert.addCommand(runNoCmd);
1273:                alert.addCommand(runYesCmd);
1274:                alert.setCommandListener(this );
1275:                alert.setTimeout(Alert.FOREVER);
1276:
1277:                display.setCurrent(alert);
1278:            }
1279:
1280:            /** A Timer which will handle firing repaints of the ScrollPainter */
1281:            protected static Timer textScrollTimer;
1282:
1283:            /** Text auto-scrolling parameters */
1284:            private static int SCROLL_RATE = 250;
1285:
1286:            private static int SCROLL_DELAY = 500;
1287:
1288:            private static int SCROLL_SPEED = 10;
1289:
1290:            /**
1291:             * Inner class used to display a running midlet in the AppSelector.
1292:             * MidletCustomItem consists of an icon and name associated with the
1293:             * corresponding midlet. In addition if a midlet requests to be
1294:             * put into foreground (requires user attention) an additional
1295:             * system provided icon will be displayed.
1296:             */
1297:            class MidletCustomItem extends CustomItem {
1298:
1299:                /**
1300:                 * Constructs a midlet representation for the App Selector Screen.
1301:                 * @param msi The MIDletSuiteInfo for which representation has
1302:                 *            to be created
1303:                 */
1304:                MidletCustomItem(RunningMIDletSuiteInfo msi) {
1305:                    super (null);
1306:                    this .msi = msi;
1307:                    icon = msi.icon;
1308:                    text = msi.displayName.toCharArray();
1309:                    textLen = msi.displayName.length();
1310:                    truncWidth = ICON_FONT.charWidth(truncationMark);
1311:                    truncated = false;
1312:                    if (textScrollTimer == null) {
1313:                        textScrollTimer = new Timer();
1314:                    }
1315:                    xScrollOffset = 0;
1316:
1317:                }
1318:
1319:                /**
1320:                 * Gets the minimum width of a midlet representation in
1321:                 * the App Selector Screen.
1322:                 * @return the minimum width of a midlet representation
1323:                 *         in the App Selector Screen.
1324:                 */
1325:                protected int getMinContentWidth() {
1326:                    return AppManagerUI.this .getWidth();
1327:                }
1328:
1329:                /**
1330:                 * Gets the minimum height of a midlet representation in
1331:                 * the App Selector Screen.
1332:                 * @return the minimum height of a midlet representation
1333:                 *         in the App Selector Screen.
1334:                 */
1335:                protected int getMinContentHeight() {
1336:                    return ICON_BG.getHeight() > ICON_FONT.getHeight() ? ICON_BG
1337:                            .getHeight()
1338:                            : ICON_FONT.getHeight();
1339:                }
1340:
1341:                /**
1342:                 * Gets the preferred width of a midlet representation in
1343:                 * the App Selector Screen based on the passed in height.
1344:                 * @param height the amount of height available for this Item
1345:                 * @return the minimum width of a midlet representation
1346:                 *         in the App Selector Screen.
1347:                 */
1348:                protected int getPrefContentWidth(int height) {
1349:                    return AppManagerUI.this .getWidth();
1350:                }
1351:
1352:                /**
1353:                 * Gets the preferred height of a midlet representation in
1354:                 * the App Selector Screen based on the passed in width.
1355:                 * @param width the amount of width available for this Item
1356:                 * @return the minimum height of a midlet representation
1357:                 *         in the App Selector Screen.
1358:                 */
1359:                protected int getPrefContentHeight(int width) {
1360:                    return ICON_BG.getHeight() > ICON_FONT.getHeight() ? ICON_BG
1361:                            .getHeight()
1362:                            : ICON_FONT.getHeight();
1363:                }
1364:
1365:                /**
1366:                 * On size change event we define the item's text
1367:                 * according to item's new width
1368:                 * @param w The current width of this Item
1369:                 * @param h The current height of this Item
1370:                 */
1371:                protected void sizeChanged(int w, int h) {
1372:                    width = w;
1373:                    height = h;
1374:                    int widthForText = w - ITEM_PAD - ICON_BG.getWidth();
1375:                    int msiNameWidth = ICON_FONT.charsWidth(text, 0, textLen);
1376:                    scrollWidth = msiNameWidth - widthForText + w / 5;
1377:                    truncated = msiNameWidth > widthForText;
1378:                }
1379:
1380:                /**
1381:                 * Paints the content of a midlet representation in
1382:                 * the App Selector Screen.
1383:                 * Note that icon representing that foreground was requested
1384:                 * is painted on to of the existing ickon.
1385:                 * @param g The graphics context where painting should be done
1386:                 * @param w The width available to this Item
1387:                 * @param h The height available to this Item
1388:                 */
1389:                protected void paint(Graphics g, int w, int h) {
1390:                    int cX = g.getClipX();
1391:                    int cY = g.getClipY();
1392:                    int cW = g.getClipWidth();
1393:                    int cH = g.getClipHeight();
1394:
1395:                    if ((cW + cX) > bgIconW) {
1396:                        if (text != null && h > ICON_FONT.getHeight()) {
1397:
1398:                            int color;
1399:                            if (msi.proxy == null) {
1400:                                color = hasFocus ? ICON_HL_TEXT : ICON_TEXT;
1401:                            } else {
1402:                                color = hasFocus ? ICON_RUNNING_HL_TEXT
1403:                                        : ICON_RUNNING_TEXT;
1404:                            }
1405:
1406:                            g.setColor(color);
1407:                            g.setFont(ICON_FONT);
1408:
1409:                            boolean truncate = (xScrollOffset == 0)
1410:                                    && truncated;
1411:
1412:                            g.clipRect(bgIconW + ITEM_PAD, 0, truncate ? w
1413:                                    - truncWidth - bgIconW - 2 * ITEM_PAD : w
1414:                                    - bgIconW - 2 * ITEM_PAD, h);
1415:                            g.drawChars(text, 0, textLen, bgIconW + ITEM_PAD
1416:                                    + xScrollOffset,
1417:                                    (h - ICON_FONT.getHeight()) / 2,
1418:                                    Graphics.LEFT | Graphics.TOP);
1419:                            g.setClip(cX, cY, cW, cH);
1420:
1421:                            if (truncate) {
1422:                                g.drawChar(truncationMark, w - truncWidth,
1423:                                        (h - ICON_FONT.getHeight()) / 2,
1424:                                        Graphics.LEFT | Graphics.TOP);
1425:                            }
1426:
1427:                        }
1428:                    }
1429:
1430:                    if (cX < bgIconW) {
1431:                        if (hasFocus) {
1432:                            g.drawImage(ICON_BG, 0, (h - bgIconH) / 2,
1433:                                    Graphics.TOP | Graphics.LEFT);
1434:                        }
1435:
1436:                        if (icon != null) {
1437:                            g.drawImage(icon, (bgIconW - icon.getWidth()) / 2,
1438:                                    (bgIconH - icon.getHeight()) / 2,
1439:                                    Graphics.TOP | Graphics.LEFT);
1440:                        }
1441:
1442:                        // Draw special icon if user attention is requested and
1443:                        // that midlet needs to be brought into foreground by the user
1444:                        if (msi.proxy != null && msi.proxy.isAlertWaiting()) {
1445:                            g.drawImage(FG_REQUESTED, bgIconW
1446:                                    - FG_REQUESTED.getWidth(), 0, Graphics.TOP
1447:                                    | Graphics.LEFT);
1448:                        }
1449:
1450:                        if (!msi.enabled) {
1451:                            // indicate that this suite is disabled
1452:                            g.drawImage(DISABLED_IMAGE,
1453:                                    (bgIconW - DISABLED_IMAGE.getWidth()) / 2,
1454:                                    (bgIconH - DISABLED_IMAGE.getHeight()) / 2,
1455:                                    Graphics.TOP | Graphics.LEFT);
1456:                        }
1457:                    }
1458:
1459:                }
1460:
1461:                /**
1462:                 * Start the scrolling of the text
1463:                 */
1464:                protected void startScroll() {
1465:                    if (!hasFocus || !truncated) {
1466:                        return;
1467:                    }
1468:                    stopScroll();
1469:                    textScrollPainter = new TextScrollPainter();
1470:                    textScrollTimer.schedule(textScrollPainter, SCROLL_DELAY,
1471:                            SCROLL_RATE);
1472:                }
1473:
1474:                /**
1475:                 * Stop the scrolling of the text
1476:                 */
1477:                protected void stopScroll() {
1478:                    if (textScrollPainter == null) {
1479:                        return;
1480:                    }
1481:                    xScrollOffset = 0;
1482:                    textScrollPainter.cancel();
1483:                    textScrollPainter = null;
1484:                    repaint(bgIconW, 0, width, height);
1485:                }
1486:
1487:                /**
1488:                 * Called repeatedly to animate a side-scroll effect for text
1489:                 */
1490:                protected void repaintScrollText() {
1491:                    if (-xScrollOffset < scrollWidth) {
1492:                        xScrollOffset -= SCROLL_SPEED;
1493:                        repaint(bgIconW, 0, width, height);
1494:                    } else {
1495:                        // already scrolled to the end of text
1496:                        stopScroll();
1497:                    }
1498:                }
1499:
1500:                /**
1501:                 * Handles traversal.
1502:                 * @param dir The direction of traversal (Canvas.UP, Canvas.DOWN,
1503:                 *            Canvas.LEFT, Canvas.RIGHT)
1504:                 * @param viewportWidth The width of the viewport in the AppSelector
1505:                 * @param viewportHeight The height of the viewport in the AppSelector
1506:                 * @param visRect_inout The return array that tells AppSelector
1507:                 *        which portion of the MidletCustomItem has to be made visible
1508:                 * @return true if traversal was handled in this method
1509:                 *         (this MidletCustomItem just got focus or there was an
1510:                 *         internal traversal), otherwise false - to transfer focus
1511:                 *         to the next item
1512:                 */
1513:                protected boolean traverse(int dir, int viewportWidth,
1514:                        int viewportHeight, int visRect_inout[]) {
1515:                    // entirely visible and hasFocus
1516:                    if (!hasFocus) {
1517:                        hasFocus = true;
1518:                        lastSelectedMsi = this .msi;
1519:                    }
1520:
1521:                    visRect_inout[0] = 0;
1522:                    visRect_inout[1] = 0;
1523:                    visRect_inout[2] = width;
1524:                    visRect_inout[3] = height;
1525:
1526:                    startScroll();
1527:
1528:                    return false;
1529:                }
1530:
1531:                /**
1532:                 * Handles traversal out. This method is called when this
1533:                 * MidletCustomItem looses focus.
1534:                 */
1535:                protected void traverseOut() {
1536:                    hasFocus = false;
1537:                    stopScroll();
1538:                }
1539:
1540:                /**
1541:                 * Repaints MidletCustomItem. Called when internal state changes.
1542:                 */
1543:                public void update() {
1544:                    repaint();
1545:                }
1546:
1547:                /**
1548:                 * Sets the owner (AppManagerUI) of this MidletCustomItem
1549:                 * @param hs The AppSelector in which this MidletCustomItem is shown
1550:                 */
1551:                void setOwner(AppManagerUI hs) {
1552:                    owner = hs;
1553:                }
1554:
1555:                /**
1556:                 * Sets default <code>Command</code> for this <code>Item</code>.
1557:                 *
1558:                 * @param c the command to be used as this <code>Item's</code> default
1559:                 * <code>Command</code>, or <code>null</code> if there is to
1560:                 * be no default command
1561:                 */
1562:                public void setDefaultCommand(Command c) {
1563:                    default_command = c;
1564:                    super .setDefaultCommand(c);
1565:                }
1566:
1567:                /**
1568:                 * Called when MidletCustomItem is shown.
1569:                 */
1570:                public void showNotify() {
1571:
1572:                    // Unfortunately there is no Form.showNotify  method where
1573:                    // this could have been done.
1574:
1575:                    // When icon for the Installer
1576:                    // is shown we want to make sure
1577:                    // that there are no running midlets from the "internal" suite.
1578:                    // The only 2 midlets that can run in bg from
1579:                    // "internal" suite are the DiscoveryApp and the Installer.
1580:                    // Icon for the Installer will be shown each time
1581:                    // the AppSelector is made current since it is the top
1582:                    // most icon and we reset the traversal to start from the top
1583:                    if (msi.suiteId == MIDletSuite.INTERNAL_SUITE_ID
1584:                            && appManagerMidlet != null) {
1585:                        appManagerMidlet.destroyMidlet();
1586:                    }
1587:                }
1588:
1589:                /** A TimerTask which will repaint scrolling text  on a repeated basis */
1590:                protected TextScrollPainter textScrollPainter;
1591:
1592:                /**
1593:                 * Width of the scroll area for text
1594:                 */
1595:                protected int scrollWidth;
1596:
1597:                /**
1598:                 * If text is truncated
1599:                 */
1600:                boolean truncated;
1601:
1602:                /**
1603:                 * pixel offset to the start of the text field  (for example,  if
1604:                 * xScrollOffset is -60 it means means that the text in this
1605:                 * text field is scrolled 60 pixels left of the left edge of the
1606:                 * text field)
1607:                 */
1608:                protected int xScrollOffset;
1609:
1610:                /**
1611:                 * Helper class used to repaint scrolling text
1612:                 * if needed.
1613:                 */
1614:                private class TextScrollPainter extends TimerTask {
1615:                    /**
1616:                     * Repaint the item text
1617:                     */
1618:                    public final void run() {
1619:                        repaintScrollText();
1620:                    }
1621:                }
1622:
1623:                /** True if this MidletCustomItem has focus, and false - otherwise */
1624:                boolean hasFocus; // = false;
1625:
1626:                /** The owner of this MidletCustomItem */
1627:                AppManagerUI owner; // = false
1628:
1629:                /** The MIDletSuiteInfo associated with this MidletCustomItem */
1630:                RunningMIDletSuiteInfo msi; // = null
1631:
1632:                /** The width of this MidletCustomItem */
1633:                int width; // = 0
1634:                /** The height of this MIDletSuiteInfo */
1635:                int height; // = 0
1636:
1637:                /** Cashed width of the truncation mark */
1638:                int truncWidth;
1639:
1640:                /** The text of this MidletCustomItem */
1641:                char[] text;
1642:
1643:                /** Length of the text */
1644:                int textLen;
1645:
1646:                /**
1647:                 * The icon to be used to draw this midlet representation.
1648:                 */
1649:                Image icon; // = null
1650:                /** current default command */
1651:                Command default_command; // = null
1652:            }
1653:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.