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.main;
028:
029: import com.sun.midp.lcdui.DisplayEventHandler;
030: import com.sun.midp.lcdui.SystemAlert;
031: import com.sun.midp.security.SecurityToken;
032: import com.sun.midp.security.Permissions;
033: import com.sun.midp.midletsuite.MIDletSuiteStorage;
034: import com.sun.midp.midlet.MIDletSuite;
035: import com.sun.midp.midlet.MIDletStateHandler;
036: import javax.microedition.lcdui.AlertType;
037:
038: /**
039: * The class designed to provide utils for starting MIDlet suites,
040: * and scheduling their start using VM cycling mechanism.
041: */
042: public class MIDletSuiteUtils {
043:
044: /** The unique ID of the last MIDlet suite to run. */
045: static int lastMidletSuiteToRun;
046:
047: /** The class name of the last MIDlet to run. */
048: static String lastMidletToRun;
049:
050: /**
051: * If not null, this will be available to the last MIDlet to run as
052: * application property arg-0.
053: */
054: static String arg0ForLastMidlet;
055:
056: /**
057: * If not null, this will be available to the last MIDlet to run as
058: * application property arg-1.
059: */
060: static String arg1ForLastMidlet;
061:
062: /** The unique ID of the next MIDlet suite to run. */
063: static int nextMidletSuiteToRun;
064:
065: /** The class of the next MIDlet to run. */
066: static String nextMidletToRun;
067:
068: /**
069: * If not null, this will be available to the MIDlet to run as
070: * application property arg-0.
071: */
072: static String arg0ForNextMidlet;
073:
074: /**
075: * If not null, this will be available to the MIDlet to run as
076: * application property arg-1.
077: */
078: static String arg1ForNextMidlet;
079:
080: /**
081: * If not null, this will be available to the MIDlet to run as
082: * application property arg-2.
083: */
084: static String arg2ForNextMidlet;
085:
086: /**
087: * The minimum amount of memory guaranteed to be available
088: * to the VM at any time; < 0 if not used.
089: */
090: static int memoryReserved;
091:
092: /**
093: * The total amount of memory that the VM can reserve; < 0 if not used.
094: */
095: static int memoryTotal;
096:
097: /**
098: * Priority to set after restarting the VM; <= 0 if not used.
099: */
100: static int priority;
101:
102: /**
103: * Name of the profile to set after restarting the VM; null if not used.
104: */
105: static String profileName;
106:
107: /**
108: * Display an exception to the user.
109: *
110: * @param handler display event handler to draw displays
111: * @param exceptionMsg exception message
112: */
113: static void displayException(DisplayEventHandler handler,
114: String exceptionMsg) {
115:
116: SystemAlert alert = new SystemAlert(handler, "Exception",
117: exceptionMsg, null, AlertType.ERROR);
118: alert.run();
119: alert.waitForUser();
120: }
121:
122: /**
123: * Starts a MIDlet in a new Isolate or
124: * queues the execution of the named Application suite to run.
125: * The current application suite should terminate itself normally
126: * to make resources available to the new application suite. Only
127: * one package and set of MIDlets can be queued in this manner.
128: * If multiple calls to execute are made, the package and MIDlets
129: * specified during the <em>last</em> invocation will be executed
130: * when the current application is terminated.
131: *
132: * @param id ID of an installed suite
133: * @param midlet class name of MIDlet to invoke
134: * @param displayName name to display to the user
135: *
136: * @return true if the MIDlet suite MUST first exit before the
137: * MIDlet is run
138: *
139: * @exception SecurityException if the caller does not have permission
140: * to manage midlets
141: */
142: public static boolean execute(int id, String midlet,
143: String displayName) {
144: return executeWithArgs(id, midlet, displayName, null, null,
145: null);
146: }
147:
148: /**
149: * Starts a MIDlet in a new Isolate or
150: * queues the execution of the named Application suite to run.
151: * The current application suite should terminate itself normally
152: * to make resources available to the new application suite. Only
153: * one package and set of MIDlets can be queued in this manner.
154: * If multiple calls to execute are made, the package and MIDlets
155: * specified during the <em>last</em> invocation will be executed
156: * when the current application is terminated.
157: *
158: * @param securityToken security token of the calling class
159: * application manager
160: * @param suiteId ID of an installed suite
161: * @param midlet class name of MIDlet to invoke
162: * @param displayName name to display to the user
163: *
164: * @return true if the MIDlet suite MUST first exit before the
165: * MIDlet is run
166: *
167: * @exception SecurityException if the caller does not have permission
168: * to manage midlets
169: */
170: public static boolean execute(SecurityToken securityToken,
171: int suiteId, String midlet, String displayName) {
172:
173: return executeWithArgs(securityToken, suiteId, midlet,
174: displayName, null, null, null);
175: }
176:
177: /**
178: * Starts a MIDlet in a new Isolate or
179: * queues the execution of the named Application suite to run.
180: * The current application suite should terminate itself normally
181: * to make resources available to the new application suite. Only
182: * one package and set of MIDlets can be queued in this manner.
183: * If multiple calls to execute are made, the package and MIDlets
184: * specified during the <em>last</em> invocation will be executed
185: * when the current application is terminated.
186: *
187: * @param suiteId ID of an installed suite
188: * @param midlet class name of MIDlet to invoke
189: * @param displayName name to display to the user
190: * @param arg0 if not null, this parameter will be available to the
191: * MIDlet as application property arg-0
192: * @param arg1 if not null, this parameter will be available to the
193: * MIDlet as application property arg-1
194: * @param arg2 if not null, this parameter will be available to the
195: * MIDlet as application property arg-2
196: *
197: * @return true if the MIDlet suite MUST first exit before the
198: * MIDlet is run
199: *
200: * @exception SecurityException if the caller does not have permission
201: * to manage midlets
202: */
203: public static boolean executeWithArgs(int suiteId, String midlet,
204: String displayName, String arg0, String arg1, String arg2) {
205:
206: return executeWithArgs(null, suiteId, midlet, displayName,
207: arg0, arg1, arg2);
208: }
209:
210: /**
211: * Starts a MIDlet in a new Isolate or
212: * queues the execution of the named Application suite to run.
213: * The current application suite should terminate itself normally
214: * to make resources available to the new application suite. Only
215: * one package and set of MIDlets can be queued in this manner.
216: * If multiple calls to execute are made, the package and MIDlets
217: * specified during the <em>last</em> invocation will be executed
218: * when the current application is terminated.
219: *
220: * @param securityToken security token of the calling class
221: * @param suiteId ID of an installed suite
222: * @param midlet class name of MIDlet to invoke
223: * @param displayName name to display to the user
224: * @param arg0 if not null, this parameter will be available to the
225: * MIDlet as application property arg-0
226: * @param arg1 if not null, this parameter will be available to the
227: * MIDlet as application property arg-1
228: * @param arg2 if not null, this parameter will be available to the
229: * MIDlet as application property arg-2
230: *
231: * @return true if the MIDlet suite MUST first exit before the
232: * MIDlet is run
233: *
234: * @exception SecurityException if the caller does not have permission
235: * to manage midlets
236: */
237: public static boolean executeWithArgs(SecurityToken securityToken,
238: int suiteId, String midlet, String displayName,
239: String arg0, String arg1, String arg2) {
240:
241: return executeWithArgs(securityToken, 0, suiteId, midlet,
242: displayName, arg0, arg1, arg2);
243: }
244:
245: /**
246: * Starts a MIDlet in a new Isolate or
247: * queues the execution of the named Application suite to run.
248: * The current application suite should terminate itself normally
249: * to make resources available to the new application suite. Only
250: * one package and set of MIDlets can be queued in this manner.
251: * If multiple calls to execute are made, the package and MIDlets
252: * specified during the <em>last</em> invocation will be executed
253: * when the current application is terminated.
254: *
255: * @param securityToken security token of the calling class
256: * @param externalAppId ID of MIDlet to invoke, given by an external
257: * application manager
258: * @param suiteId ID of an installed suite
259: * @param midlet class name of MIDlet to invoke
260: * @param displayName name to display to the user
261: * @param arg0 if not null, this parameter will be available to the
262: * MIDlet as application property arg-0
263: * @param arg1 if not null, this parameter will be available to the
264: * MIDlet as application property arg-1
265: * @param arg2 if not null, this parameter will be available to the
266: * MIDlet as application property arg-2
267: *
268: * @return true if the MIDlet suite MUST first exit before the
269: * MIDlet is run
270: *
271: * @exception SecurityException if the caller does not have permission
272: * to manage midlets
273: */
274: public static boolean executeWithArgs(SecurityToken securityToken,
275: int externalAppId, int suiteId, String midlet,
276: String displayName, String arg0, String arg1, String arg2) {
277:
278: return executeWithArgs(securityToken, externalAppId, suiteId,
279: midlet, displayName, arg0, arg1, arg2, -1, -1, -1, null);
280: }
281:
282: /**
283: * Starts a MIDlet in a new Isolate or
284: * queues the execution of the named Application suite to run.
285: * The current application suite should terminate itself normally
286: * to make resources available to the new application suite. Only
287: * one package and set of MIDlets can be queued in this manner.
288: * If multiple calls to execute are made, the package and MIDlets
289: * specified during the <em>last</em> invocation will be executed
290: * when the current application is terminated.
291: *
292: * @param securityToken security token of the calling class
293: * @param externalAppId ID of MIDlet to invoke, given by an external
294: * application manager
295: * @param suiteId ID of an installed suite
296: * @param midlet class name of MIDlet to invoke
297: * @param displayName name to display to the user
298: * @param arg0 if not null, this parameter will be available to the
299: * MIDlet as application property arg-0
300: * @param arg1 if not null, this parameter will be available to the
301: * MIDlet as application property arg-1
302: * @param arg2 if not null, this parameter will be available to the
303: * MIDlet as application property arg-2
304: * @param memoryReserved the minimum amount of memory guaranteed to be
305: * available to the isolate at any time; < 0 if not used
306: * @param memoryTotal the total amount of memory that the isolate can
307: reserve; < 0 if not used
308: * @param priority priority to set for the new isolate;
309: * <= 0 if not used
310: * @param profileName name of the profile to set for the new isolate;
311: * null if not used
312: *
313: * @return true if the MIDlet suite MUST first exit before the
314: * MIDlet is run
315: *
316: * @exception SecurityException if the caller does not have permission
317: * to manage midlets
318: */
319: public static boolean executeWithArgs(SecurityToken securityToken,
320: int externalAppId, int suiteId, String midlet,
321: String displayName, String arg0, String arg1, String arg2,
322: int memoryReserved, int memoryTotal, int priority,
323: String profileName) {
324:
325: MIDletSuiteStorage midletSuiteStorage;
326:
327: // Note: getMIDletSuiteStorage performs an AMS permission check.
328: if (securityToken != null) {
329: midletSuiteStorage = MIDletSuiteStorage
330: .getMIDletSuiteStorage(securityToken);
331: } else {
332: midletSuiteStorage = MIDletSuiteStorage
333: .getMIDletSuiteStorage();
334: }
335:
336: return AmsUtil.executeWithArgs(midletSuiteStorage,
337: externalAppId, suiteId, midlet, displayName, arg0,
338: arg1, arg2, memoryReserved, memoryTotal, priority,
339: profileName);
340: }
341:
342: /**
343: * Gets the unique storage name of the next MIDlet suite to run.
344: *
345: * @return storage name of a MIDlet suite
346: */
347: public static int getNextMIDletSuiteToRun() {
348: return nextMidletSuiteToRun;
349: }
350:
351: /**
352: * Gets the name of the next MIDlet to run.
353: *
354: * @return storage name of a MIDlet
355: */
356: public static String getNextMIDletToRun() {
357: return nextMidletToRun;
358: }
359:
360: /**
361: * Queues the last suite to run when there is not a next Suite
362: * to run. This value will be persistent until it is used.
363: * Not used in MVM mode.
364: *
365: * @param id ID of an installed suite
366: * @param midlet class name of MIDlet to invoke
367: *
368: * @exception SecurityException if the caller does not have permission
369: * to manage midlets
370: */
371: public static void setLastSuiteToRun(int id, String midlet,
372: String arg0, String arg1) {
373:
374: MIDletSuite midletSuite = MIDletStateHandler
375: .getMidletStateHandler().getMIDletSuite();
376:
377: // if a MIDlet suite is not scheduled, assume the JAM is calling.
378: if (midletSuite != null) {
379: midletSuite.checkIfPermissionAllowed(Permissions.AMS);
380: }
381:
382: lastMidletSuiteToRun = id;
383: lastMidletToRun = midlet;
384: arg0ForLastMidlet = arg0;
385: arg1ForLastMidlet = arg1;
386: }
387:
388: /**
389: * Get the Isolate ID of the AMS Isolate.
390: *
391: * @return Isolate ID of AMS Isolate
392: */
393: public static native int getAmsIsolateId();
394:
395: /**
396: * Get the current Isolate ID.
397: *
398: * @return ID of this Isolate.
399: */
400: public static native int getIsolateId();
401:
402: /**
403: * Check whether current Isolate is an AMS Isolate
404: *
405: * @return true if the current Isolate is an AMS Isolate,
406: * false otherwise.
407: */
408: public static native boolean isAmsIsolate();
409:
410: /**
411: * Register the Isolate ID of the AMS Isolate by making a native
412: * method call that will call JVM_CurrentIsolateId and set
413: * it in the proper native variable.
414: */
415: static native void registerAmsIsolateId();
416:
417: /**
418: * Send hint to VM about begin of a MIDlet startup phase within specified
419: * isolate to allow the VM to fine tune its internal parameters to achieve
420: * optimal perfomance
421: *
422: * @param midletIsolateId ID of the started MIDlet isolate
423: */
424: static native void vmBeginStartUp(int midletIsolateId);
425:
426: /**
427: * Send hint to VM about end of a MIDlet startup phase within specified
428: * isolate to allow the VM to restore its internal parameters changed on
429: * startup time for better performance
430: *
431: * @param midletIsolateId ID of the started MIDlet isolate
432: */
433: static native void vmEndStartUp(int midletIsolateId);
434:
435: /**
436: * Secure method to send VM hint about begin of a MIDlet startup phase
437: * within specified isolate
438: *
439: * @param token security token with the AMS permission allowed
440: * @param midletIsolateId ID of the started MIDlet isolate
441: */
442: static public void vmBeginStartUp(SecurityToken token,
443: int midletIsolateId) {
444: token.checkIfPermissionAllowed(Permissions.AMS);
445: vmBeginStartUp(midletIsolateId);
446: }
447:
448: /**
449: * Secure method to send VM hint about end of a MIDlet startup phase
450: * within specified isolate
451: *
452: * @param token security token with the AMS permission allowed
453: * @param midletIsolateId ID of the started MIDlet isolate
454: */
455: static public void vmEndStartUp(SecurityToken token,
456: int midletIsolateId) {
457: token.checkIfPermissionAllowed(Permissions.AMS);
458: vmEndStartUp(midletIsolateId);
459: }
460:
461: /**
462: * The method is designed to init AMS task resources. The resources
463: * can be shared between all working isolates, so it is important to
464: * init them before other isolate tasks will require the resources.
465: *
466: * The tasks other than AMS shouldn't call this method, it's guarded
467: * by run-time exception.
468: *
469: * IMPL_NOTE: The method is temporarily loacated here, since we need
470: * to introduce new abstraction for AMS task logic and separate it
471: * from the MIDlet suite loading and execution logic. Now the method
472: * is needed to MIDletSuiteLoader & NativeAppManagerPeer classes
473: * which represent an AMS task for Java AMS and Native AMS cases
474: * correspondingly.
475: */
476: static void initAmsResources() {
477: // Check whether caller task is an AMS task
478: if (!isAmsIsolate()) {
479: throw new RuntimeException(
480: "Resources initialization should be done from the AMS task");
481: }
482:
483: // The static initializer of the Display class will forward on
484: // the Chameleon skin resources loading if Chameleon is being used.
485: // It is important to load Chameleon resources from the AMS isolate
486: // before other isolates will need them.
487: try {
488: Class.forName("javax.microedition.lcdui.Display");
489: } catch (Throwable ex) {
490: throw new RuntimeException(
491: "Display initialization has failed");
492: }
493: }
494: }
|