javaruntimes/midp/runtime/javasrc/com/nokia/mj/impl/rt/midp/MidletLifeCycle.java
branchRCL_3
changeset 25 9ac0a0a7da70
parent 24 0fd27995241b
child 34 71c436fe3ce0
equal deleted inserted replaced
24:0fd27995241b 25:9ac0a0a7da70
     1 /*
     1 /*
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
     2 * Copyright (c) 2009 - 2010 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     3 * All rights reserved.
     4 * This component and the accompanying materials are made available
     4 * This component and the accompanying materials are made available
     5 * under the terms of "Eclipse Public License v1.0"
     5 * under the terms of "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     6 * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
    19 package com.nokia.mj.impl.rt.midp;
    19 package com.nokia.mj.impl.rt.midp;
    20 
    20 
    21 import java.io.InputStream;
    21 import java.io.InputStream;
    22 import java.io.InputStreamReader;
    22 import java.io.InputStreamReader;
    23 import java.io.IOException;
    23 import java.io.IOException;
       
    24 import java.util.Hashtable;
    24 import java.util.Timer;
    25 import java.util.Timer;
    25 import java.util.TimerTask;
    26 import java.util.TimerTask;
    26 
    27 
    27 import com.nokia.mj.impl.rt.utils.ExtensionUtil;
    28 import com.nokia.mj.impl.rt.utils.ExtensionUtil;
    28 
    29 
    45 
    46 
    46 import com.nokia.mj.impl.utils.LineReader;
    47 import com.nokia.mj.impl.utils.LineReader;
    47 import com.nokia.mj.impl.utils.TaskQueue;
    48 import com.nokia.mj.impl.utils.TaskQueue;
    48 import com.nokia.mj.impl.utils.Uid;
    49 import com.nokia.mj.impl.utils.Uid;
    49 import com.nokia.mj.impl.utils.StartUpTrace;
    50 import com.nokia.mj.impl.utils.StartUpTrace;
       
    51 
    50 
    52 
    51 /**
    53 /**
    52  * A core of the MIDP life cycle. This class controls the life time of the
    54  * A core of the MIDP life cycle. This class controls the life time of the
    53  * MIDlet.
    55  * MIDlet.
    54  * <p>
    56  * <p>
   173      * the url contains MIDlet argument 'PromptAppStartup'
   175      * the url contains MIDlet argument 'PromptAppStartup'
   174      */
   176      */
   175     private        boolean               mAutoinvocationFromUrl = false;
   177     private        boolean               mAutoinvocationFromUrl = false;
   176 
   178 
   177     /**
   179     /**
       
   180      * PropertyKeys that are not listed in the values of Jad / Manifest
       
   181      * attribute Nokia-MIDlet-Launch-Params
       
   182      */
       
   183     private        Hashtable             mAcceptedUserProperties;
       
   184 
       
   185     /**
   178      * Flag for identifying whether the MIDlet is a standalone MIDlet.
   186      * Flag for identifying whether the MIDlet is a standalone MIDlet.
   179      */
   187      */
   180     private        boolean               mStandAlone = false;
   188     private        boolean               mStandAlone = false;
   181 
   189 
   182     /*** ----------------------------- PRIVATE ---------------------------- */
   190     /*** ----------------------------- PRIVATE ---------------------------- */
   368         JvmInternal.setSystemProperty("com.nokia.mid.cmdline.instance",
   376         JvmInternal.setSystemProperty("com.nokia.mid.cmdline.instance",
   369                                       Integer.toString(mRelaunchCount + 1));
   377                                       Integer.toString(mRelaunchCount + 1));
   370         if (Log.mOn)
   378         if (Log.mOn)
   371             Log.logI("MIDlet launch count is : " + Integer.toString(mRelaunchCount + 1));
   379             Log.logI("MIDlet launch count is : " + Integer.toString(mRelaunchCount + 1));
   372 
   380 
   373         // Update possible MIDlet arguments
   381         if (applicationArgs != null)
   374         setMidletArguments(applicationArgs);
   382         {
       
   383             JvmInternal.setSystemProperty("com.nokia.mid.cmdline", applicationArgs);
       
   384         }
   375 
   385 
   376         if (mState == PRE_INIT_DONE)
   386         if (mState == PRE_INIT_DONE)
   377         {
   387         {
   378             // We were waiting in prewarmed state the launch request
   388             // We were waiting in prewarmed state the launch request
   379             // and now got it.
   389             // and now got it.
   382             mTaskQueue.addTask(new LifeCycleTask(LifeCycleTask.START_REQUEST,
   392             mTaskQueue.addTask(new LifeCycleTask(LifeCycleTask.START_REQUEST,
   383                                                  LifeCycleTask.PRE_WARM_START));
   393                                                  LifeCycleTask.PRE_WARM_START));
   384         }
   394         }
   385         else
   395         else
   386         {
   396         {
       
   397             // Update possible MIDlet arguments
       
   398             setMidletArguments();
   387             // Bring the MIDlet to foreground
   399             // Bring the MIDlet to foreground
   388             CoreUi.foregroundRequest();
   400             CoreUi.foregroundRequest();
   389         }
   401         }
   390     }
   402     }
   391 
   403 
   792         if ((encodedMidletArgs != null) && (encodedMidletArgs.length() > 0))
   804         if ((encodedMidletArgs != null) && (encodedMidletArgs.length() > 0))
   793         {
   805         {
   794             // Decode arguments
   806             // Decode arguments
   795             String midletArgs = decodeArgs(encodedMidletArgs);
   807             String midletArgs = decodeArgs(encodedMidletArgs);
   796 
   808 
   797             // Parse them
   809             // Resetting the system property after decoding.
   798             setMidletArguments(midletArgs);
   810             JvmInternal.setSystemProperty("com.nokia.mid.cmdline", midletArgs);
   799         }
   811         }
   800 
   812 
   801         // If the runtime is set to pre warmed state, then the
   813         // If the runtime is set to pre warmed state, then the
   802         // value of the prewarm flag contans the process id which
   814         // value of the prewarm flag contans the process id which
   803         // is needed by Captain for identification.
   815         // is needed by Captain for identification.
   847      * Decode string in a private format that was safe to pass to Java side
   859      * Decode string in a private format that was safe to pass to Java side
   848      * as a Java system property.
   860      * as a Java system property.
   849      * Native side function java::util::runtime::MidpRuntimeStarter::encodeArgs()
   861      * Native side function java::util::runtime::MidpRuntimeStarter::encodeArgs()
   850      * was used to encode the string
   862      * was used to encode the string
   851      *
   863      *
   852      * @param args original wstring
   864      * @param encodedArgs encoded arguments
   853      * @return encoded wstring
   865      * @return decoded argument string
   854      */
   866      */
   855     private String decodeArgs(String encodedArgs)
   867     private String decodeArgs(String encodedArgs)
   856     {
   868     {
   857         StringBuffer res = new StringBuffer();
   869         StringBuffer res = new StringBuffer();
   858         int idx = encodedArgs.indexOf('%');
   870         int  idx = 0;
   859         int cur = 0;
   871         int  len = encodedArgs.length();
   860 
   872         char t;
   861         while (idx != -1)
   873 
   862         {
   874         // Decoding is done in blocks of 4 or 2 characters.
   863             // Add all characters up to but not including the '%' char
   875         // Possible extra chars are ignored
   864             // to final result string
   876 
   865             if ((idx - cur) > 0)
   877         while (idx < len)
   866             {
   878         {
   867                 res.append(encodedArgs.substring(cur, idx));
   879             t = encodedArgs.charAt(idx);
   868             }
   880             if (t < 'a')
   869 
   881             {
   870             // Decode all special sequences 'X%' in same way.
   882                 if (idx + 4 >= len)
   871             // "X%" -> "X", so skip "%"
   883                     break;
   872             // Note that "%%" is decoded to "%"
   884                 // decode one 16-bit char
   873             cur = idx + 1;
   885                 char a = (char)(t - 'A');
   874             idx = encodedArgs.indexOf('%', cur + 1);
   886                 char b = (char)(encodedArgs.charAt(idx+1) - 'A');
   875         }
   887                 char c = (char)(encodedArgs.charAt(idx+2) - 'A');
   876 
   888                 char d = (char)(encodedArgs.charAt(idx+3) - 'A');
   877         // Add characters after last special character if any
   889                 char r = (char)(((a<<12)+(b<<8)+(c<<4)+d));
   878         res.append(encodedArgs.substring(cur, encodedArgs.length()));
   890                 res.append(r);
       
   891                 idx = idx + 4;
       
   892             }
       
   893             else
       
   894             {
       
   895                 if (idx + 2 >= len)
       
   896                     break;
       
   897                 // decode one 8-bit char
       
   898                 char a = (char)(t - 'a');
       
   899                 char b = (char)(encodedArgs.charAt(idx+1) - 'a');
       
   900                 char r = (char)((a<<4)+b);
       
   901                 res.append(r);
       
   902                 idx = idx + 2;
       
   903             }
       
   904         }
   879 
   905 
   880         return res.toString();
   906         return res.toString();
   881     }
   907     }
   882 
   908 
   883     /**
   909     /**
   929 
   955 
   930         // Set the MidletInfo class to contain correct data. The data is read
   956         // Set the MidletInfo class to contain correct data. The data is read
   931         // from storage.
   957         // from storage.
   932         setMidletInfo();
   958         setMidletInfo();
   933 
   959 
       
   960         // If system property com.nokia.mid.cmdline has value, it contains
       
   961         // the arguments for the current MIDlet.
       
   962         setMidletArguments();
       
   963     
   934         if (mPrewarmStart)
   964         if (mPrewarmStart)
   935         {
   965         {
   936             // Get the recorded heap size from previous run.
   966             // Get the recorded heap size from previous run.
   937             int targetHeapSize = MemoryLogger.getOldHeapSizeToExpand();
   967             int targetHeapSize = MemoryLogger.getOldHeapSizeToExpand();
   938 
   968 
  1114     }
  1144     }
  1115 
  1145 
  1116     /**
  1146     /**
  1117      * Parse the MIDlet arguments given as parameter and set them
  1147      * Parse the MIDlet arguments given as parameter and set them
  1118      * to system properties so that MIDlet can access them.
  1148      * to system properties so that MIDlet can access them.
  1119      *
  1149      */
  1120      * @param applicationArgs the MIDlet arguments, can be empty
  1150     private void setMidletArguments()
  1121      */
  1151     {
  1122     private void setMidletArguments(String applicationArgs)
  1152         String applicationArgs = System.getProperty("com.nokia.mid.cmdline");
  1123     {
  1153 
  1124         if (applicationArgs == null)
  1154         if (applicationArgs != null && applicationArgs.length() > 0)
  1125         {
       
  1126             applicationArgs = "";
       
  1127         }
       
  1128         JvmInternal.setSystemProperty("com.nokia.mid.cmdline", applicationArgs);
       
  1129 
       
  1130         if (applicationArgs.length() > 0)
       
  1131         {
  1155         {
  1132             if (Log.mOn)
  1156             if (Log.mOn)
  1133                 Log.logI("MIDlet arguments are : " + applicationArgs);
  1157                 Log.logI("MIDlet arguments are : " + applicationArgs);
  1134 
  1158 
  1135             // parse args and set individual system properties
  1159             // parse args and set individual system properties
  1140             StringBuffer argBuf = new StringBuffer();
  1164             StringBuffer argBuf = new StringBuffer();
  1141             String arg;
  1165             String arg;
  1142             String propertyKey;
  1166             String propertyKey;
  1143             String propertyValue;
  1167             String propertyValue;
  1144             mAutoinvocationFromUrl = false;
  1168             mAutoinvocationFromUrl = false;
       
  1169             if (mAcceptedUserProperties == null)
       
  1170             {
       
  1171                 // Doing intialization only once.
       
  1172                 String launchParams = 
       
  1173                   ApplicationInfoImpl.getMidletInfo().getAttribute("Nokia-MIDlet-Launch-Params");
       
  1174                 mAcceptedUserProperties = split(launchParams, ",");
       
  1175             }
  1145 
  1176 
  1146             do
  1177             do
  1147             {
  1178             {
  1148                 argBuf.setLength(0);
  1179                 argBuf.setLength(0);
  1149                 idx = applicationArgs.indexOf(";", cur);
  1180                 idx = applicationArgs.indexOf(";", cur);
  1153                     // Arguments string started with ';'
  1184                     // Arguments string started with ';'
  1154                     cur = idx + 1;
  1185                     cur = idx + 1;
  1155                     continue;
  1186                     continue;
  1156                 }
  1187                 }
  1157 
  1188 
  1158                 argBuf.append("com.nokia.mid.cmdline.param.");
       
  1159                 if (idx != -1)
  1189                 if (idx != -1)
  1160                 {
  1190                 {
  1161                     argBuf.append(applicationArgs.substring(cur, idx));
  1191                     argBuf.append(applicationArgs.substring(cur, idx));
  1162                 }
  1192                 }
  1163                 else
  1193                 else
  1181                     // The property has also a value.
  1211                     // The property has also a value.
  1182                     propertyKey = arg.substring(0, indEq);
  1212                     propertyKey = arg.substring(0, indEq);
  1183                     propertyValue = arg.substring(indEq + 1);
  1213                     propertyValue = arg.substring(indEq + 1);
  1184                 }
  1214                 }
  1185 
  1215 
  1186                 if (propertyKey.equals("com.nokia.mid.cmdline.param.PromptAppStartup"))
  1216                 if (propertyKey.equals("PromptAppStartup"))
  1187                 {
  1217                 {
  1188                     mAutoinvocationFromUrl = true;
  1218                     mAutoinvocationFromUrl = true;
  1189                     if (Log.mOn)
  1219                     if (Log.mOn)
  1190                         Log.logI("MIDlet had argument PromptAppStartup");
  1220                         Log.logI("MIDlet had argument PromptAppStartup");
  1191                 }
  1221                 }
  1192 
  1222 
  1193                 JvmInternal.setSystemProperty(propertyKey, propertyValue);
  1223                 if (mAcceptedUserProperties.get(propertyKey) != null)
       
  1224                 {
       
  1225                     JvmInternal.setUserProperty(propertyKey, propertyValue);
       
  1226                 }
  1194 
  1227 
  1195                 cur = idx + 1;
  1228                 cur = idx + 1;
  1196             }
  1229             }
  1197             while ((idx != -1) && (cur < applicationArgs.length()));
  1230             while ((idx != -1) && (cur < applicationArgs.length()));
  1198         }
  1231         }
       
  1232     }
       
  1233 
       
  1234     /**
       
  1235      * Split a string into Hashtable. This util method splits the given
       
  1236      * string separated by given separator into Hashtable so that tokens
       
  1237      * are keys and values are just empty Strings. Before adding the tokens
       
  1238      * into hashtable those are trimmed.
       
  1239      *
       
  1240      * @str String to split.
       
  1241      * @separator A separator that separates the tokens.
       
  1242      */
       
  1243     static Hashtable split(String str, String separator)
       
  1244     {
       
  1245         Hashtable ht = new Hashtable();
       
  1246         if (separator != null)
       
  1247         {
       
  1248             int separatorLen = separator.length();
       
  1249             if (str != null && separatorLen > 0)
       
  1250             {
       
  1251                 int index = str.indexOf(separator);
       
  1252                 while (index != -1)
       
  1253                 {
       
  1254                     String token = str.substring(0,index).trim();
       
  1255                     ht.put(token, "");
       
  1256                     str = str.substring(index + separatorLen);
       
  1257                     index = str.indexOf(separator);
       
  1258                 }
       
  1259             }
       
  1260         }
       
  1261         if (str != null)
       
  1262         {
       
  1263             str = str.trim();
       
  1264             if (str.length() > 0)
       
  1265             {
       
  1266                 // add token after last separator
       
  1267                 ht.put(str, "");
       
  1268             }
       
  1269         }
       
  1270         return ht;
  1199     }
  1271     }
  1200 
  1272 
  1201     /**
  1273     /**
  1202      * Class for extending the TimerTask. This is for the shut down timer.
  1274      * Class for extending the TimerTask. This is for the shut down timer.
  1203      */
  1275      */