19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.internal.os; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.ActivityManagerNative; 2035980b2cf51c06c1bdad66b7f8fb629d9c17052fEric Roweimport android.app.ActivityThread; 21b7f0367cec1c744aa66ef397b0244e25d507491cDan Egnorimport android.app.ApplicationErrorReport; 22b7f0367cec1c744aa66ef397b0244e25d507491cDan Egnorimport android.os.Build; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Debug; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Process; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemProperties; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 28c9421ba1f46d9f9aeee833e1fde2cc263b058411Dianne Hackbornimport android.util.Slog; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.logging.AndroidConfig; 308568db534118fc14cc28100306d51626464ff319Jesse Wilsonimport com.android.server.NetworkManagementSocketTagger; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport dalvik.system.VMRuntime; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.lang.reflect.Method; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.lang.reflect.Modifier; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.TimeZone; 358568db534118fc14cc28100306d51626464ff319Jesse Wilsonimport java.util.logging.LogManager; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.harmony.luni.internal.util.TimezoneGetter; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Main entry point for runtime initialization. Not for 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * public consumption. 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class RuntimeInit { 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final static String TAG = "AndroidRuntime"; 45ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown private final static boolean DEBUG = false; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** true if commonInit() has been called */ 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static boolean initialized; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5060d8762413e8daba5f73559786312a9ec5e3b827Dan Egnor private static IBinder mApplicationObject; 5160d8762413e8daba5f73559786312a9ec5e3b827Dan Egnor 5260d8762413e8daba5f73559786312a9ec5e3b827Dan Egnor private static volatile boolean mCrashing = false; 5360d8762413e8daba5f73559786312a9ec5e3b827Dan Egnor 5416f5f5cc9d4c480fac3dc7f176f3f1edfbd256f4Jeff Brown private static final native void nativeZygoteInit(); 5516f5f5cc9d4c480fac3dc7f176f3f1edfbd256f4Jeff Brown private static final native void nativeFinishInit(); 564280c4a93ea17f2e9d3f651e49d8c13dc3fb92aaJeff Brown private static final native void nativeSetExitWithoutCleanup(boolean exitWithoutCleanup); 5716f5f5cc9d4c480fac3dc7f176f3f1edfbd256f4Jeff Brown 5869eb6f57e34fb78050adcedcda8479cf2ad0c418Mark Salyzyn private static int Clog_e(String tag, String msg, Throwable tr) { 5969eb6f57e34fb78050adcedcda8479cf2ad0c418Mark Salyzyn return Log.println_native(Log.LOG_ID_CRASH, Log.ERROR, tag, 6069eb6f57e34fb78050adcedcda8479cf2ad0c418Mark Salyzyn msg + '\n' + Log.getStackTraceString(tr)); 6169eb6f57e34fb78050adcedcda8479cf2ad0c418Mark Salyzyn } 6269eb6f57e34fb78050adcedcda8479cf2ad0c418Mark Salyzyn 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Use this to log a message when a thread exits due to an uncaught 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * exception. The framework catches these for the main threads, so 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this should only matter for threads created by applications. 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static class UncaughtHandler implements Thread.UncaughtExceptionHandler { 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void uncaughtException(Thread t, Throwable e) { 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 7160d8762413e8daba5f73559786312a9ec5e3b827Dan Egnor // Don't re-enter -- avoid infinite loops if crash-reporting crashes. 7260d8762413e8daba5f73559786312a9ec5e3b827Dan Egnor if (mCrashing) return; 7360d8762413e8daba5f73559786312a9ec5e3b827Dan Egnor mCrashing = true; 7460d8762413e8daba5f73559786312a9ec5e3b827Dan Egnor 7560d8762413e8daba5f73559786312a9ec5e3b827Dan Egnor if (mApplicationObject == null) { 7669eb6f57e34fb78050adcedcda8479cf2ad0c418Mark Salyzyn Clog_e(TAG, "*** FATAL EXCEPTION IN SYSTEM PROCESS: " + t.getName(), e); 7760d8762413e8daba5f73559786312a9ec5e3b827Dan Egnor } else { 7835980b2cf51c06c1bdad66b7f8fb629d9c17052fEric Rowe StringBuilder message = new StringBuilder(); 7935980b2cf51c06c1bdad66b7f8fb629d9c17052fEric Rowe message.append("FATAL EXCEPTION: ").append(t.getName()).append("\n"); 8035980b2cf51c06c1bdad66b7f8fb629d9c17052fEric Rowe final String processName = ActivityThread.currentProcessName(); 8135980b2cf51c06c1bdad66b7f8fb629d9c17052fEric Rowe if (processName != null) { 8235980b2cf51c06c1bdad66b7f8fb629d9c17052fEric Rowe message.append("Process: ").append(processName).append(", "); 8335980b2cf51c06c1bdad66b7f8fb629d9c17052fEric Rowe } 8435980b2cf51c06c1bdad66b7f8fb629d9c17052fEric Rowe message.append("PID: ").append(Process.myPid()); 8569eb6f57e34fb78050adcedcda8479cf2ad0c418Mark Salyzyn Clog_e(TAG, message.toString(), e); 8660d8762413e8daba5f73559786312a9ec5e3b827Dan Egnor } 8760d8762413e8daba5f73559786312a9ec5e3b827Dan Egnor 8860d8762413e8daba5f73559786312a9ec5e3b827Dan Egnor // Bring up crash dialog, wait for it to be dismissed 8960d8762413e8daba5f73559786312a9ec5e3b827Dan Egnor ActivityManagerNative.getDefault().handleApplicationCrash( 9060d8762413e8daba5f73559786312a9ec5e3b827Dan Egnor mApplicationObject, new ApplicationErrorReport.CrashInfo(e)); 9160d8762413e8daba5f73559786312a9ec5e3b827Dan Egnor } catch (Throwable t2) { 9260d8762413e8daba5f73559786312a9ec5e3b827Dan Egnor try { 9369eb6f57e34fb78050adcedcda8479cf2ad0c418Mark Salyzyn Clog_e(TAG, "Error reporting crash", t2); 9460d8762413e8daba5f73559786312a9ec5e3b827Dan Egnor } catch (Throwable t3) { 9569eb6f57e34fb78050adcedcda8479cf2ad0c418Mark Salyzyn // Even Clog_e() fails! Oh well. 9660d8762413e8daba5f73559786312a9ec5e3b827Dan Egnor } 9760d8762413e8daba5f73559786312a9ec5e3b827Dan Egnor } finally { 9860d8762413e8daba5f73559786312a9ec5e3b827Dan Egnor // Try everything to make sure this process goes away. 9960d8762413e8daba5f73559786312a9ec5e3b827Dan Egnor Process.killProcess(Process.myPid()); 10060d8762413e8daba5f73559786312a9ec5e3b827Dan Egnor System.exit(10); 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final void commonInit() { 106ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown if (DEBUG) Slog.d(TAG, "Entered RuntimeInit!"); 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* set default handler; this applies to all threads in the VM */ 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler()); 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Install a TimezoneGetter subclass for ZoneInfo.db 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TimezoneGetter.setInstance(new TimezoneGetter() { 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String getId() { 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SystemProperties.get("persist.sys.timezone"); 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }); 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TimeZone.setDefault(null); 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets handler for java.util.logging to use Android log facilities. 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The odd "new instance-and-then-throw-away" is a mirror of how 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the "java.util.logging.config.class" system property works. We 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * can't use the system property here since the logger has almost 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * certainly already been initialized. 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LogManager.getLogManager().reset(); 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new AndroidConfig(); 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 133d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson * Sets the default HTTP User-Agent used by HttpURLConnection. 134d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson */ 135d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson String userAgent = getDefaultUserAgent(); 136d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson System.setProperty("http.agent", userAgent); 137d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson 138d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson /* 1398568db534118fc14cc28100306d51626464ff319Jesse Wilson * Wire socket tagging to traffic stats. 1408568db534118fc14cc28100306d51626464ff319Jesse Wilson */ 1418568db534118fc14cc28100306d51626464ff319Jesse Wilson NetworkManagementSocketTagger.install(); 1428568db534118fc14cc28100306d51626464ff319Jesse Wilson 1438568db534118fc14cc28100306d51626464ff319Jesse Wilson /* 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If we're running in an emulator launched with "-trace", put the 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * VM into emulator trace profiling mode so that the user can hit 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * F9/F10 at any time to capture traces. This has performance 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * consequences, so it's not something you want to do always. 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String trace = SystemProperties.get("ro.kernel.android.tracing"); 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (trace.equals("1")) { 151c9421ba1f46d9f9aeee833e1fde2cc263b058411Dianne Hackborn Slog.i(TAG, "NOTE: emulator trace profiling enabled"); 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Debug.enableEmulatorTraceOutput(); 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project initialized = true; 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 159d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson * Returns an HTTP user agent of the form 160d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson * "Dalvik/1.1.0 (Linux; U; Android Eclair Build/MASTER)". 161d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson */ 162d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson private static String getDefaultUserAgent() { 163d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson StringBuilder result = new StringBuilder(64); 164d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson result.append("Dalvik/"); 165d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson result.append(System.getProperty("java.vm.version")); // such as 1.1.0 166d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson result.append(" (Linux; U; Android "); 167d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson 168d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson String version = Build.VERSION.RELEASE; // "1.0" or "3.4b5" 169d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson result.append(version.length() > 0 ? version : "1.0"); 170d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson 171d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson // add the model for the release build 172d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson if ("REL".equals(Build.VERSION.CODENAME)) { 173d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson String model = Build.MODEL; 174d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson if (model.length() > 0) { 175d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson result.append("; "); 176d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson result.append(model); 177d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson } 178d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson } 179d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson String id = Build.ID; // "MASTER" or "M4-rc20" 180d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson if (id.length() > 0) { 181d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson result.append(" Build/"); 182d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson result.append(id); 183d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson } 184d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson result.append(")"); 185d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson return result.toString(); 186d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson } 187d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson 188d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson /** 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Invokes a static "main(argv[]) method on class "className". 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Converts various failing exceptions into RuntimeExceptions, with 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the assumption that they will then cause the VM instance to exit. 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param className Fully-qualified class name 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param argv Argument vector for main() 19529564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath * @param classLoader the classLoader to load {@className} with 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 19729564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader) 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws ZygoteInit.MethodAndArgsCaller { 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Class<?> cl; 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 20229564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath cl = Class.forName(className, true, classLoader); 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (ClassNotFoundException ex) { 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException( 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Missing class when invoking static main " + className, 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ex); 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Method m; 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m = cl.getMethod("main", new Class[] { String[].class }); 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (NoSuchMethodException ex) { 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException( 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Missing static main on " + className, ex); 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException ex) { 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException( 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Problem getting static main on " + className, ex); 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int modifiers = m.getModifiers(); 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) { 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException( 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Main method is not public and static on " + className); 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This throw gets caught in ZygoteInit.main(), which responds 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by invoking the exception's run() method. This arrangement 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * clears up all the stack frames that were required in setting 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * up the process. 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new ZygoteInit.MethodAndArgsCaller(m, argv); 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final void main(String[] argv) { 236ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown if (argv.length == 2 && argv[1].equals("application")) { 237ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application"); 238ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown redirectLogStreams(); 239ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown } else { 240ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting tool"); 241ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown } 242ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project commonInit(); 244e540833fdff4d58e37c9ba859388e24e2945ed45Bob Lee 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Now that we're running in interpreted code, call back into native code 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to run the system. 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 24916f5f5cc9d4c480fac3dc7f176f3f1edfbd256f4Jeff Brown nativeFinishInit(); 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 251ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown if (DEBUG) Slog.d(TAG, "Leaving RuntimeInit!"); 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 253e540833fdff4d58e37c9ba859388e24e2945ed45Bob Lee 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The main function called when started through the zygote process. This 25616f5f5cc9d4c480fac3dc7f176f3f1edfbd256f4Jeff Brown * could be unified with main(), if the native code in nativeFinishInit() 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * were rationalized with Zygote startup.<p> 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Current recognized args: 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li> <code> [--] <start class name> <args> 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 264e1dfcb7ab01fb991079ec1f70f75281a0ca9073eElliott Hughes * @param targetSdkVersion target SDK version 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param argv arg strings 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 26729564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws ZygoteInit.MethodAndArgsCaller { 269ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote"); 270ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown 271ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown redirectLogStreams(); 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project commonInit(); 27416f5f5cc9d4c480fac3dc7f176f3f1edfbd256f4Jeff Brown nativeZygoteInit(); 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27629564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath applicationInit(targetSdkVersion, argv, classLoader); 277ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown } 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 279ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown /** 280ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown * The main function called when an application is started through a 281ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown * wrapper process. 282ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown * 283ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown * When the wrapper starts, the runtime starts {@link RuntimeInit#main} 284ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown * which calls {@link WrapperInit#main} which then calls this method. 285ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown * So we don't need to call commonInit() here. 286ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown * 287e1dfcb7ab01fb991079ec1f70f75281a0ca9073eElliott Hughes * @param targetSdkVersion target SDK version 288ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown * @param argv arg strings 289ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown */ 290e1dfcb7ab01fb991079ec1f70f75281a0ca9073eElliott Hughes public static void wrapperInit(int targetSdkVersion, String[] argv) 291ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown throws ZygoteInit.MethodAndArgsCaller { 292ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from wrapper"); 293ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown 29429564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath applicationInit(targetSdkVersion, argv, null); 295ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown } 296ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown 29729564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) 298ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown throws ZygoteInit.MethodAndArgsCaller { 2994280c4a93ea17f2e9d3f651e49d8c13dc3fb92aaJeff Brown // If the application calls System.exit(), terminate the process 3004280c4a93ea17f2e9d3f651e49d8c13dc3fb92aaJeff Brown // immediately without running any shutdown hooks. It is not possible to 3014280c4a93ea17f2e9d3f651e49d8c13dc3fb92aaJeff Brown // shutdown an Android application gracefully. Among other things, the 3024280c4a93ea17f2e9d3f651e49d8c13dc3fb92aaJeff Brown // Android runtime shutdown hooks close the Binder driver, which can cause 3034280c4a93ea17f2e9d3f651e49d8c13dc3fb92aaJeff Brown // leftover running threads to crash before the process actually exits. 3044280c4a93ea17f2e9d3f651e49d8c13dc3fb92aaJeff Brown nativeSetExitWithoutCleanup(true); 3054280c4a93ea17f2e9d3f651e49d8c13dc3fb92aaJeff Brown 306ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown // We want to be fairly aggressive about heap utilization, to avoid 307ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown // holding on to a lot of memory that isn't needed. 308ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown VMRuntime.getRuntime().setTargetHeapUtilization(0.75f); 309e1dfcb7ab01fb991079ec1f70f75281a0ca9073eElliott Hughes VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion); 310ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown 311ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown final Arguments args; 312ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown try { 313ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown args = new Arguments(argv); 314ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown } catch (IllegalArgumentException ex) { 315ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown Slog.e(TAG, ex.getMessage()); 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // let the process exit 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remaining arguments are passed to the start class's static main 32129564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath invokeStaticMain(args.startClass, args.startArgs, classLoader); 322ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown } 323e540833fdff4d58e37c9ba859388e24e2945ed45Bob Lee 324ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown /** 325ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown * Redirect System.out and System.err to the Android log. 326ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown */ 327ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown public static void redirectLogStreams() { 328ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown System.out.close(); 329ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown System.setOut(new AndroidPrintStream(Log.INFO, "System.out")); 330ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown System.err.close(); 331ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown System.setErr(new AndroidPrintStream(Log.WARN, "System.err")); 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 33560d8762413e8daba5f73559786312a9ec5e3b827Dan Egnor * Report a serious error in the current process. May or may not cause 33660d8762413e8daba5f73559786312a9ec5e3b827Dan Egnor * the process to terminate (depends on system settings). 337e540833fdff4d58e37c9ba859388e24e2945ed45Bob Lee * 33860d8762413e8daba5f73559786312a9ec5e3b827Dan Egnor * @param tag to record with the error 33960d8762413e8daba5f73559786312a9ec5e3b827Dan Egnor * @param t exception describing the error site and conditions 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3415232271a41323594ae406be7476b6ca2f08af3d8Dianne Hackborn public static void wtf(String tag, Throwable t, boolean system) { 34260d8762413e8daba5f73559786312a9ec5e3b827Dan Egnor try { 34360d8762413e8daba5f73559786312a9ec5e3b827Dan Egnor if (ActivityManagerNative.getDefault().handleApplicationWtf( 3445232271a41323594ae406be7476b6ca2f08af3d8Dianne Hackborn mApplicationObject, tag, system, new ApplicationErrorReport.CrashInfo(t))) { 34560d8762413e8daba5f73559786312a9ec5e3b827Dan Egnor // The Activity Manager has already written us off -- now exit. 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Process.killProcess(Process.myPid()); 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.exit(10); 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 34960d8762413e8daba5f73559786312a9ec5e3b827Dan Egnor } catch (Throwable t2) { 350c9421ba1f46d9f9aeee833e1fde2cc263b058411Dianne Hackborn Slog.e(TAG, "Error reporting WTF", t2); 351941adc95e121332b49aedb5406b6037a6395aea6Christopher Tate Slog.e(TAG, "Original WTF:", t); 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set the object identifying this application/process, for reporting VM 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * errors. 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final void setApplicationObject(IBinder app) { 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mApplicationObject = app; 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 363438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick public static final IBinder getApplicationObject() { 364438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick return mApplicationObject; 365438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick } 366438d0595121a7a2cdf19741e76e3c0e21a5c173dBrad Fitzpatrick 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Enable debugging features. 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static { 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Register handlers for DDM messages. 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.ddm.DdmRegister.registerHandlers(); 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 374ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown 375ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown /** 376ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown * Handles argument parsing for args related to the runtime. 377ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown * 378ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown * Current recognized args: 379ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown * <ul> 380ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown * <li> <code> [--] <start class name> <args> 381ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown * </ul> 382ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown */ 383ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown static class Arguments { 384ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown /** first non-option argument */ 385ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown String startClass; 386ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown 387ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown /** all following arguments */ 388ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown String[] startArgs; 389ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown 390ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown /** 391ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown * Constructs instance and parses args 392ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown * @param args runtime command-line args 393ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown * @throws IllegalArgumentException 394ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown */ 395ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown Arguments(String args[]) throws IllegalArgumentException { 396ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown parseArgs(args); 397ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown } 398ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown 399ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown /** 400ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown * Parses the commandline arguments intended for the Runtime. 401ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown */ 402ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown private void parseArgs(String args[]) 403ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown throws IllegalArgumentException { 404ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown int curArg = 0; 405ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown for (; curArg < args.length; curArg++) { 406ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown String arg = args[curArg]; 407ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown 408ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown if (arg.equals("--")) { 409ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown curArg++; 410ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown break; 411ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown } else if (!arg.startsWith("--")) { 412ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown break; 413ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown } 414ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown } 415ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown 416ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown if (curArg == args.length) { 417ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown throw new IllegalArgumentException("Missing classname argument to RuntimeInit!"); 418ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown } 419ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown 420ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown startClass = args[curArg++]; 421ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown startArgs = new String[args.length - curArg]; 422ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown System.arraycopy(args, curArg, startArgs, 0, startArgs.length); 423ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown } 424ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown } 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 426