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> [--] <start class name> <args> 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