RuntimeInit.java revision b7f0367cec1c744aa66ef397b0244e25d507491c
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;
20b7f0367cec1c744aa66ef397b0244e25d507491cDan Egnorimport android.app.ApplicationErrorReport;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.IActivityManager;
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.ICheckinService;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Process;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ServiceManager;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemProperties;
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> [--] &lt;start class name&gt;  &lt;args&gt;
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            try {
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Log exception.
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.e(TAG, Log.getStackTraceString(t));
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
316b7f0367cec1c744aa66ef397b0244e25d507491cDan Egnor                // Show a message to the user.
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                IActivityManager am = ActivityManagerNative.getDefault();
318b7f0367cec1c744aa66ef397b0244e25d507491cDan Egnor                am.handleApplicationError(mApplicationObject, tag,
319b7f0367cec1c744aa66ef397b0244e25d507491cDan Egnor                        new ApplicationErrorReport.CrashInfo(t));
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.
323b7f0367cec1c744aa66ef397b0244e25d507491cDan Egnor                    Log.e(TAG, "Error reporting crash: " + Log.getStackTraceString(t2));
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (Throwable t3) {
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Do nothing, must be OOM so we can't format the message
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } finally {
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Try everything to make sure this process goes away.
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Process.killProcess(Process.myPid());
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                System.exit(10);
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.e(TAG, "*** EXCEPTION IN SYSTEM PROCESS.  System will crash.");
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.e(tag, Log.getStackTraceString(t));
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (Throwable t2) {
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Do nothing, must be OOM so we can't format the message
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } finally {
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Try everything to make sure this process goes away.
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Process.killProcess(Process.myPid());
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                System.exit(10);
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Counter used to prevent reentrancy in {@link #reportException}. */
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final AtomicInteger sInReportException = new AtomicInteger();
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Set the object identifying this application/process, for reporting VM
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * errors.
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final void setApplicationObject(IBinder app) {
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mApplicationObject = app;
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Enable debugging features.
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static {
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Register handlers for DDM messages.
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        android.ddm.DdmRegister.registerHandlers();
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static IBinder mApplicationObject;
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
367