001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package com.sun.midp.appmanager;
028:
029: import javax.microedition.midlet.*;
030:
031: import javax.microedition.lcdui.*;
032:
033: import com.sun.midp.i18n.Resource;
034: import com.sun.midp.i18n.ResourceConstants;
035:
036: import com.sun.midp.midlet.*;
037:
038: import com.sun.midp.installer.*;
039:
040: import com.sun.midp.midletsuite.*;
041:
042: import com.sun.midp.main.*;
043:
044: import com.sun.midp.configurator.Constants;
045:
046: /**
047: * This is an implementation of the ApplicationManager interface
048: * for the single VM mode of the VM.
049: *
050: * In this mode the VM is shut down each time a MIDlet exits.
051: *
052: * Application manager controls midlet life cycle:
053: * - installs, updates and removes midlets/midlet suites
054: * - launches and terminates midlets
055: * - displays info about a midlet/midlet suite
056: * - shuts down the AMS system
057: */
058: public class Manager extends MIDlet implements ApplicationManager {
059:
060: /** Constant for the discovery application class name. */
061: private static final String DISCOVERY_APP = "com.sun.midp.installer.DiscoveryApp";
062:
063: /** Constant for the graphical installer class name. */
064: private static final String INSTALLER = "com.sun.midp.installer.GraphicalInstaller";
065:
066: /** Constant for the CA manager class name. */
067: private static final String CA_MANAGER = "com.sun.midp.appmanager.CaManager";
068:
069: /** True until constructed for the first time. */
070: private static boolean first = true;
071:
072: /** MIDlet Suite storage object. */
073: private MIDletSuiteStorage midletSuiteStorage;
074:
075: /** UI to display error alerts. */
076: private DisplayError displayError;
077:
078: /** Application Selector Screen. */
079: private AppManagerUI managerUI;
080:
081: /**
082: * Create and initialize a new Manager MIDlet.
083: */
084: public Manager() {
085: midletSuiteStorage = MIDletSuiteStorage.getMIDletSuiteStorage();
086:
087: GraphicalInstaller.initSettings();
088:
089: first = (getAppProperty("logo-displayed") == null);
090:
091: Display display = Display.getDisplay(this );
092: displayError = new DisplayError(display);
093:
094: // Get arguments to create AppManagerUI
095: String suiteIdStr = getAppProperty("arg-0");
096: int suiteId = MIDletSuite.UNUSED_SUITE_ID;
097: try {
098: suiteId = Integer.parseInt(suiteIdStr);
099: } catch (NumberFormatException e) {
100: suiteId = MIDletSuite.UNUSED_SUITE_ID;
101: }
102:
103: if (suiteId != MIDletSuite.UNUSED_SUITE_ID) {
104: MIDletSuiteInfo sui = new MIDletSuiteInfo(suiteId);
105: if (suiteId == MIDletSuite.INTERNAL_SUITE_ID) {
106: // For internal suites midlet class name should be specified
107: sui.midletToRun = getAppProperty("arg-1");
108: }
109: // AppManagerUI will be set to be current at the end of its constructor
110: managerUI = new AppManagerUI(this , display, displayError,
111: first, sui);
112: } else {
113: // AppManagerUI will be set to be current at the end of its constructor
114: managerUI = new AppManagerUI(this , display, displayError,
115: first, null);
116: }
117:
118: if (first) {
119: first = false;
120: }
121: }
122:
123: /**
124: * Start puts up a List of the MIDlets found in the descriptor file.
125: */
126: public void startApp() {
127: }
128:
129: /**
130: * Pause; there are no resources that need to be released.
131: */
132: public void pauseApp() {
133: }
134:
135: /**
136: * Destroy cleans up.
137: *
138: * @param unconditional is ignored; this object always
139: * destroys itself when requested.
140: */
141: public void destroyApp(boolean unconditional) {
142: GraphicalInstaller.saveSettings(null,
143: MIDletSuite.UNUSED_SUITE_ID);
144:
145: if (MIDletSuiteUtils.getNextMIDletSuiteToRun() != MIDletSuite.UNUSED_SUITE_ID) {
146: /*
147: * A MIDlet was pushed.
148: * So make sure this MIDlet is run after the pushed one.
149: *
150: * Note this call only is
151: * needed now because suites are not run concurrently and must
152: * be queued to be run after this MIDlet is destroyed.
153: */
154: updateLastSuiteToRun();
155: }
156: }
157:
158: // ===================================================================
159: // ---- Implementation of the ApplicationManager interface ------------
160:
161: /**
162: * Discover and install a suite.
163: */
164: public void installSuite() {
165: try {
166: MIDletStateHandler
167: .getMidletStateHandler()
168: .startMIDlet(
169: DISCOVERY_APP,
170: Resource
171: .getString(ResourceConstants.INSTALL_APPLICATION));
172:
173: yieldForNextMidlet();
174:
175: } catch (Exception ex) {
176: displayError.showErrorAlert(Resource
177: .getString(ResourceConstants.INSTALL_APPLICATION),
178: ex, null, null);
179: }
180: }
181:
182: /** Launch the CA manager. */
183: public void launchCaManager() {
184: try {
185: MIDletStateHandler
186: .getMidletStateHandler()
187: .startMIDlet(
188: CA_MANAGER,
189: Resource
190: .getString(ResourceConstants.CA_MANAGER_APP));
191:
192: yieldForNextMidlet();
193:
194: } catch (Exception ex) {
195: displayError.showErrorAlert(Resource
196: .getString(ResourceConstants.CA_MANAGER_APP), ex,
197: null, null);
198: }
199: }
200:
201: /**
202: * Launches a suite.
203: *
204: * @param suiteInfo information for suite to launch
205: * @param midletToRun class name of the MIDlet to launch
206: */
207: public void launchSuite(RunningMIDletSuiteInfo suiteInfo,
208: String midletToRun) {
209:
210: if (Constants.MEASURE_STARTUP) {
211: System.err.println("Application Startup Time: Begin at "
212: + System.currentTimeMillis());
213: }
214:
215: try {
216: // Create an instance of the MIDlet class
217: // All other initialization happens in MIDlet constructor
218: MIDletSuiteUtils.execute(suiteInfo.suiteId, midletToRun,
219: suiteInfo.displayName);
220:
221: /*
222: * Give the new MIDlet the screen by destroy our self,
223: * because we are running in a limited VM and must
224: * restart the VM let the select suite run.
225: */
226: yieldForNextMidlet();
227:
228: } catch (Exception ex) {
229: displayError.showErrorAlert(suiteInfo.displayName, ex,
230: null, null);
231: }
232: }
233:
234: /**
235: * Update a suite.
236: *
237: * @param suiteInfo information for suite to update
238: */
239: public void updateSuite(RunningMIDletSuiteInfo suiteInfo) {
240: MIDletStateHandler midletStateHandler = MIDletStateHandler
241: .getMidletStateHandler();
242: MIDletSuite midletSuite = midletStateHandler.getMIDletSuite();
243:
244: /*
245: * Setting arg 0 to "U" signals that arg 1 is a suite ID for updating.
246: */
247: midletSuite.setTempProperty(null, "arg-0", "U");
248: midletSuite.setTempProperty(null, "arg-1", String
249: .valueOf(suiteInfo.suiteId));
250: try {
251: midletStateHandler.startMIDlet(INSTALLER, null);
252: yieldForNextMidlet();
253:
254: } catch (Exception ex) {
255: displayError.showErrorAlert(suiteInfo.displayName, ex,
256: null, null);
257: }
258: }
259:
260: /**
261: * Shut down the system
262: */
263: public void shutDown() {
264: MIDletProxyList.getMIDletProxyList().shutdown();
265: }
266:
267: /**
268: * Bring the midlet with the passed in midlet suite info to the
269: * foreground.
270: *
271: * @param suiteInfo information for the midlet to be put to foreground
272: */
273: public void moveToForeground(RunningMIDletSuiteInfo suiteInfo) {
274: }
275:
276: /**
277: * Exit the midlet with the passed in midlet suite info.
278: *
279: * @param suiteInfo information for the midlet to be terminated
280: */
281: public void exitMidlet(RunningMIDletSuiteInfo suiteInfo) {
282: }
283:
284: // ==============================================================
285: // ----------------- PRIVATE methods ---------------------------
286:
287: /**
288: * Yield the VM so the next MIDlet can run. To yield set this MIDlet as
289: * last MIDlet run after the next MIDlet suite is done and then destroy
290: * this MIDlet. Note: if the system is changed to allow multiple suites
291: * to run concurrently, this method will not be needed.
292: */
293: private void yieldForNextMidlet() {
294: // We want this MIDlet to run after the next MIDlet is run.
295: updateLastSuiteToRun();
296: destroyApp(false);
297: notifyDestroyed();
298: }
299:
300: /**
301: * Set this MIDlet to run after the next MIDlet is run.
302: */
303: private void updateLastSuiteToRun() {
304: MIDletSuiteInfo msi = managerUI.getSelectedMIDletSuiteInfo();
305: if (msi == null) {
306: MIDletSuiteUtils.setLastSuiteToRun(MIDletStateHandler
307: .getMidletStateHandler().getMIDletSuite().getID(),
308: getClass().getName(), null, null);
309: } else {
310: String midletToRun = null;
311: if (msi.suiteId == MIDletSuite.INTERNAL_SUITE_ID) {
312: midletToRun = msi.midletToRun;
313: }
314: MIDletSuiteUtils.setLastSuiteToRun(MIDletStateHandler
315: .getMidletStateHandler().getMIDletSuite().getID(),
316: getClass().getName(), String.valueOf(msi.suiteId),
317: midletToRun);
318: }
319: }
320: }
|