summaryrefslogtreecommitdiffstats
path: root/core/java/com/android/internal/os/RuntimeInit.java
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:45 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 18:28:45 -0800
commitd83a98f4ce9cfa908f5c54bbd70f03eec07e7553 (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904 /core/java/com/android/internal/os/RuntimeInit.java
parent076357b8567458d4b6dfdcf839ef751634cd2bfb (diff)
downloadframeworks_base-d83a98f4ce9cfa908f5c54bbd70f03eec07e7553.zip
frameworks_base-d83a98f4ce9cfa908f5c54bbd70f03eec07e7553.tar.gz
frameworks_base-d83a98f4ce9cfa908f5c54bbd70f03eec07e7553.tar.bz2
auto import from //depot/cupcake/@135843
Diffstat (limited to 'core/java/com/android/internal/os/RuntimeInit.java')
-rw-r--r--core/java/com/android/internal/os/RuntimeInit.java440
1 files changed, 0 insertions, 440 deletions
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
deleted file mode 100644
index 8486272..0000000
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.os;
-
-import android.app.ActivityManagerNative;
-import android.app.IActivityManager;
-import android.os.Debug;
-import android.os.IBinder;
-import android.os.ICheckinService;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemProperties;
-import android.server.data.CrashData;
-import android.util.Config;
-import android.util.Log;
-
-import com.android.internal.logging.AndroidConfig;
-
-import dalvik.system.VMRuntime;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.logging.LogManager;
-import java.util.TimeZone;
-
-import org.apache.harmony.luni.internal.util.TimezoneGetter;
-
-/**
- * Main entry point for runtime initialization. Not for
- * public consumption.
- * @hide
- */
-public class RuntimeInit {
- private final static String TAG = "AndroidRuntime";
-
- /** true if commonInit() has been called */
- private static boolean initialized;
-
- /**
- * Use this to log a message when a thread exits due to an uncaught
- * exception. The framework catches these for the main threads, so
- * this should only matter for threads created by applications.
- */
- private static class UncaughtHandler implements Thread.UncaughtExceptionHandler {
- public void uncaughtException(Thread t, Throwable e) {
- try {
- Log.e(TAG, "Uncaught handler: thread " + t.getName()
- + " exiting due to uncaught exception");
- } catch (Throwable error) {
- // Ignore the throwable, since we're in the process of crashing anyway.
- // If we don't, the crash won't happen properly and the process will
- // be left around in a bad state.
- }
- crash(TAG, e);
- }
- }
-
- private static final void commonInit() {
- if (Config.LOGV) Log.d(TAG, "Entered RuntimeInit!");
-
- /* set default handler; this applies to all threads in the VM */
- Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler());
-
- int hasQwerty = getQwertyKeyboard();
-
- if (Config.LOGV) Log.d(TAG, ">>>>> qwerty keyboard = " + hasQwerty);
- if (hasQwerty == 1) {
- System.setProperty("qwerty", "1");
- }
-
- /*
- * Install a TimezoneGetter subclass for ZoneInfo.db
- */
- TimezoneGetter.setInstance(new TimezoneGetter() {
- @Override
- public String getId() {
- return SystemProperties.get("persist.sys.timezone");
- }
- });
- TimeZone.setDefault(null);
-
- /*
- * Sets handler for java.util.logging to use Android log facilities.
- * The odd "new instance-and-then-throw-away" is a mirror of how
- * the "java.util.logging.config.class" system property works. We
- * can't use the system property here since the logger has almost
- * certainly already been initialized.
- */
- LogManager.getLogManager().reset();
- new AndroidConfig();
-
- /*
- * If we're running in an emulator launched with "-trace", put the
- * VM into emulator trace profiling mode so that the user can hit
- * F9/F10 at any time to capture traces. This has performance
- * consequences, so it's not something you want to do always.
- */
- String trace = SystemProperties.get("ro.kernel.android.tracing");
- if (trace.equals("1")) {
- Log.i(TAG, "NOTE: emulator trace profiling enabled");
- Debug.enableEmulatorTraceOutput();
- }
-
- initialized = true;
- }
-
- /**
- * Invokes a static "main(argv[]) method on class "className".
- * Converts various failing exceptions into RuntimeExceptions, with
- * the assumption that they will then cause the VM instance to exit.
- *
- * @param className Fully-qualified class name
- * @param argv Argument vector for main()
- */
- private static void invokeStaticMain(String className, String[] argv)
- throws ZygoteInit.MethodAndArgsCaller {
-
- // We want to be fairly aggressive about heap utilization, to avoid
- // holding on to a lot of memory that isn't needed.
- VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
-
- Class<?> cl;
-
- try {
- cl = Class.forName(className);
- } catch (ClassNotFoundException ex) {
- throw new RuntimeException(
- "Missing class when invoking static main " + className,
- ex);
- }
-
- Method m;
- try {
- m = cl.getMethod("main", new Class[] { String[].class });
- } catch (NoSuchMethodException ex) {
- throw new RuntimeException(
- "Missing static main on " + className, ex);
- } catch (SecurityException ex) {
- throw new RuntimeException(
- "Problem getting static main on " + className, ex);
- }
-
- int modifiers = m.getModifiers();
- if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
- throw new RuntimeException(
- "Main method is not public and static on " + className);
- }
-
- /*
- * This throw gets caught in ZygoteInit.main(), which responds
- * by invoking the exception's run() method. This arrangement
- * clears up all the stack frames that were required in setting
- * up the process.
- */
- throw new ZygoteInit.MethodAndArgsCaller(m, argv);
- }
-
- public static final void main(String[] argv) {
- commonInit();
-
- /*
- * Now that we're running in interpreted code, call back into native code
- * to run the system.
- */
- finishInit();
-
- if (Config.LOGV) Log.d(TAG, "Leaving RuntimeInit!");
- }
-
- public static final native void finishInit();
-
- /**
- * The main function called when started through the zygote process. This
- * could be unified with main(), if the native code in finishInit()
- * were rationalized with Zygote startup.<p>
- *
- * Current recognized args:
- * <ul>
- * <li> --nice-name=<i>nice name to appear in ps</i>
- * <li> <code> [--] &lt;start class name&gt; &lt;args&gt;
- * </ul>
- *
- * @param argv arg strings
- */
- public static final void zygoteInit(String[] argv)
- throws ZygoteInit.MethodAndArgsCaller {
- // TODO: Doing this here works, but it seems kind of arbitrary. Find
- // a better place. The goal is to set it up for applications, but not
- // tools like am.
- System.setOut(new AndroidPrintStream(Log.INFO, "System.out"));
- System.setErr(new AndroidPrintStream(Log.WARN, "System.err"));
-
- commonInit();
- zygoteInitNative();
-
- int curArg = 0;
- for ( /* curArg */ ; curArg < argv.length; curArg++) {
- String arg = argv[curArg];
-
- if (arg.equals("--")) {
- curArg++;
- break;
- } else if (!arg.startsWith("--")) {
- break;
- } else if (arg.startsWith("--nice-name=")) {
- String niceName = arg.substring(arg.indexOf('=') + 1);
- Process.setArgV0(niceName);
- }
- }
-
- if (curArg == argv.length) {
- Log.e(TAG, "Missing classname argument to RuntimeInit!");
- // let the process exit
- return;
- }
-
- // Remaining arguments are passed to the start class's static main
-
- String startClass = argv[curArg++];
- String[] startArgs = new String[argv.length - curArg];
-
- System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);
- invokeStaticMain(startClass, startArgs);
- }
-
- public static final native void zygoteInitNative();
-
- /**
- * Returns 1 if the computer is on. If the computer isn't on, the value returned by this method is undefined.
- */
- public static final native int isComputerOn();
-
- /**
- * Turns the computer on if the computer is off. If the computer is on, the behavior of this method is undefined.
- */
- public static final native void turnComputerOn();
-
- /**
- *
- * @return 1 if the device has a qwerty keyboard
- */
- public static native int getQwertyKeyboard();
-
- /**
- * Report a fatal error in the current process. If this is a user-process,
- * a dialog may be displayed informing the user of the error. This
- * function does not return; it forces the current process to exit.
- *
- * @param tag to use when logging the error
- * @param t exception that was generated by the error
- */
- public static void crash(String tag, Throwable t) {
- if (mApplicationObject != null) {
- byte[] crashData = null;
- try {
- // Log exception.
- Log.e(TAG, Log.getStackTraceString(t));
- crashData = marshallException(tag, t);
- if (crashData == null) {
- throw new NullPointerException("Can't marshall crash data");
- }
- } catch (Throwable t2) {
- try {
- // Log exception as a string so we don't get in an infinite loop.
- Log.e(TAG, "Error reporting crash: "
- + Log.getStackTraceString(t2));
- } catch (Throwable t3) {
- // Do nothing, must be OOM so we can't format the message
- }
- }
-
- try {
- // Display user-visible error message.
- String msg = t.getMessage();
- if (msg == null) {
- msg = t.toString();
- }
-
- IActivityManager am = ActivityManagerNative.getDefault();
- try {
- int res = am.handleApplicationError(mApplicationObject,
- 0, tag, msg, t.toString(), crashData);
- // Is waiting for the debugger the right thing?
- // For now I have turned off the Debug button, because
- // I'm not sure what we should do if it is actually
- // selected.
- //Log.i(TAG, "Got app error result: " + res);
- if (res == 1) {
- Debug.waitForDebugger();
- return;
- }
- } catch (RemoteException e) {
- }
- } catch (Throwable t2) {
- try {
- // Log exception as a string so we don't get in an infinite loop.
- Log.e(TAG, "Error reporting crash: "
- + Log.getStackTraceString(t2));
- } catch (Throwable t3) {
- // Do nothing, must be OOM so we can't format the message
- }
- } finally {
- // Try everything to make sure this process goes away.
- Process.killProcess(Process.myPid());
- System.exit(10);
- }
- } else {
- try {
- Log.e(TAG, "*** EXCEPTION IN SYSTEM PROCESS. System will crash.");
- Log.e(tag, Log.getStackTraceString(t));
- reportException(tag, t, true); // synchronous
- } catch (Throwable t2) {
- // Do nothing, must be OOM so we can't format the message
- } finally {
- // Try everything to make sure this process goes away.
- Process.killProcess(Process.myPid());
- System.exit(10);
- }
- }
- }
-
- /** Counter used to prevent reentrancy in {@link #reportException}. */
- private static final AtomicInteger sInReportException = new AtomicInteger();
-
- /**
- * Report an error in the current process. The exception information will
- * be handed off to the checkin service and eventually uploaded for analysis.
- * This is expensive! Only use this when the exception indicates a programming
- * error ("should not happen").
- *
- * @param tag to use when logging the error
- * @param t exception that was generated by the error
- * @param sync true to wait for the report, false to "fire and forget"
- */
- public static void reportException(String tag, Throwable t, boolean sync) {
- if (!initialized) {
- // Exceptions during, eg, zygote cannot use this mechanism
- return;
- }
-
- // It's important to prevent an infinite crash-reporting loop:
- // while this function is running, don't let it be called again.
- int reenter = sInReportException.getAndIncrement();
- if (reenter != 0) {
- sInReportException.decrementAndGet();
- Log.e(TAG, "Crash logging skipped, already logging another crash");
- return;
- }
-
- // TODO: Enable callers to specify a level (i.e. warn or error).
- try {
- // Submit crash data to statistics service.
- byte[] crashData = marshallException(tag, t);
- ICheckinService checkin = ICheckinService.Stub.asInterface(
- ServiceManager.getService("checkin"));
- if (checkin == null) {
- Log.e(TAG, "Crash logging skipped, no checkin service");
- } else if (sync) {
- checkin.reportCrashSync(crashData);
- } else {
- checkin.reportCrashAsync(crashData);
- }
- } catch (Throwable t2) {
- // Log exception as a string so we don't get in an infinite loop.
- Log.e(TAG, "Crash logging failed: " + t2);
- } finally {
- sInReportException.decrementAndGet();
- }
- }
-
- private static byte[] marshallException(String tag, Throwable t) {
- // Convert crash data to bytes.
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
- DataOutputStream dout = new DataOutputStream(bout);
- try {
- new CrashData(tag, t).write(dout);
- dout.close();
- } catch (IOException e) {
- return null;
- }
- return bout.toByteArray();
- }
-
- /**
- * Replay an encoded CrashData record back into a useable CrashData record. This can be
- * helpful for providing debugging output after a process error.
- *
- * @param crashDataBytes The byte array containing the encoded crash record
- * @return new CrashData record, or null if could not create one.
- */
- public static CrashData unmarshallException(byte[] crashDataBytes) {
- try {
- ByteArrayInputStream bin = new ByteArrayInputStream(crashDataBytes);
- DataInputStream din = new DataInputStream(bin);
- return new CrashData(din);
- } catch (IOException e) {
- return null;
- }
- }
-
- /**
- * Set the object identifying this application/process, for reporting VM
- * errors.
- */
- public static final void setApplicationObject(IBinder app) {
- mApplicationObject = app;
- }
-
- /**
- * Enable debugging features.
- */
- static {
- // Register handlers for DDM messages.
- android.ddm.DdmRegister.registerHandlers();
- }
-
- private static IBinder mApplicationObject;
-
-}