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; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.IActivityManager; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Debug; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ICheckinService; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Process; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ServiceManager; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemProperties; 28d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilsonimport android.os.Build; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.server.data.CrashData; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Config; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.logging.AndroidConfig; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport dalvik.system.VMRuntime; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.ByteArrayInputStream; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.ByteArrayOutputStream; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.DataInputStream; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.DataOutputStream; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.lang.reflect.Method; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.lang.reflect.Modifier; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.concurrent.atomic.AtomicInteger; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.logging.LogManager; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.TimeZone; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.apache.harmony.luni.internal.util.TimezoneGetter; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Main entry point for runtime initialization. Not for 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * public consumption. 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class RuntimeInit { 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final static String TAG = "AndroidRuntime"; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** true if commonInit() has been called */ 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static boolean initialized; 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Use this to log a message when a thread exits due to an uncaught 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * exception. The framework catches these for the main threads, so 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this should only matter for threads created by applications. 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static class UncaughtHandler implements Thread.UncaughtExceptionHandler { 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void uncaughtException(Thread t, Throwable e) { 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "Uncaught handler: thread " + t.getName() 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " exiting due to uncaught exception"); 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Throwable error) { 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Ignore the throwable, since we're in the process of crashing anyway. 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If we don't, the crash won't happen properly and the process will 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // be left around in a bad state. 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project crash(TAG, e); 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final void commonInit() { 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGV) Log.d(TAG, "Entered RuntimeInit!"); 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* set default handler; this applies to all threads in the VM */ 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler()); 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int hasQwerty = getQwertyKeyboard(); 87e540833fdff4d58e37c9ba859388e24e2945ed45Bob Lee 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGV) Log.d(TAG, ">>>>> qwerty keyboard = " + hasQwerty); 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (hasQwerty == 1) { 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.setProperty("qwerty", "1"); 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Install a TimezoneGetter subclass for ZoneInfo.db 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TimezoneGetter.setInstance(new TimezoneGetter() { 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String getId() { 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SystemProperties.get("persist.sys.timezone"); 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }); 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TimeZone.setDefault(null); 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets handler for java.util.logging to use Android log facilities. 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The odd "new instance-and-then-throw-away" is a mirror of how 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the "java.util.logging.config.class" system property works. We 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * can't use the system property here since the logger has almost 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * certainly already been initialized. 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LogManager.getLogManager().reset(); 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new AndroidConfig(); 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 115d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson * Sets the default HTTP User-Agent used by HttpURLConnection. 116d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson */ 117d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson String userAgent = getDefaultUserAgent(); 118d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson System.setProperty("http.agent", userAgent); 119d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson 120d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson /* 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If we're running in an emulator launched with "-trace", put the 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * VM into emulator trace profiling mode so that the user can hit 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * F9/F10 at any time to capture traces. This has performance 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * consequences, so it's not something you want to do always. 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String trace = SystemProperties.get("ro.kernel.android.tracing"); 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (trace.equals("1")) { 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.i(TAG, "NOTE: emulator trace profiling enabled"); 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Debug.enableEmulatorTraceOutput(); 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project initialized = true; 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 136d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson * Returns an HTTP user agent of the form 137d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson * "Dalvik/1.1.0 (Linux; U; Android Eclair Build/MASTER)". 138d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson */ 139d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson private static String getDefaultUserAgent() { 140d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson StringBuilder result = new StringBuilder(64); 141d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson result.append("Dalvik/"); 142d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson result.append(System.getProperty("java.vm.version")); // such as 1.1.0 143d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson result.append(" (Linux; U; Android "); 144d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson 145d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson String version = Build.VERSION.RELEASE; // "1.0" or "3.4b5" 146d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson result.append(version.length() > 0 ? version : "1.0"); 147d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson 148d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson // add the model for the release build 149d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson if ("REL".equals(Build.VERSION.CODENAME)) { 150d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson String model = Build.MODEL; 151d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson if (model.length() > 0) { 152d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson result.append("; "); 153d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson result.append(model); 154d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson } 155d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson } 156d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson String id = Build.ID; // "MASTER" or "M4-rc20" 157d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson if (id.length() > 0) { 158d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson result.append(" Build/"); 159d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson result.append(id); 160d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson } 161d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson result.append(")"); 162d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson return result.toString(); 163d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson } 164d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson 165d0f80d445644bfc08b62339f01766b924e42dc4dJesse Wilson /** 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Invokes a static "main(argv[]) method on class "className". 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Converts various failing exceptions into RuntimeExceptions, with 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the assumption that they will then cause the VM instance to exit. 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param className Fully-qualified class name 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param argv Argument vector for main() 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 173e540833fdff4d58e37c9ba859388e24e2945ed45Bob Lee private static void invokeStaticMain(String className, String[] argv) 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws ZygoteInit.MethodAndArgsCaller { 175e540833fdff4d58e37c9ba859388e24e2945ed45Bob Lee 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We want to be fairly aggressive about heap utilization, to avoid 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // holding on to a lot of memory that isn't needed. 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project VMRuntime.getRuntime().setTargetHeapUtilization(0.75f); 179e540833fdff4d58e37c9ba859388e24e2945ed45Bob Lee 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Class<?> cl; 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cl = Class.forName(className); 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (ClassNotFoundException ex) { 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException( 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Missing class when invoking static main " + className, 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ex); 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Method m; 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project m = cl.getMethod("main", new Class[] { String[].class }); 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (NoSuchMethodException ex) { 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException( 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Missing static main on " + className, ex); 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException ex) { 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException( 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Problem getting static main on " + className, ex); 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int modifiers = m.getModifiers(); 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) { 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException( 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Main method is not public and static on " + className); 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This throw gets caught in ZygoteInit.main(), which responds 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by invoking the exception's run() method. This arrangement 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * clears up all the stack frames that were required in setting 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * up the process. 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new ZygoteInit.MethodAndArgsCaller(m, argv); 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final void main(String[] argv) { 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project commonInit(); 218e540833fdff4d58e37c9ba859388e24e2945ed45Bob Lee 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Now that we're running in interpreted code, call back into native code 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to run the system. 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project finishInit(); 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGV) Log.d(TAG, "Leaving RuntimeInit!"); 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 227e540833fdff4d58e37c9ba859388e24e2945ed45Bob Lee 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final native void finishInit(); 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The main function called when started through the zygote process. This 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * could be unified with main(), if the native code in finishInit() 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * were rationalized with Zygote startup.<p> 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Current recognized args: 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li> --nice-name=<i>nice name to appear in ps</i> 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li> <code> [--] <start class name> <args> 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param argv arg strings 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final void zygoteInit(String[] argv) 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws ZygoteInit.MethodAndArgsCaller { 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: Doing this here works, but it seems kind of arbitrary. Find 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // a better place. The goal is to set it up for applications, but not 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // tools like am. 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.setOut(new AndroidPrintStream(Log.INFO, "System.out")); 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.setErr(new AndroidPrintStream(Log.WARN, "System.err")); 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project commonInit(); 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zygoteInitNative(); 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int curArg = 0; 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for ( /* curArg */ ; curArg < argv.length; curArg++) { 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String arg = argv[curArg]; 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (arg.equals("--")) { 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curArg++; 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (!arg.startsWith("--")) { 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (arg.startsWith("--nice-name=")) { 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String niceName = arg.substring(arg.indexOf('=') + 1); 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Process.setArgV0(niceName); 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (curArg == argv.length) { 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "Missing classname argument to RuntimeInit!"); 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // let the process exit 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remaining arguments are passed to the start class's static main 276e540833fdff4d58e37c9ba859388e24e2945ed45Bob Lee 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String startClass = argv[curArg++]; 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String[] startArgs = new String[argv.length - curArg]; 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(argv, curArg, startArgs, 0, startArgs.length); 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project invokeStaticMain(startClass, startArgs); 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final native void zygoteInitNative(); 285e540833fdff4d58e37c9ba859388e24e2945ed45Bob Lee 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns 1 if the computer is on. If the computer isn't on, the value returned by this method is undefined. 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final native int isComputerOn(); 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 292e540833fdff4d58e37c9ba859388e24e2945ed45Bob Lee * Turns the computer on if the computer is off. If the computer is on, the behavior of this method is undefined. 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final native void turnComputerOn(); 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 297e540833fdff4d58e37c9ba859388e24e2945ed45Bob Lee * 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return 1 if the device has a qwerty keyboard 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static native int getQwertyKeyboard(); 301e540833fdff4d58e37c9ba859388e24e2945ed45Bob Lee 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Report a fatal error in the current process. If this is a user-process, 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a dialog may be displayed informing the user of the error. This 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * function does not return; it forces the current process to exit. 306e540833fdff4d58e37c9ba859388e24e2945ed45Bob Lee * 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param tag to use when logging the error 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param t exception that was generated by the error 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void crash(String tag, Throwable t) { 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mApplicationObject != null) { 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byte[] crashData = null; 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Log exception. 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, Log.getStackTraceString(t)); 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project crashData = marshallException(tag, t); 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (crashData == null) { 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new NullPointerException("Can't marshall crash data"); 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Throwable t2) { 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Log exception as a string so we don't get in an infinite loop. 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "Error reporting crash: " 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Log.getStackTraceString(t2)); 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Throwable t3) { 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Do nothing, must be OOM so we can't format the message 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Display user-visible error message. 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String msg = t.getMessage(); 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (msg == null) { 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg = t.toString(); 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IActivityManager am = ActivityManagerNative.getDefault(); 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int res = am.handleApplicationError(mApplicationObject, 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 0, tag, msg, t.toString(), crashData); 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Is waiting for the debugger the right thing? 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // For now I have turned off the Debug button, because 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // I'm not sure what we should do if it is actually 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // selected. 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //Log.i(TAG, "Got app error result: " + res); 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (res == 1) { 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Debug.waitForDebugger(); 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Throwable t2) { 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Log exception as a string so we don't get in an infinite loop. 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "Error reporting crash: " 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Log.getStackTraceString(t2)); 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Throwable t3) { 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Do nothing, must be OOM so we can't format the message 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Try everything to make sure this process goes away. 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Process.killProcess(Process.myPid()); 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.exit(10); 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "*** EXCEPTION IN SYSTEM PROCESS. System will crash."); 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(tag, Log.getStackTraceString(t)); 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reportException(tag, t, true); // synchronous 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Throwable t2) { 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Do nothing, must be OOM so we can't format the message 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Try everything to make sure this process goes away. 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Process.killProcess(Process.myPid()); 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.exit(10); 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Counter used to prevent reentrancy in {@link #reportException}. */ 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final AtomicInteger sInReportException = new AtomicInteger(); 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Report an error in the current process. The exception information will 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * be handed off to the checkin service and eventually uploaded for analysis. 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is expensive! Only use this when the exception indicates a programming 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * error ("should not happen"). 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param tag to use when logging the error 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param t exception that was generated by the error 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sync true to wait for the report, false to "fire and forget" 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void reportException(String tag, Throwable t, boolean sync) { 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!initialized) { 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Exceptions during, eg, zygote cannot use this mechanism 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // It's important to prevent an infinite crash-reporting loop: 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // while this function is running, don't let it be called again. 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int reenter = sInReportException.getAndIncrement(); 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (reenter != 0) { 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sInReportException.decrementAndGet(); 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "Crash logging skipped, already logging another crash"); 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: Enable callers to specify a level (i.e. warn or error). 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Submit crash data to statistics service. 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byte[] crashData = marshallException(tag, t); 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ICheckinService checkin = ICheckinService.Stub.asInterface( 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ServiceManager.getService("checkin")); 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (checkin == null) { 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "Crash logging skipped, no checkin service"); 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (sync) { 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkin.reportCrashSync(crashData); 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkin.reportCrashAsync(crashData); 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Throwable t2) { 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Log exception as a string so we don't get in an infinite loop. 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "Crash logging failed: " + t2); 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sInReportException.decrementAndGet(); 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static byte[] marshallException(String tag, Throwable t) { 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Convert crash data to bytes. 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ByteArrayOutputStream bout = new ByteArrayOutputStream(); 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DataOutputStream dout = new DataOutputStream(bout); 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new CrashData(tag, t).write(dout); 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project dout.close(); 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return bout.toByteArray(); 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Replay an encoded CrashData record back into a useable CrashData record. This can be 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * helpful for providing debugging output after a process error. 445e540833fdff4d58e37c9ba859388e24e2945ed45Bob Lee * 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param crashDataBytes The byte array containing the encoded crash record 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return new CrashData record, or null if could not create one. 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static CrashData unmarshallException(byte[] crashDataBytes) { 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ByteArrayInputStream bin = new ByteArrayInputStream(crashDataBytes); 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DataInputStream din = new DataInputStream(bin); 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new CrashData(din); 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set the object identifying this application/process, for reporting VM 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * errors. 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final void setApplicationObject(IBinder app) { 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mApplicationObject = app; 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Enable debugging features. 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static { 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Register handlers for DDM messages. 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.ddm.DdmRegister.registerHandlers(); 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static IBinder mApplicationObject; 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 478