/** * Process an Execute event to start a new MIDlet. If the MIDlet is already in the ProxyList it * will <strong>not</strong> start it again. If the MIDlet/Isolate has decided to exit but has not * yet sent the remove event the execute will be unreliable. * * @param genericEvent event to process */ public void process(Event genericEvent) { // Verify that the requested MIDlet is not already running // (is not in the MIDletProxyList) if (MIDletProxyList.getMIDletProxyList().isMidletInList(id, midlet)) { if (Logging.REPORT_LEVEL <= Logging.WARNING) { Logging.report( Logging.WARNING, LogChannels.LC_CORE, "MIDlet already running; execute ignored"); } return; } try { // The execute MIDlet method may block NativeEvent event = (NativeEvent) genericEvent; ExecuteMIDletEventListener runnable = new ExecuteMIDletEventListener( event.intParam1, event.intParam2, event.stringParam1, event.stringParam2, event.stringParam3, event.stringParam4, event.stringParam5); (new Thread(runnable)).start(); } catch (Throwable t) { Logging.trace(t, "Error creating a new Execute thread"); } }
/** * Clear the fields of the saved connection and release any system resources. Any open input and * output streams are closed as well as the connection itself. */ public void close() { try { if (m_data_output_stream != null) { m_data_output_stream.close(); m_data_output_stream = null; } if (m_data_input_stream != null) { m_data_input_stream.close(); m_data_input_stream = null; } if (m_stream != null) { m_stream.close(); m_stream = null; } } catch (IOException ioe) { /* * No special processing for errors, since the * the cached connection is no longer in use, and * the server may already have shutdown its end * of the connection. */ if (Logging.REPORT_LEVEL <= Logging.WARNING) { Logging.report(Logging.WARNING, LogChannels.LC_PROTOCOL, "IOException while close"); } } }
/** * Handles exceptions happened during MIDlet suite execution. * * @param t exception instance */ public void handleException(Throwable t) { t.printStackTrace(); int errorCode = getErrorCode(t); if (Logging.TRACE_ENABLED) { Logging.trace(t, "Exception caught in CdcMIDletSuiteLoader"); } reportError(errorCode, t.getMessage()); }
/** Get the settings the Manager saved for the user. */ private void restoreSettings() { ByteArrayInputStream bas; DataInputStream dis; byte[] data; RecordStore settings = null; try { settings = RecordStore.openRecordStore(GraphicalInstaller.SETTINGS_STORE, false); data = settings.getRecord(1); if (data != null) { bas = new ByteArrayInputStream(data); dis = new DataInputStream(bas); defaultInstallListUrl = dis.readUTF(); } } catch (RecordStoreException e) { if (Logging.REPORT_LEVEL <= Logging.WARNING) { Logging.report( Logging.WARNING, LogChannels.LC_AMS, "restoreSettings threw a RecordStoreException"); } } catch (IOException e) { if (Logging.REPORT_LEVEL <= Logging.WARNING) { Logging.report(Logging.WARNING, LogChannels.LC_AMS, "restoreSettings threw an IOException"); } } finally { if (settings != null) { try { settings.closeRecordStore(); } catch (RecordStoreException e) { if (Logging.REPORT_LEVEL <= Logging.WARNING) { Logging.report( Logging.WARNING, LogChannels.LC_AMS, "closeRecordStore threw a RecordStoreException"); } } } } }
/** * Updates CommandState status and displays proper exception message to user * * @param errorCode generic error code * @param details text with error details */ protected void reportError(int errorCode, String details) { String errorMsg = getErrorMessage(errorCode); if (details != null) { errorMsg += "\n\n" + details; } displayException(errorMsg); // Error message is always obtained for logging if (Logging.REPORT_LEVEL <= Logging.ERROR) { Logging.report(Logging.ERROR, LogChannels.LC_CORE, errorMsg); } }
/** Processes an execute MIDlet event outside of the event thread. */ public void run() { try { MIDletSuiteUtils.executeWithArgs( classSecurityToken, externalAppId, id, midlet, displayName, arg0, arg1, arg2); } catch (Throwable t) { if (Logging.TRACE_ENABLED) { Logging.trace(t, "Exception calling MIDletSuiteLoader.execute"); } MIDletSuiteUtils.displayException( displayEventHandler, Resource.getString(ResourceConstants.AMS_MIDLETSUITELDR_CANT_EXE_NEXT_MIDLET) + "\n\n" + t.getMessage()); } }
/** * Creates MIDlet suite instance by suite ID * * @return MIDlet suite to load * @throws Exception in the case MIDlet suite can not be created because of a security reasons or * some problems related to suite storage */ protected MIDletSuite createMIDletSuite() throws Exception { MIDletSuiteStorage storage; MIDletSuite suite = null; storage = MIDletSuiteStorage.getMIDletSuiteStorage(internalSecurityToken); if (suiteId == MIDletSuite.INTERNAL_SUITE_ID) { // assume a class name of a MIDlet in the classpath suite = InternalMIDletSuiteImpl.create(storage, midletDisplayName, suiteId); } else { suite = storage.getMIDletSuite(suiteId, false); Logging.initLogSettings(suiteId); } return suite; }
/** Set the next capital mode for this input method */ protected void nextCapsMode() { if (Logging.REPORT_LEVEL <= Logging.INFORMATION) { Logging.report(Logging.INFORMATION, LogChannels.LC_HIGHUI, "[A.nextCapsMode]"); } capsModePointer++; if (capsModePointer == CAPS_MODES.length) { capsModePointer = 0; } if (CAPS_MODES[capsModePointer] == CAPS_OFF) { keyMap = lowerKeyMap; } else { keyMap = upperKeyMap; } mediator.subInputModeChanged(); }
/** * Run the refresh thread. * * @see java.lang.Runnable#run() */ public void run() { Request clonedRequest = (Request) request.clone(); // setRequestHeaders(clonedRequest); request = null; try { updateAndSendRequest(clonedRequest); } catch (Exception ex) { if (Logging.REPORT_LEVEL <= Logging.WARNING) { Logging.report( Logging.WARNING, LogChannels.LC_JSR180, "RefreshTask.run(): can't send a message: " + ex); } } }
/** * Splits a classpath into elements using the <code>path.separator</code> system property. * * @param elements the <code>Vector</code> to which to add the classpath elements * @param classpath the classpath to split */ private static void splitClassPath(final Vector elements, final String classpath) { String separator = System.getProperty("path.separator"); if (separator == null) { // defaults to ';' separator = ";"; Logging.report( Logging.ERROR, LogChannels.LC_AMS, "No \"path.separator\" defined! Using \"" + separator + "\"!"); } int index = classpath.indexOf(separator); int offset = 0; while (index != -1) { addClassPathElement(elements, classpath, offset, index); offset = index + separator.length(); index = classpath.indexOf(separator, offset); } addClassPathElement(elements, classpath, offset, classpath.length()); }
/** * Starts a MIDlet in a new Isolate. Check that the MIDlet is is not realy running and is not * already being started. If so, return immediately. * * @param midletSuiteStorage midletSuiteStorage for obtaining a classpath * @param externalAppId ID of MIDlet to invoke, given by an external application manager * @param id ID of an installed suite * @param midlet class name of MIDlet to invoke * @param displayName name to display to the user * @param arg0 if not null, this parameter will be available to the MIDlet as application property * arg-0 * @param arg1 if not null, this parameter will be available to the MIDlet as application property * arg-1 * @param arg2 if not null, this parameter will be available to the MIDlet as application property * arg-2 * @param memoryReserved the minimum amount of memory guaranteed to be available to the isolate at * any time; < 0 if not used * @param memoryTotal the total amount of memory that the isolate can reserve; < 0 if not used * @param priority priority to set for the new isolate; <= 0 if not used * @param profileName name of the profile to set for the new isolate; null if not used * @param debugMode debug option for the new isolate, one of: MIDP_NO_DEBUG, MIDP_DEBUG_SUSPEND, * MIDP_DEBUG_NO_SUSPEND * @return Isolate that the MIDlet suite was started in; <code>null</code> if the MIDlet is * already running */ private static Isolate startMidletCommon( MIDletSuiteStorage midletSuiteStorage, int externalAppId, int id, String midlet, String displayName, String arg0, String arg1, String arg2, int memoryReserved, int memoryTotal, int priority, String profileName, int debugMode) { Isolate isolate; String[] args = { Integer.toString(id), midlet, displayName, arg0, arg1, arg2, Integer.toString(externalAppId), String.valueOf(debugMode) }; String[] classpath = midletSuiteStorage.getMidletSuiteClassPath(id); if (classpath[0] == null) { if (id == MIDletSuite.INTERNAL_SUITE_ID) { /* * Avoid a null pointer exception, rommized midlets don't need * a classpath. */ classpath[0] = ""; } else { throw new IllegalArgumentException("Suite " + id + " not found"); } } Vector cpExtElements = new Vector(); String isolateClassPath = System.getProperty("classpathext"); if (isolateClassPath != null) { splitClassPath(cpExtElements, isolateClassPath); } /* * Include paths to dynamic components belonging to this suite * and to the "internal" suite (actually, to AMS) into class * path for the new Isolate. */ DynamicComponentStorage componentStorage = DynamicComponentStorage.getComponentStorage(); ComponentInfo[] ci = componentStorage.getListOfSuiteComponents(id); ComponentInfo[] ciAms = componentStorage.getListOfSuiteComponents(MIDletSuite.INTERNAL_SUITE_ID); int numOfComponents = 0; // calculate the number of the components to be added to the class path if (ci != null) { numOfComponents += ci.length; } if (ciAms != null) { numOfComponents += ciAms.length; } if (numOfComponents > 0) { Vector ciVector = new Vector(numOfComponents); // add the suite's own components if (ci != null) { for (int i = 0; i < ci.length; i++) { ciVector.addElement(ci[i]); } } // add the shared (belonging to AMS) components if (ciAms != null) { for (int i = 0; i < ciAms.length; i++) { ciVector.addElement(ciAms[i]); } } /* * IMPL_NOTE: currently is assumed that each component may have * not more than 1 entry in class path. * Later it will be possible to have 2: 1 for MONET. * + 1 is for System.getProperty("classpathext"). */ int n = 0; try { for (int i = 0; i < ciVector.size(); i++) { final ComponentInfo nextComponent = ((ComponentInfo) ciVector.elementAt(i)); final String[] componentPath = componentStorage.getComponentClassPath(nextComponent.getComponentId()); if (componentPath != null) { for (int j = 0; j < componentPath.length; j++) { cpExtElements.addElement(componentPath[j]); ++n; } } } } catch (Exception e) { /* * if something is wrong with a dynamic component, just * don't use the components, this error is not fatal */ cpExtElements.setSize(cpExtElements.size() - n); if (Logging.REPORT_LEVEL <= Logging.ERROR) { e.printStackTrace(); Logging.report( Logging.ERROR, LogChannels.LC_AMS, "Cannot use a dynamic component when starting '" + midlet + "' from the suite with id = " + id); } } } try { StartMIDletMonitor app = StartMIDletMonitor.okToStart(id, midlet); if (app == null) { // Isolate is already running; don't start it again return null; } final String[] classpathext = new String[cpExtElements.size()]; cpExtElements.copyInto(classpathext); isolate = new Isolate( "com.sun.midp.main.AppIsolateMIDletSuiteLoader", args, classpath, classpathext); app.setIsolate(isolate); } catch (Throwable t) { t.printStackTrace(); throw new RuntimeException("Can't create Isolate****"); } try { int reserved, limit; if (memoryReserved >= 0) { reserved = memoryReserved; } else { reserved = Constants.SUITE_MEMORY_RESERVED * 1024; } if (memoryTotal > 0) { limit = memoryTotal; } else { limit = Constants.SUITE_MEMORY_LIMIT; if (limit < 0) { limit = isolate.totalMemory(); } else { limit = limit * 1024; } int heapSize = getMidletHeapSize(id, midlet); if ((heapSize > 0) && (heapSize < limit)) { limit = heapSize; } } isolate.setMemoryQuota(reserved, limit); if (priority >= Isolate.MIN_PRIORITY) { isolate.setPriority(priority); } if (profileName != null) { IsolateUtil.setProfile(isolate, profileName); } isolate.setDebug(debugMode); isolate.setAPIAccess(true); isolate.start(); // Ability to launch midlet implies right to use Service API // for negotiations with isolate being run Link[] isolateLinks = SystemServiceLinkPortal.establishLinksFor(isolate, getTrustedToken()); LinkPortal.setLinks(isolate, isolateLinks); } catch (Throwable t) { int errorCode; String msg; if (Logging.REPORT_LEVEL <= Logging.WARNING) { t.printStackTrace(); } if (t instanceof IsolateStartupException) { /* * An error occured in the * initialization or configuration of the new isolate * before any application code is invoked, or if this * Isolate was already started or is terminated. */ errorCode = Constants.MIDLET_ISOLATE_CONSTRUCTOR_FAILED; msg = "Can't start Application."; } else if (t instanceof IsolateResourceError) { /* The system has exceeded the maximum Isolate count. */ errorCode = Constants.MIDLET_ISOLATE_RESOURCE_LIMIT; msg = "No more concurrent applications allowed."; } else if (t instanceof IllegalArgumentException) { /* Requested profile doesn't exist. */ errorCode = Constants.MIDLET_ISOLATE_CONSTRUCTOR_FAILED; msg = "Invalid profile name: " + profileName; } else if (t instanceof OutOfMemoryError) { /* The reserved memory cannot be allocated */ errorCode = Constants.MIDLET_OUT_OF_MEM_ERROR; msg = "Not enough memory to run the application."; } else { errorCode = Constants.MIDLET_ISOLATE_CONSTRUCTOR_FAILED; msg = t.toString(); } midletControllerEventProducer.sendMIDletStartErrorEvent( id, midlet, externalAppId, errorCode, msg); throw new RuntimeException(msg); } return isolate; }
/** * Get the list of suites for the user to install. The suites that are listed are the links on a * web page that end with .jad. */ public void run() { StreamConnection conn = null; InputStreamReader in = null; String errorMessage; long startTime; startTime = System.currentTimeMillis(); try { parent.displayProgressForm( Resource.getString(ResourceConstants.AMS_DISC_APP_GET_INSTALL_LIST), "", url, 0, Resource.getString(ResourceConstants.AMS_GRA_INTLR_CONN_GAUGE_LABEL)); conn = (StreamConnection) Connector.open(url, Connector.READ); in = new InputStreamReader(conn.openInputStream()); try { parent.updateProgressForm( "", 0, Resource.getString(ResourceConstants.AMS_DISC_APP_GAUGE_LABEL_DOWNLOAD)); parent.installList = SuiteDownloadInfo.getDownloadInfoFromPage(in); if (parent.installList.size() > 0) { parent.installListBox = new List( Resource.getString(ResourceConstants.AMS_DISC_APP_SELECT_INSTALL), Choice.IMPLICIT); // Add each suite for (int i = 0; i < parent.installList.size(); i++) { SuiteDownloadInfo suite = (SuiteDownloadInfo) installList.elementAt(i); parent.installListBox.append(suite.label, (Image) null); } parent.installListBox.addCommand(parent.backCmd); parent.installListBox.addCommand(parent.installCmd); parent.installListBox.setCommandListener(parent); /* * We need to prevent "flashing" on fast development * platforms. */ while (System.currentTimeMillis() - parent.lastDisplayChange < GraphicalInstaller.ALERT_TIMEOUT) ; parent.display.setCurrent(parent.installListBox); return; } errorMessage = Resource.getString(ResourceConstants.AMS_DISC_APP_CHECK_URL_MSG); } catch (IllegalArgumentException ex) { errorMessage = Resource.getString(ResourceConstants.AMS_DISC_APP_URL_FORMAT_MSG); } catch (Exception ex) { errorMessage = ex.getMessage(); } } catch (Exception ex) { errorMessage = Resource.getString(ResourceConstants.AMS_DISC_APP_CONN_FAILED_MSG); } finally { if (parent.progressForm != null) { // end the background thread of progress gauge. Gauge progressGauge = (Gauge) parent.progressForm.get(parent.progressGaugeIndex); progressGauge.setValue(Gauge.CONTINUOUS_IDLE); } try { conn.close(); in.close(); } catch (Exception e) { if (Logging.REPORT_LEVEL <= Logging.WARNING) { Logging.report(Logging.WARNING, LogChannels.LC_AMS, "close threw an Exception"); } } } Alert a = new Alert( Resource.getString(ResourceConstants.ERROR), errorMessage, null, AlertType.ERROR); a.setTimeout(Alert.FOREVER); parent.display.setCurrent(a, parent.urlTextBox); }
/** * Sets appropriate CSeq and Via headers in the given request preparing it for sending. * * @param clonedRequest the request to modify */ public synchronized void setRequestHeaders(Request clonedRequest) { // RFC 3261, section 10.2.4, Refreshing Bindings: // "A UA SHOULD use the same Call-ID for all registrations during a // single boot cycle". // // Call-Id header was added in SipClientConnectionImpl.send() // when the initial request was sent. This is the reason why // Call-Id header is not added here. // Update the CSeq header. RFC 3261, p. 58: // A UA MUST increment the CSeq value by one for each // REGISTER request with the same Call-ID. CSeqHeader cseq = clonedRequest.getCSeqHeader(); if (cseq != null) { cseq.setSequenceNumber(cseq.getSequenceNumber() + 1); } else { // log an error if (Logging.REPORT_LEVEL <= Logging.ERROR) { Logging.report( Logging.ERROR, LogChannels.LC_JSR180, "RefreshTask.run(): The request doesn't " + "contain CSeq header!"); } } // ViaHeader clonedRequest.removeHeader(ViaHeader.NAME); Vector viaHeaders = new Vector(); try { ViaHeader viaHeader = StackConnector.headerFactory.createViaHeader( sipConnectionNotifier.getLocalAddress(), sipConnectionNotifier.getLocalPort(), ((SipConnectionNotifierImpl) sipConnectionNotifier) .getSipProvider() .getListeningPoint() .getTransport(), null); viaHeaders.addElement(viaHeader); } catch (ParseException ex) { if (Logging.REPORT_LEVEL <= Logging.WARNING) { Logging.report( Logging.WARNING, LogChannels.LC_JSR180, "RefreshTask.run(): can't create Via header: " + ex); } } catch (IOException ioe) { if (Logging.REPORT_LEVEL <= Logging.WARNING) { Logging.report( Logging.WARNING, LogChannels.LC_JSR180, "RefreshTask.run(): can't create Via header: " + ioe); } } try { clonedRequest.setVia(viaHeaders); } catch (SipException ex) { if (Logging.REPORT_LEVEL <= Logging.WARNING) { Logging.report( Logging.WARNING, LogChannels.LC_JSR180, "RefreshTask.run(): can't set Via header: " + ex); } } }