19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 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
19a9569ff70f51a93e134e4d45558884d196b869c3Elliott Hughesimport static android.system.OsConstants.S_IRWXG;
20a9569ff70f51a93e134e4d45558884d196b869c3Elliott Hughesimport static android.system.OsConstants.S_IRWXO;
214c74f8c1713fa82904b10beec4da9ad8ebb97375Kenny Root
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray;
244f41f6198baf60cdb9992736dc7682ae7e291e0eNeil Fullerimport android.icu.impl.CacheValue;
254f41f6198baf60cdb9992736dc7682ae7e291e0eNeil Fullerimport android.icu.text.DecimalFormatSymbols;
264f41f6198baf60cdb9992736dc7682ae7e291e0eNeil Fullerimport android.icu.util.ULocale;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.LocalServerSocket;
28ba0370eef3d17baa70d43723e96eb135c8e4ed58Jesse Hallimport android.opengl.EGL14;
29b3eecebddd08f43790f3104bbb298f480b2338ddMathieu Chartierimport android.os.Build;
30740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkeyimport android.os.IInstalld;
31b3eecebddd08f43790f3104bbb298f480b2338ddMathieu Chartierimport android.os.Environment;
32ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brownimport android.os.Process;
33740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkeyimport android.os.RemoteException;
34ef854774704d61992f13b8c49b9d210bf33ef4a8Paul Lawrenceimport android.os.Seccomp;
35740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkeyimport android.os.ServiceManager;
36740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkeyimport android.os.ServiceSpecificException;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemClock;
38c5e3638c06f30827cdc6eb0d987adb677e900487Romain Guyimport android.os.SystemProperties;
396ad0452e6301c0650f58f3991f7c523f6f279ddbJamie Gennisimport android.os.Trace;
408f8d187a78b48109911a800ba5993b645d3015c5Robert Sesekimport android.os.ZygoteProcess;
41c98c7bccdccbff1ceeda501e6a6f8c21d61649caJeff Sharkeyimport android.os.storage.StorageManager;
4269de32071c8ca7fa2277e4340a320b7df6fe963dSergio Giroimport android.security.keystore.AndroidKeyStoreProvider;
439a76e9ba1adbdf7cc431b1e6fe454cf0c5d900deBill Yiimport android.system.ErrnoException;
44860c5911a2437ab2543614e138c98553d0d4ebf7Elliott Hughesimport android.system.Os;
45860c5911a2437ab2543614e138c98553d0d4ebf7Elliott Hughesimport android.system.OsConstants;
46c3dd1c1b91b4e47c3b141944be68037ec2d607d8Raph Levienimport android.text.Hyphenator;
473235e0c2eeb9f1c3d7152ebc2738a2e784085d38Fyodor Kupolovimport android.util.BootTimingsTraceLog;
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.EventLog;
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
5076d4fc84518b3560fc0e8d912a09c1eefefe85acAndreas Gampeimport android.util.Slog;
5108cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles)import android.webkit.WebViewFactory;
52ddc1397eba25e17591e3491dddb192b3fa38100fAndreas Gampeimport android.widget.TextView;
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
543235e0c2eeb9f1c3d7152ebc2738a2e784085d38Fyodor Kupolovimport com.android.internal.logging.MetricsLogger;
55fdeeeea6cfdebdb98dd70a7dd48965743af01750Jeff Sharkey
56669afcc9d05606eeaf7ebe87f991e1bf1b583f9dNarayan Kamathimport com.android.internal.util.Preconditions;
5729564cd24589867f653cd22cabbaac6493cfc530Narayan Kamathimport dalvik.system.DexFile;
5829564cd24589867f653cd22cabbaac6493cfc530Narayan Kamathimport dalvik.system.PathClassLoader;
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport dalvik.system.VMRuntime;
601ef8aef260c19236be023c429b41a46e7f5da8b0Andreas Gampeimport dalvik.system.ZygoteHooks;
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6246703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstromimport libcore.io.IoUtils;
6346703b099516c383a6882815bcf9cd4df0ec538dBrian Carlstrom
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.BufferedReader;
65b3eecebddd08f43790f3104bbb298f480b2338ddMathieu Chartierimport java.io.File;
66d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wangimport java.io.FileInputStream;
67d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wangimport java.io.FileNotFoundException;
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException;
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.InputStream;
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.InputStreamReader;
716cb7b1c4765e9bc5175056826523dbd88426e9aaSergio Giroimport java.security.Security;
726cb7b1c4765e9bc5175056826523dbd88426e9aaSergio Giroimport java.security.Provider;
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Startup class for the zygote process.
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Pre-initializes some classes, and then waits for commands on a UNIX domain
78e1dfcb7ab01fb991079ec1f70f75281a0ca9073eElliott Hughes * socket. Based on these commands, forks off child processes that inherit
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the initial state of the VM.
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Please see {@link ZygoteConnection.Arguments} for documentation on the
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * client protocol.
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class ZygoteInit {
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String TAG = "Zygote";
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
892852a28254a5b8b99b2a74554af1dd8e9828c60eJesse Hall    private static final String PROPERTY_DISABLE_OPENGL_PRELOADING = "ro.zygote.disable_gl_preload";
90ba0370eef3d17baa70d43723e96eb135c8e4ed58Jesse Hall    private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
915dd239a1f8e305013ee782e45e7e789ec531e9d1Luis Hector Chavez    private static final String PROPERTY_RUNNING_IN_CONTAINER = "ro.boot.container";
92c5e3638c06f30827cdc6eb0d987adb677e900487Romain Guy
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int LOG_BOOT_PROGRESS_PRELOAD_START = 3020;
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int LOG_BOOT_PROGRESS_PRELOAD_END = 3030;
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** when preloading, GC after allocating this many bytes */
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int PRELOAD_GC_THRESHOLD = 50000;
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
99c41638cb759ce569630ffae4c5c4cdee1b0f3b82Narayan Kamath    private static final String ABI_LIST_ARG = "--abi-list=";
100c41638cb759ce569630ffae4c5c4cdee1b0f3b82Narayan Kamath
101c41638cb759ce569630ffae4c5c4cdee1b0f3b82Narayan Kamath    private static final String SOCKET_NAME_ARG = "--socket-name=";
1020b3533ae838811d15afb1017144dfbf7c41df4a8Barry Hayes
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
104dd4bb31639047b27118d44b9a0609952fac6debfTobias Sargeant     * Used to pre-load resources.
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static Resources mResources;
107e540833fdff4d58e37c9ba859388e24e2945ed45Bob Lee
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
109d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang     * The path of a file that contains classes to preload.
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
111d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang    private static final String PRELOADED_CLASSES = "/system/etc/preloaded-classes";
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** Controls whether we should preload resources during zygote init. */
1143c27a2303fdb6b222b7b7628fea7bc3c159990ffSteve Paik    public static final boolean PRELOAD_RESOURCES = true;
115599c918d9794b51992de85b42befa0c71d9ec07fAndy McFadden
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int UNPRIVILEGED_UID = 9999;
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int UNPRIVILEGED_GID = 9999;
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int ROOT_UID = 0;
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int ROOT_GID = 0;
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1225a3d0c6e11d9eee40e8134c2efc8fcf6485ce7c5Narayan Kamath    private static boolean sPreloadComplete;
1235a3d0c6e11d9eee40e8134c2efc8fcf6485ce7c5Narayan Kamath
1243235e0c2eeb9f1c3d7152ebc2738a2e784085d38Fyodor Kupolov    static void preload(BootTimingsTraceLog bootTimingsTraceLog) {
1259a76e9ba1adbdf7cc431b1e6fe454cf0c5d900deBill Yi        Log.d(TAG, "begin preload");
1263235e0c2eeb9f1c3d7152ebc2738a2e784085d38Fyodor Kupolov        bootTimingsTraceLog.traceBegin("BeginIcuCachePinning");
1274f41f6198baf60cdb9992736dc7682ae7e291e0eNeil Fuller        beginIcuCachePinning();
1283235e0c2eeb9f1c3d7152ebc2738a2e784085d38Fyodor Kupolov        bootTimingsTraceLog.traceEnd(); // BeginIcuCachePinning
1293235e0c2eeb9f1c3d7152ebc2738a2e784085d38Fyodor Kupolov        bootTimingsTraceLog.traceBegin("PreloadClasses");
13025878b288846831048e157271c635d31d1c7557bYasuhiro Matsuda        preloadClasses();
1313235e0c2eeb9f1c3d7152ebc2738a2e784085d38Fyodor Kupolov        bootTimingsTraceLog.traceEnd(); // PreloadClasses
1323235e0c2eeb9f1c3d7152ebc2738a2e784085d38Fyodor Kupolov        bootTimingsTraceLog.traceBegin("PreloadResources");
13325878b288846831048e157271c635d31d1c7557bYasuhiro Matsuda        preloadResources();
1343235e0c2eeb9f1c3d7152ebc2738a2e784085d38Fyodor Kupolov        bootTimingsTraceLog.traceEnd(); // PreloadResources
135ba0370eef3d17baa70d43723e96eb135c8e4ed58Jesse Hall        Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadOpenGL");
136ba0370eef3d17baa70d43723e96eb135c8e4ed58Jesse Hall        preloadOpenGL();
137ba0370eef3d17baa70d43723e96eb135c8e4ed58Jesse Hall        Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
1386c9af96de59ab2feebe3d0165548591c4f632bc5Brian Carlstrom        preloadSharedLibraries();
139c3dd1c1b91b4e47c3b141944be68037ec2d607d8Raph Levien        preloadTextResources();
14008cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles)        // Ask the WebViewFactory to do any initialization that must run in the zygote process,
14108cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles)        // for memory sharing purposes.
14208cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles)        WebViewFactory.prepareWebViewInZygote();
1434f41f6198baf60cdb9992736dc7682ae7e291e0eNeil Fuller        endIcuCachePinning();
1446cb7b1c4765e9bc5175056826523dbd88426e9aaSergio Giro        warmUpJcaProviders();
1459a76e9ba1adbdf7cc431b1e6fe454cf0c5d900deBill Yi        Log.d(TAG, "end preload");
1465a3d0c6e11d9eee40e8134c2efc8fcf6485ce7c5Narayan Kamath
1475a3d0c6e11d9eee40e8134c2efc8fcf6485ce7c5Narayan Kamath        sPreloadComplete = true;
1485a3d0c6e11d9eee40e8134c2efc8fcf6485ce7c5Narayan Kamath    }
1495a3d0c6e11d9eee40e8134c2efc8fcf6485ce7c5Narayan Kamath
150669afcc9d05606eeaf7ebe87f991e1bf1b583f9dNarayan Kamath    public static void lazyPreload() {
151669afcc9d05606eeaf7ebe87f991e1bf1b583f9dNarayan Kamath        Preconditions.checkState(!sPreloadComplete);
152669afcc9d05606eeaf7ebe87f991e1bf1b583f9dNarayan Kamath        Log.i(TAG, "Lazily preloading resources.");
153669afcc9d05606eeaf7ebe87f991e1bf1b583f9dNarayan Kamath
154669afcc9d05606eeaf7ebe87f991e1bf1b583f9dNarayan Kamath        preload(new BootTimingsTraceLog("ZygoteInitTiming_lazy", Trace.TRACE_TAG_DALVIK));
15574c691221b620d74eafff315bf7c8ed8c4b58f3aRomain Guy    }
15674c691221b620d74eafff315bf7c8ed8c4b58f3aRomain Guy
1574f41f6198baf60cdb9992736dc7682ae7e291e0eNeil Fuller    private static void beginIcuCachePinning() {
1584f41f6198baf60cdb9992736dc7682ae7e291e0eNeil Fuller        // Pin ICU data in memory from this point that would normally be held by soft references.
1594f41f6198baf60cdb9992736dc7682ae7e291e0eNeil Fuller        // Without this, any references created immediately below or during class preloading
1604f41f6198baf60cdb9992736dc7682ae7e291e0eNeil Fuller        // would be collected when the Zygote GC runs in gcAndFinalize().
1614f41f6198baf60cdb9992736dc7682ae7e291e0eNeil Fuller        Log.i(TAG, "Installing ICU cache reference pinning...");
1624f41f6198baf60cdb9992736dc7682ae7e291e0eNeil Fuller
1634f41f6198baf60cdb9992736dc7682ae7e291e0eNeil Fuller        CacheValue.setStrength(CacheValue.Strength.STRONG);
1644f41f6198baf60cdb9992736dc7682ae7e291e0eNeil Fuller
1654f41f6198baf60cdb9992736dc7682ae7e291e0eNeil Fuller        Log.i(TAG, "Preloading ICU data...");
1664f41f6198baf60cdb9992736dc7682ae7e291e0eNeil Fuller        // Explicitly exercise code to cache data apps are likely to need.
1674f41f6198baf60cdb9992736dc7682ae7e291e0eNeil Fuller        ULocale[] localesToPin = { ULocale.ROOT, ULocale.US, ULocale.getDefault() };
1684f41f6198baf60cdb9992736dc7682ae7e291e0eNeil Fuller        for (ULocale uLocale : localesToPin) {
1694f41f6198baf60cdb9992736dc7682ae7e291e0eNeil Fuller            new DecimalFormatSymbols(uLocale);
1704f41f6198baf60cdb9992736dc7682ae7e291e0eNeil Fuller        }
1714f41f6198baf60cdb9992736dc7682ae7e291e0eNeil Fuller    }
1724f41f6198baf60cdb9992736dc7682ae7e291e0eNeil Fuller
1734f41f6198baf60cdb9992736dc7682ae7e291e0eNeil Fuller    private static void endIcuCachePinning() {
1744f41f6198baf60cdb9992736dc7682ae7e291e0eNeil Fuller        // All cache references created by ICU from this point will be soft.
1754f41f6198baf60cdb9992736dc7682ae7e291e0eNeil Fuller        CacheValue.setStrength(CacheValue.Strength.SOFT);
1764f41f6198baf60cdb9992736dc7682ae7e291e0eNeil Fuller
1774f41f6198baf60cdb9992736dc7682ae7e291e0eNeil Fuller        Log.i(TAG, "Uninstalled ICU cache reference pinning...");
1784f41f6198baf60cdb9992736dc7682ae7e291e0eNeil Fuller    }
1794f41f6198baf60cdb9992736dc7682ae7e291e0eNeil Fuller
1806c9af96de59ab2feebe3d0165548591c4f632bc5Brian Carlstrom    private static void preloadSharedLibraries() {
1816c9af96de59ab2feebe3d0165548591c4f632bc5Brian Carlstrom        Log.i(TAG, "Preloading shared libraries...");
1826c9af96de59ab2feebe3d0165548591c4f632bc5Brian Carlstrom        System.loadLibrary("android");
1836c9af96de59ab2feebe3d0165548591c4f632bc5Brian Carlstrom        System.loadLibrary("compiler_rt");
1846c9af96de59ab2feebe3d0165548591c4f632bc5Brian Carlstrom        System.loadLibrary("jnigraphics");
1856c9af96de59ab2feebe3d0165548591c4f632bc5Brian Carlstrom    }
1866c9af96de59ab2feebe3d0165548591c4f632bc5Brian Carlstrom
187ba0370eef3d17baa70d43723e96eb135c8e4ed58Jesse Hall    private static void preloadOpenGL() {
188ba0370eef3d17baa70d43723e96eb135c8e4ed58Jesse Hall        String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
1895d911fe6bb8f05a69b208fafeb3f6bd4b13f06adJesse Hall        if (!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING, false) &&
1905d911fe6bb8f05a69b208fafeb3f6bd4b13f06adJesse Hall                (driverPackageName == null || driverPackageName.isEmpty())) {
191ba0370eef3d17baa70d43723e96eb135c8e4ed58Jesse Hall            EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
192ba0370eef3d17baa70d43723e96eb135c8e4ed58Jesse Hall        }
193ba0370eef3d17baa70d43723e96eb135c8e4ed58Jesse Hall    }
194ba0370eef3d17baa70d43723e96eb135c8e4ed58Jesse Hall
195c3dd1c1b91b4e47c3b141944be68037ec2d607d8Raph Levien    private static void preloadTextResources() {
196c3dd1c1b91b4e47c3b141944be68037ec2d607d8Raph Levien        Hyphenator.init();
197ddc1397eba25e17591e3491dddb192b3fa38100fAndreas Gampe        TextView.preloadFontCache();
198c3dd1c1b91b4e47c3b141944be68037ec2d607d8Raph Levien    }
199c3dd1c1b91b4e47c3b141944be68037ec2d607d8Raph Levien
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
20169de32071c8ca7fa2277e4340a320b7df6fe963dSergio Giro     * Register AndroidKeyStoreProvider and warm up the providers that are already registered.
2026cb7b1c4765e9bc5175056826523dbd88426e9aaSergio Giro     *
2036cb7b1c4765e9bc5175056826523dbd88426e9aaSergio Giro     * By doing it here we avoid that each app does it when requesting a service from the
2046cb7b1c4765e9bc5175056826523dbd88426e9aaSergio Giro     * provider for the first time.
2056cb7b1c4765e9bc5175056826523dbd88426e9aaSergio Giro     */
2066cb7b1c4765e9bc5175056826523dbd88426e9aaSergio Giro    private static void warmUpJcaProviders() {
2076cb7b1c4765e9bc5175056826523dbd88426e9aaSergio Giro        long startTime = SystemClock.uptimeMillis();
2086cb7b1c4765e9bc5175056826523dbd88426e9aaSergio Giro        Trace.traceBegin(
20969de32071c8ca7fa2277e4340a320b7df6fe963dSergio Giro                Trace.TRACE_TAG_DALVIK, "Starting installation of AndroidKeyStoreProvider");
21069de32071c8ca7fa2277e4340a320b7df6fe963dSergio Giro        // AndroidKeyStoreProvider.install() manipulates the list of JCA providers to insert
21169de32071c8ca7fa2277e4340a320b7df6fe963dSergio Giro        // preferred providers. Note this is not done via security.properties as the JCA providers
21269de32071c8ca7fa2277e4340a320b7df6fe963dSergio Giro        // are not on the classpath in the case of, for example, raw dalvikvm runtimes.
21369de32071c8ca7fa2277e4340a320b7df6fe963dSergio Giro        AndroidKeyStoreProvider.install();
21469de32071c8ca7fa2277e4340a320b7df6fe963dSergio Giro        Log.i(TAG, "Installed AndroidKeyStoreProvider in "
21569de32071c8ca7fa2277e4340a320b7df6fe963dSergio Giro                + (SystemClock.uptimeMillis() - startTime) + "ms.");
21669de32071c8ca7fa2277e4340a320b7df6fe963dSergio Giro        Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
21769de32071c8ca7fa2277e4340a320b7df6fe963dSergio Giro
21869de32071c8ca7fa2277e4340a320b7df6fe963dSergio Giro        startTime = SystemClock.uptimeMillis();
21969de32071c8ca7fa2277e4340a320b7df6fe963dSergio Giro        Trace.traceBegin(
2206cb7b1c4765e9bc5175056826523dbd88426e9aaSergio Giro                Trace.TRACE_TAG_DALVIK, "Starting warm up of JCA providers");
2216cb7b1c4765e9bc5175056826523dbd88426e9aaSergio Giro        for (Provider p : Security.getProviders()) {
2226cb7b1c4765e9bc5175056826523dbd88426e9aaSergio Giro            p.warmUpServiceProvision();
2236cb7b1c4765e9bc5175056826523dbd88426e9aaSergio Giro        }
2246cb7b1c4765e9bc5175056826523dbd88426e9aaSergio Giro        Log.i(TAG, "Warmed up JCA providers in "
22569de32071c8ca7fa2277e4340a320b7df6fe963dSergio Giro                + (SystemClock.uptimeMillis() - startTime) + "ms.");
2266cb7b1c4765e9bc5175056826523dbd88426e9aaSergio Giro        Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
2276cb7b1c4765e9bc5175056826523dbd88426e9aaSergio Giro    }
2286cb7b1c4765e9bc5175056826523dbd88426e9aaSergio Giro
2296cb7b1c4765e9bc5175056826523dbd88426e9aaSergio Giro    /**
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Performs Zygote process initialization. Loads and initializes
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * commonly used classes.
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Most classes only cause a few hundred bytes to be allocated, but
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * a few will allocate a dozen Kbytes (in one case, 500+K).
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static void preloadClasses() {
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final VMRuntime runtime = VMRuntime.getRuntime();
238e540833fdff4d58e37c9ba859388e24e2945ed45Bob Lee
239d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang        InputStream is;
240d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang        try {
241d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang            is = new FileInputStream(PRELOADED_CLASSES);
242d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang        } catch (FileNotFoundException e) {
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + ".");
244d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang            return;
245d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang        }
246e540833fdff4d58e37c9ba859388e24e2945ed45Bob Lee
247d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang        Log.i(TAG, "Preloading classes...");
248d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang        long startTime = SystemClock.uptimeMillis();
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
250d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang        // Drop root perms while running static initializers.
25123e68780be581a1bb05110f16ad56d1da2bed1e9Narayan Kamath        final int reuid = Os.getuid();
25223e68780be581a1bb05110f16ad56d1da2bed1e9Narayan Kamath        final int regid = Os.getgid();
25323e68780be581a1bb05110f16ad56d1da2bed1e9Narayan Kamath
25423e68780be581a1bb05110f16ad56d1da2bed1e9Narayan Kamath        // We need to drop root perms only if we're already root. In the case of "wrapped"
25523e68780be581a1bb05110f16ad56d1da2bed1e9Narayan Kamath        // processes (see WrapperInit), this function is called from an unprivileged uid
25623e68780be581a1bb05110f16ad56d1da2bed1e9Narayan Kamath        // and gid.
25723e68780be581a1bb05110f16ad56d1da2bed1e9Narayan Kamath        boolean droppedPriviliges = false;
25823e68780be581a1bb05110f16ad56d1da2bed1e9Narayan Kamath        if (reuid == ROOT_UID && regid == ROOT_GID) {
25923e68780be581a1bb05110f16ad56d1da2bed1e9Narayan Kamath            try {
26023e68780be581a1bb05110f16ad56d1da2bed1e9Narayan Kamath                Os.setregid(ROOT_GID, UNPRIVILEGED_GID);
26123e68780be581a1bb05110f16ad56d1da2bed1e9Narayan Kamath                Os.setreuid(ROOT_UID, UNPRIVILEGED_UID);
26223e68780be581a1bb05110f16ad56d1da2bed1e9Narayan Kamath            } catch (ErrnoException ex) {
26323e68780be581a1bb05110f16ad56d1da2bed1e9Narayan Kamath                throw new RuntimeException("Failed to drop root", ex);
26423e68780be581a1bb05110f16ad56d1da2bed1e9Narayan Kamath            }
26523e68780be581a1bb05110f16ad56d1da2bed1e9Narayan Kamath
26623e68780be581a1bb05110f16ad56d1da2bed1e9Narayan Kamath            droppedPriviliges = true;
26726b56e628bd77b1e77137b68aecb194791ec6cf6Elliott Hughes        }
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
269d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang        // Alter the target heap utilization.  With explicit GCs this
270d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang        // is not likely to have any effect.
271d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang        float defaultUtilization = runtime.getTargetHeapUtilization();
272d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang        runtime.setTargetHeapUtilization(0.8f);
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
274d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang        try {
275d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang            BufferedReader br
276d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang                = new BufferedReader(new InputStreamReader(is), 256);
277d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang
278d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang            int count = 0;
279d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang            String line;
280d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang            while ((line = br.readLine()) != null) {
281d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang                // Skip comments and blank lines.
282d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang                line = line.trim();
283d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang                if (line.startsWith("#") || line.equals("")) {
284d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang                    continue;
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
287c425362049390c61c0654ea2510f5c5c1db8588eAndreas Gampe                Trace.traceBegin(Trace.TRACE_TAG_DALVIK, line);
288d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang                try {
289d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang                    if (false) {
290d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang                        Log.v(TAG, "Preloading " + line + "...");
291d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang                    }
292dd8e5fbe96ecdf95ce8629ca5c6e1d8c520ecff4Andreas Gampe                    // Load and explicitly initialize the given class. Use
293dd8e5fbe96ecdf95ce8629ca5c6e1d8c520ecff4Andreas Gampe                    // Class.forName(String, boolean, ClassLoader) to avoid repeated stack lookups
294dd8e5fbe96ecdf95ce8629ca5c6e1d8c520ecff4Andreas Gampe                    // (to derive the caller's class-loader). Use true to force initialization, and
295dd8e5fbe96ecdf95ce8629ca5c6e1d8c520ecff4Andreas Gampe                    // null for the boot classpath class-loader (could as well cache the
296dd8e5fbe96ecdf95ce8629ca5c6e1d8c520ecff4Andreas Gampe                    // class-loader of this class in a variable).
297c917f74d9235feefd1788a7b9ba34ed8f1215850Andreas Gampe                    Class.forName(line, true, null);
298d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang                    count++;
299d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang                } catch (ClassNotFoundException e) {
300d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang                    Log.w(TAG, "Class not found for preloading: " + line);
301d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang                } catch (UnsatisfiedLinkError e) {
302d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang                    Log.w(TAG, "Problem preloading " + line + ": " + e);
303d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang                } catch (Throwable t) {
304d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang                    Log.e(TAG, "Error preloading " + line + ".", t);
305d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang                    if (t instanceof Error) {
306d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang                        throw (Error) t;
307d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang                    }
308d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang                    if (t instanceof RuntimeException) {
309d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang                        throw (RuntimeException) t;
310d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang                    }
311d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang                    throw new RuntimeException(t);
312d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang                }
31325878b288846831048e157271c635d31d1c7557bYasuhiro Matsuda                Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
315d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang
316d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang            Log.i(TAG, "...preloaded " + count + " classes in "
317d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang                    + (SystemClock.uptimeMillis()-startTime) + "ms.");
318d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang        } catch (IOException e) {
319d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang            Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);
320d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang        } finally {
321d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang            IoUtils.closeQuietly(is);
322d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang            // Restore default.
323d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang            runtime.setTargetHeapUtilization(defaultUtilization);
324d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang
325d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang            // Fill in dex caches with classes, fields, and methods brought in by preloading.
3261ab43d5978813f56899dbd3115fd7d9f96b4fe55Yasuhiro Matsuda            Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadDexCaches");
327d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang            runtime.preloadDexCaches();
3281ab43d5978813f56899dbd3115fd7d9f96b4fe55Yasuhiro Matsuda            Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
329d0c45355b96fb55dd1a79ee06d151ce98d959c23Ying Wang
33023e68780be581a1bb05110f16ad56d1da2bed1e9Narayan Kamath            // Bring back root. We'll need it later if we're in the zygote.
33123e68780be581a1bb05110f16ad56d1da2bed1e9Narayan Kamath            if (droppedPriviliges) {
33223e68780be581a1bb05110f16ad56d1da2bed1e9Narayan Kamath                try {
33323e68780be581a1bb05110f16ad56d1da2bed1e9Narayan Kamath                    Os.setreuid(ROOT_UID, ROOT_UID);
33423e68780be581a1bb05110f16ad56d1da2bed1e9Narayan Kamath                    Os.setregid(ROOT_GID, ROOT_GID);
33523e68780be581a1bb05110f16ad56d1da2bed1e9Narayan Kamath                } catch (ErrnoException ex) {
33623e68780be581a1bb05110f16ad56d1da2bed1e9Narayan Kamath                    throw new RuntimeException("Failed to restore root", ex);
33723e68780be581a1bb05110f16ad56d1da2bed1e9Narayan Kamath                }
33826b56e628bd77b1e77137b68aecb194791ec6cf6Elliott Hughes            }
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Load in commonly used resources, so they can be shared across
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * processes.
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * These tend to be a few Kbytes, but are frequently in the 20-40K
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * range, and occasionally even larger.
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static void preloadResources() {
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final VMRuntime runtime = VMRuntime.getRuntime();
351e540833fdff4d58e37c9ba859388e24e2945ed45Bob Lee
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mResources = Resources.getSystem();
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mResources.startPreloading();
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (PRELOAD_RESOURCES) {
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.i(TAG, "Preloading resources...");
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                long startTime = SystemClock.uptimeMillis();
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                TypedArray ar = mResources.obtainTypedArray(
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        com.android.internal.R.array.preloaded_drawables);
361811dc3b42b4d3c967a2304bf1e01840147b1a528Filip Gruszczynski                int N = preloadDrawables(ar);
36214577c4df57004131174fbe435031a18f3e7996bJeff Brown                ar.recycle();
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.i(TAG, "...preloaded " + N + " resources in "
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + (SystemClock.uptimeMillis()-startTime) + "ms.");
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                startTime = SystemClock.uptimeMillis();
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ar = mResources.obtainTypedArray(
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        com.android.internal.R.array.preloaded_color_state_lists);
369811dc3b42b4d3c967a2304bf1e01840147b1a528Filip Gruszczynski                N = preloadColorStateLists(ar);
37014577c4df57004131174fbe435031a18f3e7996bJeff Brown                ar.recycle();
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.i(TAG, "...preloaded " + N + " resources in "
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + (SystemClock.uptimeMillis()-startTime) + "ms.");
373811dc3b42b4d3c967a2304bf1e01840147b1a528Filip Gruszczynski
374811dc3b42b4d3c967a2304bf1e01840147b1a528Filip Gruszczynski                if (mResources.getBoolean(
375811dc3b42b4d3c967a2304bf1e01840147b1a528Filip Gruszczynski                        com.android.internal.R.bool.config_freeformWindowManagement)) {
376811dc3b42b4d3c967a2304bf1e01840147b1a528Filip Gruszczynski                    startTime = SystemClock.uptimeMillis();
377811dc3b42b4d3c967a2304bf1e01840147b1a528Filip Gruszczynski                    ar = mResources.obtainTypedArray(
378811dc3b42b4d3c967a2304bf1e01840147b1a528Filip Gruszczynski                            com.android.internal.R.array.preloaded_freeform_multi_window_drawables);
379811dc3b42b4d3c967a2304bf1e01840147b1a528Filip Gruszczynski                    N = preloadDrawables(ar);
380811dc3b42b4d3c967a2304bf1e01840147b1a528Filip Gruszczynski                    ar.recycle();
381811dc3b42b4d3c967a2304bf1e01840147b1a528Filip Gruszczynski                    Log.i(TAG, "...preloaded " + N + " resource in "
382811dc3b42b4d3c967a2304bf1e01840147b1a528Filip Gruszczynski                            + (SystemClock.uptimeMillis() - startTime) + "ms.");
383811dc3b42b4d3c967a2304bf1e01840147b1a528Filip Gruszczynski                }
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mResources.finishPreloading();
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RuntimeException e) {
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.w(TAG, "Failure preloading resources", e);
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
391811dc3b42b4d3c967a2304bf1e01840147b1a528Filip Gruszczynski    private static int preloadColorStateLists(TypedArray ar) {
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int N = ar.length();
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i=0; i<N; i++) {
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int id = ar.getResourceId(i, 0);
39543a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato            if (false) {
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.v(TAG, "Preloading resource #" + Integer.toHexString(id));
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (id != 0) {
39977bb6f179a5495c90470f910d46667d8306ae010Alan Viverette                if (mResources.getColorStateList(id, null) == null) {
400dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn                    throw new IllegalArgumentException(
401dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn                            "Unable to find preloaded color resource #0x"
402dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn                            + Integer.toHexString(id)
403dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn                            + " (" + ar.getString(i) + ")");
404dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn                }
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return N;
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
411811dc3b42b4d3c967a2304bf1e01840147b1a528Filip Gruszczynski    private static int preloadDrawables(TypedArray ar) {
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int N = ar.length();
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i=0; i<N; i++) {
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int id = ar.getResourceId(i, 0);
41543a17654cf4bfe7f1ec22bd8b7b32daccdf27c09Joe Onorato            if (false) {
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Log.v(TAG, "Preloading resource #" + Integer.toHexString(id));
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (id != 0) {
41984e001a9f514a047816f27db6ce836966efa481eAlan Viverette                if (mResources.getDrawable(id, null) == null) {
420dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn                    throw new IllegalArgumentException(
421dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn                            "Unable to find preloaded drawable resource #0x"
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            + Integer.toHexString(id)
423dde331cebd87982faded6818ad5f9927ff994c96Dianne Hackborn                            + " (" + ar.getString(i) + ")");
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return N;
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Runs several special GCs to try to clean up a few generations of
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * softly- and final-reachable objects, along with any other garbage.
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is only useful just before a fork().
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4359a88f10b8996645d7c479df3610c9af1499e741cMathieu Chartier    /*package*/ static void gcAndFinalize() {
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final VMRuntime runtime = VMRuntime.getRuntime();
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /* runFinalizationSync() lets finalizers be called in Zygote,
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * which doesn't have a HeapWorker thread.
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
44108065b9f09ead8895d97b2971622af8c179e1768Brian Carlstrom        System.gc();
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        runtime.runFinalizationSync();
44308065b9f09ead8895d97b2971622af8c179e1768Brian Carlstrom        System.gc();
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Finish remaining work for the newly forked system server process.
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static void handleSystemServerProcess(
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ZygoteConnection.Arguments parsedArgs)
451dd4bb31639047b27118d44b9a0609952fac6debfTobias Sargeant            throws Zygote.MethodAndArgsCaller {
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
45390960e87ecae696f73ae18e46c2f003fc3f592ccMike Lockwood        // set umask to 0077 so new files and directories will default to owner-only permissions.
454860c5911a2437ab2543614e138c98553d0d4ebf7Elliott Hughes        Os.umask(S_IRWXG | S_IRWXO);
45590960e87ecae696f73ae18e46c2f003fc3f592ccMike Lockwood
456ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown        if (parsedArgs.niceName != null) {
457ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown            Process.setArgV0(parsedArgs.niceName);
458ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown        }
459ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown
46029564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath        final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
46129564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath        if (systemServerClasspath != null) {
46229564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath            performSystemServerDexOpt(systemServerClasspath);
463b3eecebddd08f43790f3104bbb298f480b2338ddMathieu Chartier            // Capturing profiles is only supported for debug or eng builds since selinux normally
464b3eecebddd08f43790f3104bbb298f480b2338ddMathieu Chartier            // prevents it.
465b3eecebddd08f43790f3104bbb298f480b2338ddMathieu Chartier            boolean profileSystemServer = SystemProperties.getBoolean(
466b3eecebddd08f43790f3104bbb298f480b2338ddMathieu Chartier                    "dalvik.vm.profilesystemserver", false);
467b3eecebddd08f43790f3104bbb298f480b2338ddMathieu Chartier            if (profileSystemServer && (Build.IS_USERDEBUG || Build.IS_ENG)) {
468b3eecebddd08f43790f3104bbb298f480b2338ddMathieu Chartier                try {
469b3eecebddd08f43790f3104bbb298f480b2338ddMathieu Chartier                    File profileDir = Environment.getDataProfilesDePackageDirectory(
470b3eecebddd08f43790f3104bbb298f480b2338ddMathieu Chartier                            Process.SYSTEM_UID, "system_server");
471b3eecebddd08f43790f3104bbb298f480b2338ddMathieu Chartier                    File profile = new File(profileDir, "primary.prof");
472b3eecebddd08f43790f3104bbb298f480b2338ddMathieu Chartier                    profile.getParentFile().mkdirs();
473b3eecebddd08f43790f3104bbb298f480b2338ddMathieu Chartier                    profile.createNewFile();
474b3eecebddd08f43790f3104bbb298f480b2338ddMathieu Chartier                    String[] codePaths = systemServerClasspath.split(":");
475b3eecebddd08f43790f3104bbb298f480b2338ddMathieu Chartier                    VMRuntime.registerAppInfo(profile.getPath(), codePaths);
476b3eecebddd08f43790f3104bbb298f480b2338ddMathieu Chartier                } catch (Exception e) {
477b3eecebddd08f43790f3104bbb298f480b2338ddMathieu Chartier                    Log.wtf(TAG, "Failed to set up system server profile", e);
478b3eecebddd08f43790f3104bbb298f480b2338ddMathieu Chartier                }
479b3eecebddd08f43790f3104bbb298f480b2338ddMathieu Chartier            }
48029564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath        }
48129564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath
482ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown        if (parsedArgs.invokeWith != null) {
48329564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath            String[] args = parsedArgs.remainingArgs;
48429564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath            // If we have a non-null system server class path, we'll have to duplicate the
48529564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath            // existing arguments and append the classpath to it. ART will handle the classpath
48629564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath            // correctly when we exec a new process.
48729564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath            if (systemServerClasspath != null) {
48829564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath                String[] amendedArgs = new String[args.length + 2];
48929564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath                amendedArgs[0] = "-cp";
49029564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath                amendedArgs[1] = systemServerClasspath;
49134738174ba6e5967b51cb4fd77de49d5717d225dtony.ys_liu                System.arraycopy(args, 0, amendedArgs, 2, args.length);
49234738174ba6e5967b51cb4fd77de49d5717d225dtony.ys_liu                args = amendedArgs;
49329564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath            }
49429564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath
495ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown            WrapperInit.execApplication(parsedArgs.invokeWith,
496e1dfcb7ab01fb991079ec1f70f75281a0ca9073eElliott Hughes                    parsedArgs.niceName, parsedArgs.targetSdkVersion,
49737ad4b0242579d9a7251c8683eb20645be44cea8Narayan Kamath                    VMRuntime.getCurrentInstructionSet(), null, args);
498ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown        } else {
49929564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath            ClassLoader cl = null;
50029564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath            if (systemServerClasspath != null) {
50134738174ba6e5967b51cb4fd77de49d5717d225dtony.ys_liu                cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
50289dad3360ea6ae2fa0c4eb70a760b8d6bcb98b82Dimitry Ivanov
50329564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath                Thread.currentThread().setContextClassLoader(cl);
50429564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath            }
50529564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath
506ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown            /*
507ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown             * Pass the remaining arguments to SystemServer.
508ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown             */
50976d4fc84518b3560fc0e8d912a09c1eefefe85acAndreas Gampe            ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
510ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown        }
511ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /* should never reach here */
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
51634738174ba6e5967b51cb4fd77de49d5717d225dtony.ys_liu     * Creates a PathClassLoader for the given class path that is associated with a shared
51734738174ba6e5967b51cb4fd77de49d5717d225dtony.ys_liu     * namespace, i.e., this classloader can access platform-private native libraries. The
51834738174ba6e5967b51cb4fd77de49d5717d225dtony.ys_liu     * classloader will use java.library.path as the native library path.
51989dad3360ea6ae2fa0c4eb70a760b8d6bcb98b82Dimitry Ivanov     */
52034738174ba6e5967b51cb4fd77de49d5717d225dtony.ys_liu    static PathClassLoader createPathClassLoader(String classPath, int targetSdkVersion) {
5219e9061f608abc6ae76f1b190c62ad5336f65ec89Dimitry Ivanov      String libraryPath = System.getProperty("java.library.path");
52289dad3360ea6ae2fa0c4eb70a760b8d6bcb98b82Dimitry Ivanov
52334738174ba6e5967b51cb4fd77de49d5717d225dtony.ys_liu      return PathClassLoaderFactory.createClassLoader(classPath,
5249e9061f608abc6ae76f1b190c62ad5336f65ec89Dimitry Ivanov                                                      libraryPath,
5259e9061f608abc6ae76f1b190c62ad5336f65ec89Dimitry Ivanov                                                      libraryPath,
52689dad3360ea6ae2fa0c4eb70a760b8d6bcb98b82Dimitry Ivanov                                                      ClassLoader.getSystemClassLoader(),
52789dad3360ea6ae2fa0c4eb70a760b8d6bcb98b82Dimitry Ivanov                                                      targetSdkVersion,
52889dad3360ea6ae2fa0c4eb70a760b8d6bcb98b82Dimitry Ivanov                                                      true /* isNamespaceShared */);
52989dad3360ea6ae2fa0c4eb70a760b8d6bcb98b82Dimitry Ivanov    }
53089dad3360ea6ae2fa0c4eb70a760b8d6bcb98b82Dimitry Ivanov
53189dad3360ea6ae2fa0c4eb70a760b8d6bcb98b82Dimitry Ivanov    /**
53229564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath     * Performs dex-opt on the elements of {@code classPath}, if needed. We
53329564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath     * choose the instruction set of the current runtime.
53429564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath     */
53529564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath    private static void performSystemServerDexOpt(String classPath) {
53629564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath        final String[] classPathElements = classPath.split(":");
537740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey        final IInstalld installd = IInstalld.Stub
538740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey                .asInterface(ServiceManager.getService("installd"));
53929564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath        final String instructionSet = VMRuntime.getRuntime().vmInstructionSet();
54029564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath
541740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey        String sharedLibraries = "";
542740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey        for (String classPathElement : classPathElements) {
543740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey            // System server is fully AOTed and never profiled
544740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey            // for profile guided compilation.
545740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey            // TODO: Make this configurable between INTERPRET_ONLY, SPEED, SPACE and EVERYTHING?
546740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey
547740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey            int dexoptNeeded;
548740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey            try {
549740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey                dexoptNeeded = DexFile.getDexOptNeeded(
550740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey                    classPathElement, instructionSet, "speed",
551740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey                    false /* newProfile */);
552740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey            } catch (FileNotFoundException ignored) {
553740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey                // Do not add to the classpath.
554740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey                Log.w(TAG, "Missing classpath element for system server: " + classPathElement);
555740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey                continue;
556740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey            } catch (IOException e) {
557740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey                // Not fully clear what to do here as we don't know the cause of the
558740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey                // IO exception. Add to the classpath to be conservative, but don't
559740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey                // attempt to compile it.
560740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey                Log.w(TAG, "Error checking classpath element for system server: "
561740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey                        + classPathElement, e);
562740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey                dexoptNeeded = DexFile.NO_DEXOPT_NEEDED;
563740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey            }
564e7bc152c20a21dfa76bdf0f2f129fc0ccf38761dAndreas Gampe
565740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey            if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
566740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey                final String packageName = "*";
567740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey                final String outputPath = null;
568740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey                final int dexFlags = 0;
569740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey                final String compilerFilter = "speed";
570740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey                final String uuid = StorageManager.UUID_PRIVATE_INTERNAL;
571811a75a0c0dbe211ccabdfbfba60c8f76d5738ebCalin Juravle                final String seInfo = null;
572e7bc152c20a21dfa76bdf0f2f129fc0ccf38761dAndreas Gampe                try {
573740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey                    installd.dexopt(classPathElement, Process.SYSTEM_UID, packageName,
574740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey                            instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter,
575811a75a0c0dbe211ccabdfbfba60c8f76d5738ebCalin Juravle                            uuid, sharedLibraries, seInfo);
576740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey                } catch (RemoteException | ServiceSpecificException e) {
577740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey                    // Ignore (but log), we need this on the classpath for fallback mode.
578740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey                    Log.w(TAG, "Failed compiling classpath element for system server: "
579e7bc152c20a21dfa76bdf0f2f129fc0ccf38761dAndreas Gampe                            + classPathElement, e);
58029564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath                }
581740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey            }
582e7bc152c20a21dfa76bdf0f2f129fc0ccf38761dAndreas Gampe
583740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey            if (!sharedLibraries.isEmpty()) {
584740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey                sharedLibraries += ":";
58529564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath            }
586740f523b2571d1c4eb4a954e1faedea45dd7fa53Jeff Sharkey            sharedLibraries += classPathElement;
58729564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath        }
58829564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath    }
58929564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath
59029564cd24589867f653cd22cabbaac6493cfc530Narayan Kamath    /**
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Prepare the arguments and fork for the system server process.
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
593dd4bb31639047b27118d44b9a0609952fac6debfTobias Sargeant    private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
594dd4bb31639047b27118d44b9a0609952fac6debfTobias Sargeant            throws Zygote.MethodAndArgsCaller, RuntimeException {
59548a06e740782184bd126ab743150b474abc9e6a4Alex Klyubin        long capabilities = posixCapabilitiesAsBits(
5967bd0fdd639640f9ddffbffa6a117644134d8be30Philip Cuadra            OsConstants.CAP_IPC_LOCK,
59748a06e740782184bd126ab743150b474abc9e6a4Alex Klyubin            OsConstants.CAP_KILL,
59848a06e740782184bd126ab743150b474abc9e6a4Alex Klyubin            OsConstants.CAP_NET_ADMIN,
59948a06e740782184bd126ab743150b474abc9e6a4Alex Klyubin            OsConstants.CAP_NET_BIND_SERVICE,
60048a06e740782184bd126ab743150b474abc9e6a4Alex Klyubin            OsConstants.CAP_NET_BROADCAST,
60148a06e740782184bd126ab743150b474abc9e6a4Alex Klyubin            OsConstants.CAP_NET_RAW,
60248a06e740782184bd126ab743150b474abc9e6a4Alex Klyubin            OsConstants.CAP_SYS_MODULE,
60348a06e740782184bd126ab743150b474abc9e6a4Alex Klyubin            OsConstants.CAP_SYS_NICE,
6043082eb7c7253c62a06aa151a80487a4eabd49914Nick Kralevich            OsConstants.CAP_SYS_PTRACE,
60548a06e740782184bd126ab743150b474abc9e6a4Alex Klyubin            OsConstants.CAP_SYS_TIME,
6065733f387be6cef3836ed06ed897ab43897eb470dJohn Stultz            OsConstants.CAP_SYS_TTY_CONFIG,
6075733f387be6cef3836ed06ed897ab43897eb470dJohn Stultz            OsConstants.CAP_WAKE_ALARM
60848a06e740782184bd126ab743150b474abc9e6a4Alex Klyubin        );
6095dd239a1f8e305013ee782e45e7e789ec531e9d1Luis Hector Chavez        /* Containers run without this capability, so avoid setting it in that case */
6105dd239a1f8e305013ee782e45e7e789ec531e9d1Luis Hector Chavez        if (!SystemProperties.getBoolean(PROPERTY_RUNNING_IN_CONTAINER, false)) {
6115dd239a1f8e305013ee782e45e7e789ec531e9d1Luis Hector Chavez            capabilities |= posixCapabilitiesAsBits(OsConstants.CAP_BLOCK_SUSPEND);
6125dd239a1f8e305013ee782e45e7e789ec531e9d1Luis Hector Chavez        }
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /* Hardcoded command line to start the system server */
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String args[] = {
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            "--setuid=1000",
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            "--setgid=1000",
617053a909fd82706e0a213c00e00c397d19b893836Jeff Sharkey            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
61848a06e740782184bd126ab743150b474abc9e6a4Alex Klyubin            "--capabilities=" + capabilities + "," + capabilities,
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            "--nice-name=system_server",
620b6b044ae8263d1104e249ad2b857f0c570309990Narayan Kamath            "--runtime-args",
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            "com.android.server.SystemServer",
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        };
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ZygoteConnection.Arguments parsedArgs = null;
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int pid;
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            parsedArgs = new ZygoteConnection.Arguments(args);
629ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
630ebed7d6e35f7f960e6e6add2b8ab7c7a31a511c3Jeff Brown            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            /* Request to fork the system server process */
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pid = Zygote.forkSystemServer(
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    parsedArgs.uid, parsedArgs.gid,
635e1dfcb7ab01fb991079ec1f70f75281a0ca9073eElliott Hughes                    parsedArgs.gids,
636e1dfcb7ab01fb991079ec1f70f75281a0ca9073eElliott Hughes                    parsedArgs.debugFlags,
637e1dfcb7ab01fb991079ec1f70f75281a0ca9073eElliott Hughes                    null,
6381b4c7966b15382e9ffb2bfe6468dcef0b6d090b6Andy McFadden                    parsedArgs.permittedCapabilities,
6391b4c7966b15382e9ffb2bfe6468dcef0b6d090b6Andy McFadden                    parsedArgs.effectiveCapabilities);
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (IllegalArgumentException ex) {
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new RuntimeException(ex);
642e540833fdff4d58e37c9ba859388e24e2945ed45Bob Lee        }
643e540833fdff4d58e37c9ba859388e24e2945ed45Bob Lee
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /* For child process */
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (pid == 0) {
64664cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath            if (hasSecondZygote(abiList)) {
64764cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath                waitForSecondaryZygote(socketName);
64864cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath            }
64964cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath
650dd4bb31639047b27118d44b9a0609952fac6debfTobias Sargeant            zygoteServer.closeServerSocket();
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            handleSystemServerProcess(parsedArgs);
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
65748a06e740782184bd126ab743150b474abc9e6a4Alex Klyubin    /**
65848a06e740782184bd126ab743150b474abc9e6a4Alex Klyubin     * Gets the bit array representation of the provided list of POSIX capabilities.
65948a06e740782184bd126ab743150b474abc9e6a4Alex Klyubin     */
66048a06e740782184bd126ab743150b474abc9e6a4Alex Klyubin    private static long posixCapabilitiesAsBits(int... capabilities) {
66148a06e740782184bd126ab743150b474abc9e6a4Alex Klyubin        long result = 0;
66248a06e740782184bd126ab743150b474abc9e6a4Alex Klyubin        for (int capability : capabilities) {
66348a06e740782184bd126ab743150b474abc9e6a4Alex Klyubin            if ((capability < 0) || (capability > OsConstants.CAP_LAST_CAP)) {
66448a06e740782184bd126ab743150b474abc9e6a4Alex Klyubin                throw new IllegalArgumentException(String.valueOf(capability));
66548a06e740782184bd126ab743150b474abc9e6a4Alex Klyubin            }
66648a06e740782184bd126ab743150b474abc9e6a4Alex Klyubin            result |= (1L << capability);
66748a06e740782184bd126ab743150b474abc9e6a4Alex Klyubin        }
66848a06e740782184bd126ab743150b474abc9e6a4Alex Klyubin        return result;
66948a06e740782184bd126ab743150b474abc9e6a4Alex Klyubin    }
67048a06e740782184bd126ab743150b474abc9e6a4Alex Klyubin
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static void main(String argv[]) {
672dd4bb31639047b27118d44b9a0609952fac6debfTobias Sargeant        ZygoteServer zygoteServer = new ZygoteServer();
673dd4bb31639047b27118d44b9a0609952fac6debfTobias Sargeant
6741ef8aef260c19236be023c429b41a46e7f5da8b0Andreas Gampe        // Mark zygote start. This ensures that thread creation will throw
6751ef8aef260c19236be023c429b41a46e7f5da8b0Andreas Gampe        // an error.
6761ef8aef260c19236be023c429b41a46e7f5da8b0Andreas Gampe        ZygoteHooks.startZygoteNoThreadCreation();
6771ef8aef260c19236be023c429b41a46e7f5da8b0Andreas Gampe
678e4f8d69c58e3e0a54b1434d64217d30e8d448864Robert Sesek        // Zygote goes into its own process group.
679e4f8d69c58e3e0a54b1434d64217d30e8d448864Robert Sesek        try {
680e4f8d69c58e3e0a54b1434d64217d30e8d448864Robert Sesek            Os.setpgid(0, 0);
681e4f8d69c58e3e0a54b1434d64217d30e8d448864Robert Sesek        } catch (ErrnoException ex) {
682e4f8d69c58e3e0a54b1434d64217d30e8d448864Robert Sesek            throw new RuntimeException("Failed to setpgid(0,0)", ex);
683e4f8d69c58e3e0a54b1434d64217d30e8d448864Robert Sesek        }
684e4f8d69c58e3e0a54b1434d64217d30e8d448864Robert Sesek
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
6866733e6c6b6f5c49b3c668caae9a8765221c22412Fyodor Kupolov            // Report Zygote start time to tron unless it is a runtime restart
6876733e6c6b6f5c49b3c668caae9a8765221c22412Fyodor Kupolov            if (!"1".equals(SystemProperties.get("sys.boot_completed"))) {
6886733e6c6b6f5c49b3c668caae9a8765221c22412Fyodor Kupolov                MetricsLogger.histogram(null, "boot_zygote_init",
6896733e6c6b6f5c49b3c668caae9a8765221c22412Fyodor Kupolov                        (int) SystemClock.elapsedRealtime());
6906733e6c6b6f5c49b3c668caae9a8765221c22412Fyodor Kupolov            }
6913235e0c2eeb9f1c3d7152ebc2738a2e784085d38Fyodor Kupolov
6923235e0c2eeb9f1c3d7152ebc2738a2e784085d38Fyodor Kupolov            String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
6933235e0c2eeb9f1c3d7152ebc2738a2e784085d38Fyodor Kupolov            BootTimingsTraceLog bootTimingsTraceLog = new BootTimingsTraceLog(bootTimeTag,
6943235e0c2eeb9f1c3d7152ebc2738a2e784085d38Fyodor Kupolov                    Trace.TRACE_TAG_DALVIK);
6953235e0c2eeb9f1c3d7152ebc2738a2e784085d38Fyodor Kupolov            bootTimingsTraceLog.traceBegin("ZygoteInit");
69625878b288846831048e157271c635d31d1c7557bYasuhiro Matsuda            RuntimeInit.enableDdms();
69725878b288846831048e157271c635d31d1c7557bYasuhiro Matsuda            // Start profiling the zygote initialization.
69825878b288846831048e157271c635d31d1c7557bYasuhiro Matsuda            SamplingProfilerIntegration.start();
69925878b288846831048e157271c635d31d1c7557bYasuhiro Matsuda
700c41638cb759ce569630ffae4c5c4cdee1b0f3b82Narayan Kamath            boolean startSystemServer = false;
701c41638cb759ce569630ffae4c5c4cdee1b0f3b82Narayan Kamath            String socketName = "zygote";
702c41638cb759ce569630ffae4c5c4cdee1b0f3b82Narayan Kamath            String abiList = null;
7035a3d0c6e11d9eee40e8134c2efc8fcf6485ce7c5Narayan Kamath            boolean enableLazyPreload = false;
70425878b288846831048e157271c635d31d1c7557bYasuhiro Matsuda            for (int i = 1; i < argv.length; i++) {
70525878b288846831048e157271c635d31d1c7557bYasuhiro Matsuda                if ("start-system-server".equals(argv[i])) {
70625878b288846831048e157271c635d31d1c7557bYasuhiro Matsuda                    startSystemServer = true;
7075a3d0c6e11d9eee40e8134c2efc8fcf6485ce7c5Narayan Kamath                } else if ("--enable-lazy-preload".equals(argv[i])) {
7085a3d0c6e11d9eee40e8134c2efc8fcf6485ce7c5Narayan Kamath                    enableLazyPreload = true;
70925878b288846831048e157271c635d31d1c7557bYasuhiro Matsuda                } else if (argv[i].startsWith(ABI_LIST_ARG)) {
71025878b288846831048e157271c635d31d1c7557bYasuhiro Matsuda                    abiList = argv[i].substring(ABI_LIST_ARG.length());
71125878b288846831048e157271c635d31d1c7557bYasuhiro Matsuda                } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
71225878b288846831048e157271c635d31d1c7557bYasuhiro Matsuda                    socketName = argv[i].substring(SOCKET_NAME_ARG.length());
71325878b288846831048e157271c635d31d1c7557bYasuhiro Matsuda                } else {
71425878b288846831048e157271c635d31d1c7557bYasuhiro Matsuda                    throw new RuntimeException("Unknown command line argument: " + argv[i]);
715c41638cb759ce569630ffae4c5c4cdee1b0f3b82Narayan Kamath                }
71625878b288846831048e157271c635d31d1c7557bYasuhiro Matsuda            }
717c41638cb759ce569630ffae4c5c4cdee1b0f3b82Narayan Kamath
71825878b288846831048e157271c635d31d1c7557bYasuhiro Matsuda            if (abiList == null) {
71925878b288846831048e157271c635d31d1c7557bYasuhiro Matsuda                throw new RuntimeException("No ABI list supplied.");
72025878b288846831048e157271c635d31d1c7557bYasuhiro Matsuda            }
721c41638cb759ce569630ffae4c5c4cdee1b0f3b82Narayan Kamath
722dd4bb31639047b27118d44b9a0609952fac6debfTobias Sargeant            zygoteServer.registerServerSocket(socketName);
7235a3d0c6e11d9eee40e8134c2efc8fcf6485ce7c5Narayan Kamath            // In some configurations, we avoid preloading resources and classes eagerly.
7245a3d0c6e11d9eee40e8134c2efc8fcf6485ce7c5Narayan Kamath            // In such cases, we will preload things prior to our first fork.
7255a3d0c6e11d9eee40e8134c2efc8fcf6485ce7c5Narayan Kamath            if (!enableLazyPreload) {
7265a3d0c6e11d9eee40e8134c2efc8fcf6485ce7c5Narayan Kamath                bootTimingsTraceLog.traceBegin("ZygotePreload");
7275a3d0c6e11d9eee40e8134c2efc8fcf6485ce7c5Narayan Kamath                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
7285a3d0c6e11d9eee40e8134c2efc8fcf6485ce7c5Narayan Kamath                    SystemClock.uptimeMillis());
7295a3d0c6e11d9eee40e8134c2efc8fcf6485ce7c5Narayan Kamath                preload(bootTimingsTraceLog);
7305a3d0c6e11d9eee40e8134c2efc8fcf6485ce7c5Narayan Kamath                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
7315a3d0c6e11d9eee40e8134c2efc8fcf6485ce7c5Narayan Kamath                    SystemClock.uptimeMillis());
7325a3d0c6e11d9eee40e8134c2efc8fcf6485ce7c5Narayan Kamath                bootTimingsTraceLog.traceEnd(); // ZygotePreload
733b49996d8e2658ea2d62cd19d28edd70b2b22f605Narayan Kamath            } else {
7341e3db871e52e59c69edb1843df7f4aecb030bc6fHiroshi Yamauchi                Zygote.resetNicePriority();
7355a3d0c6e11d9eee40e8134c2efc8fcf6485ce7c5Narayan Kamath            }
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
73725878b288846831048e157271c635d31d1c7557bYasuhiro Matsuda            // Finish profiling the zygote initialization.
73825878b288846831048e157271c635d31d1c7557bYasuhiro Matsuda            SamplingProfilerIntegration.writeZygoteSnapshot();
739e540833fdff4d58e37c9ba859388e24e2945ed45Bob Lee
74025878b288846831048e157271c635d31d1c7557bYasuhiro Matsuda            // Do an initial gc to clean up after startup
7413235e0c2eeb9f1c3d7152ebc2738a2e784085d38Fyodor Kupolov            bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
74225878b288846831048e157271c635d31d1c7557bYasuhiro Matsuda            gcAndFinalize();
7433235e0c2eeb9f1c3d7152ebc2738a2e784085d38Fyodor Kupolov            bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC
74425878b288846831048e157271c635d31d1c7557bYasuhiro Matsuda
7453235e0c2eeb9f1c3d7152ebc2738a2e784085d38Fyodor Kupolov            bootTimingsTraceLog.traceEnd(); // ZygoteInit
7466ad0452e6301c0650f58f3991f7c523f6f279ddbJamie Gennis            // Disable tracing so that forked processes do not inherit stale tracing tags from
7476ad0452e6301c0650f58f3991f7c523f6f279ddbJamie Gennis            // Zygote.
7486ad0452e6301c0650f58f3991f7c523f6f279ddbJamie Gennis            Trace.setTracingEnabled(false);
7496ad0452e6301c0650f58f3991f7c523f6f279ddbJamie Gennis
750885b742bb66660947d8335e9a4f5a4eef2e45ff9doheon            // Zygote process unmounts root storage spaces.
751885b742bb66660947d8335e9a4f5a4eef2e45ff9doheon            Zygote.nativeUnmountStorageOnInit();
752885b742bb66660947d8335e9a4f5a4eef2e45ff9doheon
753ef854774704d61992f13b8c49b9d210bf33ef4a8Paul Lawrence            // Set seccomp policy
754ef854774704d61992f13b8c49b9d210bf33ef4a8Paul Lawrence            Seccomp.setPolicy();
755ef854774704d61992f13b8c49b9d210bf33ef4a8Paul Lawrence
7561ef8aef260c19236be023c429b41a46e7f5da8b0Andreas Gampe            ZygoteHooks.stopZygoteNoThreadCreation();
7571ef8aef260c19236be023c429b41a46e7f5da8b0Andreas Gampe
758c41638cb759ce569630ffae4c5c4cdee1b0f3b82Narayan Kamath            if (startSystemServer) {
759dd4bb31639047b27118d44b9a0609952fac6debfTobias Sargeant                startSystemServer(abiList, socketName, zygoteServer);
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.i(TAG, "Accepting command socket connections");
763dd4bb31639047b27118d44b9a0609952fac6debfTobias Sargeant            zygoteServer.runSelectLoop(abiList);
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
765dd4bb31639047b27118d44b9a0609952fac6debfTobias Sargeant            zygoteServer.closeServerSocket();
766dd4bb31639047b27118d44b9a0609952fac6debfTobias Sargeant        } catch (Zygote.MethodAndArgsCaller caller) {
7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            caller.run();
768ea8b5de33dc4aa446cd22fd0e4a9253216ac4086Christopher Ferris        } catch (Throwable ex) {
769dd4bb31639047b27118d44b9a0609952fac6debfTobias Sargeant            Log.e(TAG, "System zygote died with exception", ex);
770dd4bb31639047b27118d44b9a0609952fac6debfTobias Sargeant            zygoteServer.closeServerSocket();
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw ex;
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
77664cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath     * Return {@code true} if this device configuration has another zygote.
77764cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath     *
77864cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath     * We determine this by comparing the device ABI list with this zygotes
77964cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath     * list. If this zygote supports all ABIs this device supports, there won't
78064cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath     * be another zygote.
78164cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath     */
78264cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath    private static boolean hasSecondZygote(String abiList) {
78364cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath        return !SystemProperties.get("ro.product.cpu.abilist").equals(abiList);
78464cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath    }
78564cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath
78664cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath    private static void waitForSecondaryZygote(String socketName) {
78764cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath        String otherZygoteName = Process.ZYGOTE_SOCKET.equals(socketName) ?
78864cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath                Process.SECONDARY_ZYGOTE_SOCKET : Process.ZYGOTE_SOCKET;
78964cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath        while (true) {
79064cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath            try {
7918f8d187a78b48109911a800ba5993b645d3015c5Robert Sesek                final ZygoteProcess.ZygoteState zs =
7928f8d187a78b48109911a800ba5993b645d3015c5Robert Sesek                        ZygoteProcess.ZygoteState.connect(otherZygoteName);
79364cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath                zs.close();
79464cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath                break;
79564cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath            } catch (IOException ioe) {
79664cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath                Log.w(TAG, "Got error connecting to zygote, retrying. msg= " + ioe.getMessage());
79764cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath            }
79864cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath
79964cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath            try {
80064cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath                Thread.sleep(1000);
80164cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath            } catch (InterruptedException ie) {
80264cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath            }
80364cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath        }
80464cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath    }
80564cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath
806669afcc9d05606eeaf7ebe87f991e1bf1b583f9dNarayan Kamath    static boolean isPreloadComplete() {
807669afcc9d05606eeaf7ebe87f991e1bf1b583f9dNarayan Kamath        return sPreloadComplete;
808669afcc9d05606eeaf7ebe87f991e1bf1b583f9dNarayan Kamath    }
809669afcc9d05606eeaf7ebe87f991e1bf1b583f9dNarayan Kamath
81064cd907af99ce9702e8975a657ee437c2626f8b5Narayan Kamath    /**
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Class not instantiable.
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private ZygoteInit() {
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
81576d4fc84518b3560fc0e8d912a09c1eefefe85acAndreas Gampe
81676d4fc84518b3560fc0e8d912a09c1eefefe85acAndreas Gampe    /**
81776d4fc84518b3560fc0e8d912a09c1eefefe85acAndreas Gampe     * The main function called when started through the zygote process. This
81876d4fc84518b3560fc0e8d912a09c1eefefe85acAndreas Gampe     * could be unified with main(), if the native code in nativeFinishInit()
81976d4fc84518b3560fc0e8d912a09c1eefefe85acAndreas Gampe     * were rationalized with Zygote startup.<p>
82076d4fc84518b3560fc0e8d912a09c1eefefe85acAndreas Gampe     *
82176d4fc84518b3560fc0e8d912a09c1eefefe85acAndreas Gampe     * Current recognized args:
82276d4fc84518b3560fc0e8d912a09c1eefefe85acAndreas Gampe     * <ul>
82376d4fc84518b3560fc0e8d912a09c1eefefe85acAndreas Gampe     *   <li> <code> [--] &lt;start class name&gt;  &lt;args&gt;
82476d4fc84518b3560fc0e8d912a09c1eefefe85acAndreas Gampe     * </ul>
82576d4fc84518b3560fc0e8d912a09c1eefefe85acAndreas Gampe     *
82676d4fc84518b3560fc0e8d912a09c1eefefe85acAndreas Gampe     * @param targetSdkVersion target SDK version
82776d4fc84518b3560fc0e8d912a09c1eefefe85acAndreas Gampe     * @param argv arg strings
82876d4fc84518b3560fc0e8d912a09c1eefefe85acAndreas Gampe     */
82976d4fc84518b3560fc0e8d912a09c1eefefe85acAndreas Gampe    public static final void zygoteInit(int targetSdkVersion, String[] argv,
83076d4fc84518b3560fc0e8d912a09c1eefefe85acAndreas Gampe            ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
83176d4fc84518b3560fc0e8d912a09c1eefefe85acAndreas Gampe        if (RuntimeInit.DEBUG) {
83276d4fc84518b3560fc0e8d912a09c1eefefe85acAndreas Gampe            Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
83376d4fc84518b3560fc0e8d912a09c1eefefe85acAndreas Gampe        }
83476d4fc84518b3560fc0e8d912a09c1eefefe85acAndreas Gampe
83576d4fc84518b3560fc0e8d912a09c1eefefe85acAndreas Gampe        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
83676d4fc84518b3560fc0e8d912a09c1eefefe85acAndreas Gampe        RuntimeInit.redirectLogStreams();
83776d4fc84518b3560fc0e8d912a09c1eefefe85acAndreas Gampe
83876d4fc84518b3560fc0e8d912a09c1eefefe85acAndreas Gampe        RuntimeInit.commonInit();
83976d4fc84518b3560fc0e8d912a09c1eefefe85acAndreas Gampe        ZygoteInit.nativeZygoteInit();
84076d4fc84518b3560fc0e8d912a09c1eefefe85acAndreas Gampe        RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
84176d4fc84518b3560fc0e8d912a09c1eefefe85acAndreas Gampe    }
84276d4fc84518b3560fc0e8d912a09c1eefefe85acAndreas Gampe
84376d4fc84518b3560fc0e8d912a09c1eefefe85acAndreas Gampe    private static final native void nativeZygoteInit();
8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
845