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.events.EventTypes;
030: import com.sun.midp.events.NativeEvent;
031: import com.sun.midp.events.EventQueue;
032:
033: /**
034: * This class provides methods to send events of types
035: * handled by MIDletControllerEventConsumer I/F implementors.
036: * This class completely hide event construction & sending in its methods.
037: *
038: * This class is intended to be used by MIDletStateHandler & MIDletPeer
039: * classes in Allication Isolate.
040: * So in some of its sendXXXEvent()methods we can change int IDs to
041: * MIDletPeer references.
042: *
043: * Generic comments for all XXXEventProducers:
044: *
045: * For each supported event type there is a separate sendXXXEvent() method,
046: * that gets all needed parameters to construct an event of an approprate class.
047: * The method also performs event sending itself.
048: *
049: * If a given event type merges a set of logically different subtypes,
050: * this class shall provide separate methods for these subtypes.
051: *
052: * It is assumed that only one object instance of this class
053: * is initialized with the system event that is created at (isolate) startup.
054: *
055: * This class only operates on the event queue given to it during
056: * construction, the class does not obtain any restricted object itself,
057: * so it does not need protection.
058: *
059: * All MIDP stack subsystems that need to send events of supported types,
060: * must get a reference to an already created istance of this class.
061: * Typically, this instance should be passed as a constructor parameter.
062: *
063: * Class is NOT final to allow debug/profile/test/automation subsystems
064: * to change, substitute, complement default "event sending" functionality :
065: * Ex.
066: * class LogXXXEventProducer
067: * extends XXXEventProducer {
068: * ...
069: * void sendXXXEvent(parameters) {
070: * LOG("Event of type XXX is about to be sent ...")
071: * super.sendXXXEvent(parameters);
072: * LOG("Event of type XXX has been sent successfully !")
073: * }
074: * ...
075: * }
076: */
077: public class MIDletControllerEventProducer {
078:
079: /** Cached reference to the MIDP event queue. */
080: protected EventQueue eventQueue;
081: /** Cached reference to AMS isolate ID. */
082: protected int amsIsolateId;
083: /** Cached reference to current isolate ID. */
084: protected int currentIsolateId;
085:
086: /** Preallocate start error event to work in case of out of memory */
087: final NativeEvent startErrorEvent;
088: /** Preallocate MIDlet created event to work in case of out of memory */
089: final NativeEvent midletCreatedEvent;
090: /** Preallocate MIDlet active event to work in case of out of memory */
091: final NativeEvent midletActiveEvent;
092: /** Preallocate MIDlet paused event to work in case of out of memory */
093: final NativeEvent midletPausedEvent;
094: /** Preallocate MIDlet destroyed event to work in case of out of memory */
095: final NativeEvent midletDestroyedEvent;
096: /**
097: * Preallocate MIDlet resources paused event to work in case of out
098: * of memory
099: */
100: final NativeEvent midletRsPausedEvent;
101:
102: /**
103: * Construct a new MIDletControllerEventProducer.
104: *
105: * @param theEventQueue An event queue where new events will be posted.
106: * @param theAmsIsolateId AMS Isolate Id
107: * @param theCurrentIsolateId Current Isolate Id
108: */
109: public MIDletControllerEventProducer(EventQueue theEventQueue,
110: int theAmsIsolateId, int theCurrentIsolateId) {
111:
112: eventQueue = theEventQueue;
113: amsIsolateId = theAmsIsolateId;
114: currentIsolateId = theCurrentIsolateId;
115:
116: /* Cache all of the notification events. */
117: startErrorEvent = new NativeEvent(
118: EventTypes.MIDLET_START_ERROR_EVENT);
119: midletCreatedEvent = new NativeEvent(
120: EventTypes.MIDLET_CREATED_NOTIFICATION);
121: midletActiveEvent = new NativeEvent(
122: EventTypes.MIDLET_ACTIVE_NOTIFICATION);
123: midletPausedEvent = new NativeEvent(
124: EventTypes.MIDLET_PAUSED_NOTIFICATION);
125: midletDestroyedEvent = new NativeEvent(
126: EventTypes.MIDLET_DESTROYED_NOTIFICATION);
127: midletRsPausedEvent = new NativeEvent(
128: EventTypes.MIDLET_RS_PAUSED_NOTIFICATION);
129: }
130:
131: /*
132: * MIDlet Startup Events:
133: *
134: * MIDLET_START_ERROR
135: * MIDLET_CREATED_NOTIFICATION
136: */
137: /**
138: * Notifies AMS that MIDlet creation failed
139: * NEW: earlier it has been explicitely generated by
140: * void static AppIsolateMIDletSuiteLoader.main(...)
141: *
142: * @param midletExternalAppId ID of given by an external application
143: * manager
144: * @param midletSuiteId ID of the MIDlet suite
145: * @param midletClassName Class name of the MIDlet
146: * @param errorCode start error code
147: */
148: public void sendMIDletStartErrorEvent(int midletSuiteId,
149: String midletClassName, int midletExternalAppId,
150: int errorCode, String errorDetails) {
151:
152: synchronized (startErrorEvent) {
153: // use pre-created event to work in case of handling out of memory
154: startErrorEvent.intParam1 = midletSuiteId;
155: startErrorEvent.intParam2 = midletExternalAppId;
156: startErrorEvent.intParam3 = errorCode;
157:
158: startErrorEvent.stringParam1 = midletClassName;
159: startErrorEvent.stringParam2 = errorDetails;
160:
161: eventQueue.sendNativeEventToIsolate(startErrorEvent,
162: amsIsolateId);
163: }
164: }
165:
166: /**
167: * Called to send a MIDlet created notification to the AMS isolate.
168: *
169: * @param midletSuiteId ID of the MIDlet suite
170: * @param midletClassName Class name of the MIDlet
171: * @param midletExternalAppId ID of given by an external application
172: * manager
173: * @param midletDisplayName name to show the user
174: */
175: public void sendMIDletCreateNotifyEvent(int midletSuiteId,
176: String midletClassName, int midletExternalAppId,
177: String midletDisplayName) {
178:
179: synchronized (midletCreatedEvent) {
180: midletCreatedEvent.intParam1 = midletSuiteId;
181: midletCreatedEvent.intParam2 = currentIsolateId;
182: midletCreatedEvent.intParam3 = midletExternalAppId;
183:
184: midletCreatedEvent.stringParam1 = midletClassName;
185: midletCreatedEvent.stringParam2 = midletDisplayName;
186:
187: eventQueue.sendNativeEventToIsolate(midletCreatedEvent,
188: amsIsolateId);
189: }
190: }
191:
192: /*
193: * MIDlet State Management (Lifecycle) Events:
194: *
195: * MIDLET_ACTIVE_NOTIFICATION
196: * MIDLET_PAUSE_NOTIFICATION
197: * MIDLET_DESTROY_NOTIFICATION
198: *
199: * MIDLET_DESTROY_REQUEST
200: *
201: * ACTIVATE_ALL - produced by native code
202: * PAUSE_ALL -produced by native code
203: * SHUTDOWN/DESTROY_ALL - produced by native code
204: *
205: * FATAL_ERROR_NOTIFICATION - produced by native code
206: *
207: */
208: /**
209: * Called to send a MIDlet active notification to the AMS isolate.
210: *
211: * @param midletSuiteId ID of the MIDlet suite
212: * @param midletClassName Class name of the MIDlet
213: */
214: public void sendMIDletActiveNotifyEvent(int midletSuiteId,
215: String midletClassName) {
216: sendEvent(midletActiveEvent, midletSuiteId, midletClassName);
217: }
218:
219: /**
220: * Called to send a MIDlet paused notification to the AMS isolate.
221: *
222: * @param midletSuiteId ID of the MIDlet suite
223: * @param midletClassName Class name of the MIDlet
224: */
225: public void sendMIDletPauseNotifyEvent(int midletSuiteId,
226: String midletClassName) {
227: sendEvent(midletPausedEvent, midletSuiteId, midletClassName);
228: }
229:
230: /**
231: * Called to send a MIDlet destroyed notification to the AMS isolate.
232: *
233: * @param midletSuiteId ID of the MIDlet suite
234: * @param midletClassName Class name of the MIDlet
235: */
236: public void sendMIDletDestroyNotifyEvent(int midletSuiteId,
237: String midletClassName) {
238: sendEvent(midletDestroyedEvent, midletSuiteId, midletClassName);
239: }
240:
241: /**
242: * Called to send a MIDlet resume request to the AMS isolate.
243: *
244: * @param midletSuiteId ID of the MIDlet suite
245: * @param midletClassName Class name of the MIDlet
246: */
247: public void sendMIDletResumeRequest(int midletSuiteId,
248: String midletClassName) {
249: sendEvent(new NativeEvent(EventTypes.MIDLET_RESUME_REQUEST),
250: midletSuiteId, midletClassName);
251: }
252:
253: /**
254: * Sends notification for MIDlet resources pause to the AMS isolate.
255: *
256: * @param midletSuiteId ID of the MIDlet suite
257: * @param midletClassName Class name of the MIDlet
258: */
259: public void sendMIDletRsPauseNotifyEvent(int midletSuiteId,
260: String midletClassName) {
261: sendEvent(midletRsPausedEvent, midletSuiteId, midletClassName);
262: }
263:
264: /**
265: * Called by the display to request the central AMS to destroy the owning
266: * MIDlet.
267: *
268: * @param midletDisplayId ID of the sending Display
269: */
270: public void sendMIDletDestroyRequestEvent(int midletDisplayId) {
271: sendEvent(new NativeEvent(
272: EventTypes.MIDLET_DESTROY_REQUEST_EVENT),
273: midletDisplayId);
274: }
275:
276: /*
277: * Foreground MIDlet Management Events:
278: *
279: * SELECT_FOREGROUND - produced by native code
280: * FOREGROUND_TRANSFER
281: * SET_FOREGROUND_BY_NAME_REQUEST
282: *
283: */
284: /**
285: * Called to send a foreground MIDlet transfer event to the AMS isolate.
286: * Former: NEW method, originally sent from CHAPI
287: *
288: * @param originMIDletSuiteId ID of MIDlet from which
289: * to take forefround ownership away,
290: * @param originMIDletClassName Name of MIDlet from which
291: * to take forefround ownership away
292: * @param targetMIDletSuiteId ID of MIDlet
293: * to give forefround ownership to,
294: * @param targetMIDletClassName Name of MIDlet
295: * to give forefround ownership to
296: */
297: public void sendMIDletForegroundTransferEvent(
298: int originMIDletSuiteId, String originMIDletClassName,
299: int targetMIDletSuiteId, String targetMIDletClassName) {
300: NativeEvent event = new NativeEvent(
301: EventTypes.FOREGROUND_TRANSFER_EVENT);
302:
303: event.intParam1 = originMIDletSuiteId;
304: event.intParam2 = targetMIDletSuiteId;
305:
306: event.stringParam1 = originMIDletClassName;
307: event.stringParam2 = targetMIDletClassName;
308:
309: eventQueue.sendNativeEventToIsolate(event, amsIsolateId);
310: }
311:
312: /**
313: * Called to send a request to AMS isolate for a MIDlet be in
314: * the foreground.
315: *
316: * @param suiteId MIDlet's suite ID
317: * @param className MIDlet's class name
318: */
319: public void sendSetForegroundByNameRequestEvent(int suiteId,
320: String className) {
321:
322: NativeEvent event = new NativeEvent(
323: EventTypes.SET_FOREGROUND_BY_NAME_REQUEST);
324:
325: event.intParam1 = suiteId;
326: event.stringParam1 = className;
327:
328: eventQueue.sendNativeEventToIsolate(event, amsIsolateId);
329: }
330:
331: /**
332: * Called to send a Display created notification to the AMS isolate.
333: *
334: * @param midletDisplayId ID of the sending Display
335: * @param midletClassName Class name of the MIDlet that owns the display
336: */
337: public void sendDisplayCreateNotifyEvent(int midletDisplayId,
338: String midletClassName) {
339: NativeEvent event = new NativeEvent(
340: EventTypes.DISPLAY_CREATED_NOTIFICATION);
341:
342: event.intParam1 = currentIsolateId;
343: event.intParam2 = midletDisplayId;
344:
345: event.stringParam1 = midletClassName;
346:
347: eventQueue.sendNativeEventToIsolate(event, amsIsolateId);
348: }
349:
350: /*
351: * Foreground Display Management Events:
352: *
353: * FOREGROUND_REQUEST
354: * BACKGROUND_REQUEST
355: *
356: */
357: /**
358: * Called to send a foreground request event to the AMS isolate.
359: *
360: * @param midletDisplayId ID of the sending Display
361: * @param isAlert true if the current displayable is an Alert
362: */
363: public void sendDisplayForegroundRequestEvent(int midletDisplayId,
364: boolean isAlert) {
365: NativeEvent event = new NativeEvent(
366: EventTypes.FOREGROUND_REQUEST_EVENT);
367:
368: if (isAlert) {
369: event.intParam2 = 1;
370: } else {
371: event.intParam2 = 0;
372: }
373:
374: sendEvent(event, midletDisplayId);
375: }
376:
377: /**
378: * Called to send a background request event to the AMS isolate.
379: *
380: * @param midletDisplayId ID of the sending Display
381: */
382: public void sendDisplayBackgroundRequestEvent(int midletDisplayId) {
383: sendEvent(new NativeEvent(EventTypes.BACKGROUND_REQUEST_EVENT),
384: midletDisplayId);
385: }
386:
387: /*
388: * Display Preemption Management Events:
389: *
390: * PREEMPT
391: *
392: */
393: /**
394: * Called to start preempting and end preempting.
395: * Probably: will need more parameters, ex. MIDlet ID
396: *
397: * @param midletDisplayId ID of the sending Display
398: */
399: public void sendDisplayPreemptStartEvent(int midletDisplayId) {
400: NativeEvent event = new NativeEvent(EventTypes.PREEMPT_EVENT);
401:
402: event.intParam2 = -1; /* start = true */
403:
404: sendEvent(event, midletDisplayId);
405: }
406:
407: /**
408: * Called to start preempting and end preempting.
409: * Probably: will need more parameters, ex. MIDlet ID
410: *
411: * @param midletDisplayId ID of the sending Display
412: */
413: public void sendDisplayPreemptStopEvent(int midletDisplayId) {
414: NativeEvent event = new NativeEvent(EventTypes.PREEMPT_EVENT);
415:
416: event.intParam2 = 0; /* start = false */
417:
418: sendEvent(event, midletDisplayId);
419: }
420:
421: /**
422: * Sends standard MIDlet controller event setting two integer parameters
423: * for display ID and isolate ID. It is synchronized by the event to be
424: * sent to avoid inconsistent parameters setting.
425: *
426: * @param event event to be sent
427: * @param midletDisplayId ID of the sending Display
428: */
429: private void sendEvent(NativeEvent event, int midletDisplayId) {
430: synchronized (event) {
431: event.intParam1 = currentIsolateId;
432: event.intParam4 = midletDisplayId;
433: eventQueue.sendNativeEventToIsolate(event, amsIsolateId);
434: }
435: }
436:
437: /**
438: * Sends standard MIDlet controller event setting two parameters
439: * for suite ID and class name. It is synchronized by the event to be
440: * sent to avoid inconsistent parameters setting.
441: *
442: * @param event event to be sent
443: * @param midletSuiteId ID of the MIDlet suite
444: * @param midletClassName Class name of the MIDlet
445: */
446: private void sendEvent(NativeEvent event, int midletSuiteId,
447: String midletClassName) {
448: synchronized (event) {
449: event.intParam1 = midletSuiteId;
450: event.stringParam1 = midletClassName;
451: eventQueue.sendNativeEventToIsolate(event, amsIsolateId);
452: }
453: }
454: }
|