blob: 6f5836531c271db288f936743645d0953e0234ca [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.internal.os;
18
Elliott Hughesa9569ff2014-04-28 20:53:52 -070019import static android.system.OsConstants.S_IRWXG;
20import static android.system.OsConstants.S_IRWXO;
Kenny Root4c74f8c2012-08-17 08:45:55 -070021
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022import android.content.res.Resources;
23import android.content.res.TypedArray;
Neil Fuller4f41f612016-05-09 16:55:36 +010024import android.icu.impl.CacheValue;
25import android.icu.text.DecimalFormatSymbols;
26import android.icu.util.ULocale;
Jesse Hallba0370e2017-02-09 14:43:14 -080027import android.opengl.EGL14;
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -070028import android.os.Build;
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -070029import android.os.Environment;
Mathew Inwood04194fe2018-04-04 14:48:03 +010030import android.os.IInstalld;
Jeff Brownebed7d62011-05-16 17:08:42 -070031import android.os.Process;
Jeff Sharkey740f5232016-12-09 14:31:26 -070032import android.os.RemoteException;
33import android.os.ServiceManager;
34import android.os.ServiceSpecificException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035import android.os.SystemClock;
Romain Guyc5e36382013-05-09 11:08:17 -070036import android.os.SystemProperties;
Jamie Gennis6ad04522013-04-15 18:53:24 -070037import android.os.Trace;
Robert Sesek8f8d1872016-03-18 16:52:57 -040038import android.os.ZygoteProcess;
Jeff Sharkeyc98c7bc2016-12-07 14:57:34 -070039import android.os.storage.StorageManager;
Sergio Giro69de3202016-05-17 16:52:33 +010040import android.security.keystore.AndroidKeyStoreProvider;
Bill Yi9a76e9b2014-04-29 18:52:48 -070041import android.system.ErrnoException;
Elliott Hughes860c5912014-04-28 19:19:13 -070042import android.system.Os;
43import android.system.OsConstants;
Luis Hector Chavez72042c92017-07-12 10:03:30 -070044import android.system.StructCapUserData;
45import android.system.StructCapUserHeader;
Raph Levienc3dd1c12015-04-06 10:37:57 -070046import android.text.Hyphenator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047import android.util.EventLog;
48import android.util.Log;
Andreas Gampe76d4fc82017-02-07 19:44:37 -080049import android.util.Slog;
Mathew Inwood04194fe2018-04-04 14:48:03 +010050import android.util.TimingsTraceLog;
Torne (Richard Coles)08cfaf62014-05-08 16:07:05 +010051import android.webkit.WebViewFactory;
Andreas Gampeddc13972016-02-26 16:54:59 -080052import android.widget.TextView;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -080054import com.android.internal.logging.MetricsLogger;
Narayan Kamath669afcc2017-02-06 20:24:08 +000055import com.android.internal.util.Preconditions;
Mathew Inwood04194fe2018-04-04 14:48:03 +010056
Narayan Kamath29564cd2014-08-07 10:57:40 +010057import dalvik.system.DexFile;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058import dalvik.system.VMRuntime;
Andreas Gampe1ef8aef2016-04-11 08:39:52 -070059import dalvik.system.ZygoteHooks;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060
Brian Carlstrom46703b02011-04-06 15:41:29 -070061import libcore.io.IoUtils;
62
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063import java.io.BufferedReader;
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -070064import java.io.File;
Ying Wangd0c45352014-11-13 15:22:47 -080065import java.io.FileInputStream;
66import java.io.FileNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067import java.io.IOException;
68import java.io.InputStream;
69import java.io.InputStreamReader;
Sergio Giro6cb7b1c2016-05-13 16:34:46 +010070import java.security.Provider;
Mathew Inwood04194fe2018-04-04 14:48:03 +010071import java.security.Security;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072
73/**
74 * Startup class for the zygote process.
75 *
76 * Pre-initializes some classes, and then waits for commands on a UNIX domain
Elliott Hughese1dfcb72011-07-08 11:08:07 -070077 * socket. Based on these commands, forks off child processes that inherit
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078 * the initial state of the VM.
79 *
80 * Please see {@link ZygoteConnection.Arguments} for documentation on the
81 * client protocol.
82 *
83 * @hide
84 */
85public class ZygoteInit {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086 private static final String TAG = "Zygote";
87
Jesse Hall2852a282017-01-17 10:17:41 -080088 private static final String PROPERTY_DISABLE_OPENGL_PRELOADING = "ro.zygote.disable_gl_preload";
Jesse Hallba0370e2017-02-09 14:43:14 -080089 private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
Romain Guyc5e36382013-05-09 11:08:17 -070090
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091 private static final int LOG_BOOT_PROGRESS_PRELOAD_START = 3020;
92 private static final int LOG_BOOT_PROGRESS_PRELOAD_END = 3030;
93
94 /** when preloading, GC after allocating this many bytes */
95 private static final int PRELOAD_GC_THRESHOLD = 50000;
96
Narayan Kamathc41638c2014-04-07 13:56:15 +010097 private static final String ABI_LIST_ARG = "--abi-list=";
98
99 private static final String SOCKET_NAME_ARG = "--socket-name=";
Barry Hayes0b3533a2010-01-20 12:46:47 -0800100
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101 /**
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000102 * Used to pre-load resources.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103 */
104 private static Resources mResources;
Bob Leee5408332009-09-04 18:31:17 -0700105
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106 /**
Ying Wangd0c45352014-11-13 15:22:47 -0800107 * The path of a file that contains classes to preload.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108 */
Ying Wangd0c45352014-11-13 15:22:47 -0800109 private static final String PRELOADED_CLASSES = "/system/etc/preloaded-classes";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110
111 /** Controls whether we should preload resources during zygote init. */
Steve Paik3c27a232015-06-10 18:25:44 -0700112 public static final boolean PRELOAD_RESOURCES = true;
Andy McFadden599c9182009-04-08 00:35:56 -0700113
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114 private static final int UNPRIVILEGED_UID = 9999;
115 private static final int UNPRIVILEGED_GID = 9999;
116
117 private static final int ROOT_UID = 0;
118 private static final int ROOT_GID = 0;
119
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000120 private static boolean sPreloadComplete;
121
Fyodor Kupolov6e3461b2017-08-10 17:00:43 -0700122 static void preload(TimingsTraceLog bootTimingsTraceLog) {
Bill Yi9a76e9b2014-04-29 18:52:48 -0700123 Log.d(TAG, "begin preload");
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800124 bootTimingsTraceLog.traceBegin("BeginIcuCachePinning");
Neil Fuller4f41f612016-05-09 16:55:36 +0100125 beginIcuCachePinning();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800126 bootTimingsTraceLog.traceEnd(); // BeginIcuCachePinning
127 bootTimingsTraceLog.traceBegin("PreloadClasses");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900128 preloadClasses();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800129 bootTimingsTraceLog.traceEnd(); // PreloadClasses
130 bootTimingsTraceLog.traceBegin("PreloadResources");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900131 preloadResources();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800132 bootTimingsTraceLog.traceEnd(); // PreloadResources
Jesse Hall1fe1dc02017-07-06 15:30:39 -0700133 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs");
134 nativePreloadAppProcessHALs();
135 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Jesse Hallba0370e2017-02-09 14:43:14 -0800136 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadOpenGL");
137 preloadOpenGL();
138 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Brian Carlstrom6c9af962014-09-11 15:36:00 -0700139 preloadSharedLibraries();
Raph Levienc3dd1c12015-04-06 10:37:57 -0700140 preloadTextResources();
Torne (Richard Coles)08cfaf62014-05-08 16:07:05 +0100141 // Ask the WebViewFactory to do any initialization that must run in the zygote process,
142 // for memory sharing purposes.
143 WebViewFactory.prepareWebViewInZygote();
Neil Fuller4f41f612016-05-09 16:55:36 +0100144 endIcuCachePinning();
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100145 warmUpJcaProviders();
Bill Yi9a76e9b2014-04-29 18:52:48 -0700146 Log.d(TAG, "end preload");
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000147
148 sPreloadComplete = true;
149 }
150
Narayan Kamath669afcc2017-02-06 20:24:08 +0000151 public static void lazyPreload() {
152 Preconditions.checkState(!sPreloadComplete);
153 Log.i(TAG, "Lazily preloading resources.");
154
Fyodor Kupolov6e3461b2017-08-10 17:00:43 -0700155 preload(new TimingsTraceLog("ZygoteInitTiming_lazy", Trace.TRACE_TAG_DALVIK));
Romain Guy74c69122013-05-08 17:54:20 -0700156 }
157
Neil Fuller4f41f612016-05-09 16:55:36 +0100158 private static void beginIcuCachePinning() {
159 // Pin ICU data in memory from this point that would normally be held by soft references.
160 // Without this, any references created immediately below or during class preloading
161 // would be collected when the Zygote GC runs in gcAndFinalize().
162 Log.i(TAG, "Installing ICU cache reference pinning...");
163
164 CacheValue.setStrength(CacheValue.Strength.STRONG);
165
166 Log.i(TAG, "Preloading ICU data...");
167 // Explicitly exercise code to cache data apps are likely to need.
168 ULocale[] localesToPin = { ULocale.ROOT, ULocale.US, ULocale.getDefault() };
169 for (ULocale uLocale : localesToPin) {
170 new DecimalFormatSymbols(uLocale);
171 }
172 }
173
174 private static void endIcuCachePinning() {
175 // All cache references created by ICU from this point will be soft.
176 CacheValue.setStrength(CacheValue.Strength.SOFT);
177
178 Log.i(TAG, "Uninstalled ICU cache reference pinning...");
179 }
180
Brian Carlstrom6c9af962014-09-11 15:36:00 -0700181 private static void preloadSharedLibraries() {
182 Log.i(TAG, "Preloading shared libraries...");
183 System.loadLibrary("android");
184 System.loadLibrary("compiler_rt");
185 System.loadLibrary("jnigraphics");
186 }
187
Jesse Hall1fe1dc02017-07-06 15:30:39 -0700188 native private static void nativePreloadAppProcessHALs();
189
Jesse Hallba0370e2017-02-09 14:43:14 -0800190 private static void preloadOpenGL() {
191 String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
Jesse Hall5d911fe2017-04-13 15:44:24 -0700192 if (!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING, false) &&
193 (driverPackageName == null || driverPackageName.isEmpty())) {
Jesse Hallba0370e2017-02-09 14:43:14 -0800194 EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
195 }
196 }
197
Raph Levienc3dd1c12015-04-06 10:37:57 -0700198 private static void preloadTextResources() {
199 Hyphenator.init();
Andreas Gampeddc13972016-02-26 16:54:59 -0800200 TextView.preloadFontCache();
Raph Levienc3dd1c12015-04-06 10:37:57 -0700201 }
202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800203 /**
Sergio Giro69de3202016-05-17 16:52:33 +0100204 * Register AndroidKeyStoreProvider and warm up the providers that are already registered.
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100205 *
206 * By doing it here we avoid that each app does it when requesting a service from the
207 * provider for the first time.
208 */
209 private static void warmUpJcaProviders() {
210 long startTime = SystemClock.uptimeMillis();
211 Trace.traceBegin(
Sergio Giro69de3202016-05-17 16:52:33 +0100212 Trace.TRACE_TAG_DALVIK, "Starting installation of AndroidKeyStoreProvider");
213 // AndroidKeyStoreProvider.install() manipulates the list of JCA providers to insert
214 // preferred providers. Note this is not done via security.properties as the JCA providers
215 // are not on the classpath in the case of, for example, raw dalvikvm runtimes.
216 AndroidKeyStoreProvider.install();
217 Log.i(TAG, "Installed AndroidKeyStoreProvider in "
218 + (SystemClock.uptimeMillis() - startTime) + "ms.");
219 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
220
221 startTime = SystemClock.uptimeMillis();
222 Trace.traceBegin(
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100223 Trace.TRACE_TAG_DALVIK, "Starting warm up of JCA providers");
224 for (Provider p : Security.getProviders()) {
225 p.warmUpServiceProvision();
226 }
227 Log.i(TAG, "Warmed up JCA providers in "
Sergio Giro69de3202016-05-17 16:52:33 +0100228 + (SystemClock.uptimeMillis() - startTime) + "ms.");
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100229 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
230 }
231
232 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800233 * Performs Zygote process initialization. Loads and initializes
234 * commonly used classes.
235 *
236 * Most classes only cause a few hundred bytes to be allocated, but
237 * a few will allocate a dozen Kbytes (in one case, 500+K).
238 */
239 private static void preloadClasses() {
240 final VMRuntime runtime = VMRuntime.getRuntime();
Bob Leee5408332009-09-04 18:31:17 -0700241
Ying Wangd0c45352014-11-13 15:22:47 -0800242 InputStream is;
243 try {
244 is = new FileInputStream(PRELOADED_CLASSES);
245 } catch (FileNotFoundException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800246 Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + ".");
Ying Wangd0c45352014-11-13 15:22:47 -0800247 return;
248 }
Bob Leee5408332009-09-04 18:31:17 -0700249
Ying Wangd0c45352014-11-13 15:22:47 -0800250 Log.i(TAG, "Preloading classes...");
251 long startTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800252
Ying Wangd0c45352014-11-13 15:22:47 -0800253 // Drop root perms while running static initializers.
Narayan Kamath23e68782015-01-16 17:22:41 +0000254 final int reuid = Os.getuid();
255 final int regid = Os.getgid();
256
257 // We need to drop root perms only if we're already root. In the case of "wrapped"
258 // processes (see WrapperInit), this function is called from an unprivileged uid
259 // and gid.
260 boolean droppedPriviliges = false;
261 if (reuid == ROOT_UID && regid == ROOT_GID) {
262 try {
263 Os.setregid(ROOT_GID, UNPRIVILEGED_GID);
264 Os.setreuid(ROOT_UID, UNPRIVILEGED_UID);
265 } catch (ErrnoException ex) {
266 throw new RuntimeException("Failed to drop root", ex);
267 }
268
269 droppedPriviliges = true;
Elliott Hughes26b56e62014-12-17 12:28:29 -0800270 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800271
Ying Wangd0c45352014-11-13 15:22:47 -0800272 // Alter the target heap utilization. With explicit GCs this
273 // is not likely to have any effect.
274 float defaultUtilization = runtime.getTargetHeapUtilization();
275 runtime.setTargetHeapUtilization(0.8f);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800276
Ying Wangd0c45352014-11-13 15:22:47 -0800277 try {
278 BufferedReader br
279 = new BufferedReader(new InputStreamReader(is), 256);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800280
Ying Wangd0c45352014-11-13 15:22:47 -0800281 int count = 0;
282 String line;
283 while ((line = br.readLine()) != null) {
284 // Skip comments and blank lines.
285 line = line.trim();
286 if (line.startsWith("#") || line.equals("")) {
287 continue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800288 }
289
Andreas Gampec4253622016-10-28 18:19:30 -0700290 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, line);
Ying Wangd0c45352014-11-13 15:22:47 -0800291 try {
292 if (false) {
293 Log.v(TAG, "Preloading " + line + "...");
294 }
Andreas Gampedd8e5fb2015-04-21 09:01:51 -0700295 // Load and explicitly initialize the given class. Use
296 // Class.forName(String, boolean, ClassLoader) to avoid repeated stack lookups
297 // (to derive the caller's class-loader). Use true to force initialization, and
298 // null for the boot classpath class-loader (could as well cache the
299 // class-loader of this class in a variable).
Andreas Gampec917f742015-04-20 19:16:37 -0700300 Class.forName(line, true, null);
Ying Wangd0c45352014-11-13 15:22:47 -0800301 count++;
302 } catch (ClassNotFoundException e) {
303 Log.w(TAG, "Class not found for preloading: " + line);
304 } catch (UnsatisfiedLinkError e) {
305 Log.w(TAG, "Problem preloading " + line + ": " + e);
306 } catch (Throwable t) {
307 Log.e(TAG, "Error preloading " + line + ".", t);
308 if (t instanceof Error) {
309 throw (Error) t;
310 }
311 if (t instanceof RuntimeException) {
312 throw (RuntimeException) t;
313 }
314 throw new RuntimeException(t);
315 }
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900316 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800317 }
Ying Wangd0c45352014-11-13 15:22:47 -0800318
319 Log.i(TAG, "...preloaded " + count + " classes in "
320 + (SystemClock.uptimeMillis()-startTime) + "ms.");
321 } catch (IOException e) {
322 Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);
323 } finally {
324 IoUtils.closeQuietly(is);
325 // Restore default.
326 runtime.setTargetHeapUtilization(defaultUtilization);
327
328 // Fill in dex caches with classes, fields, and methods brought in by preloading.
Yasuhiro Matsuda1ab43d52015-06-30 17:07:32 +0900329 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadDexCaches");
Ying Wangd0c45352014-11-13 15:22:47 -0800330 runtime.preloadDexCaches();
Yasuhiro Matsuda1ab43d52015-06-30 17:07:32 +0900331 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Ying Wangd0c45352014-11-13 15:22:47 -0800332
Narayan Kamath23e68782015-01-16 17:22:41 +0000333 // Bring back root. We'll need it later if we're in the zygote.
334 if (droppedPriviliges) {
335 try {
336 Os.setreuid(ROOT_UID, ROOT_UID);
337 Os.setregid(ROOT_GID, ROOT_GID);
338 } catch (ErrnoException ex) {
339 throw new RuntimeException("Failed to restore root", ex);
340 }
Elliott Hughes26b56e62014-12-17 12:28:29 -0800341 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800342 }
343 }
344
345 /**
346 * Load in commonly used resources, so they can be shared across
347 * processes.
348 *
349 * These tend to be a few Kbytes, but are frequently in the 20-40K
350 * range, and occasionally even larger.
351 */
352 private static void preloadResources() {
353 final VMRuntime runtime = VMRuntime.getRuntime();
Bob Leee5408332009-09-04 18:31:17 -0700354
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800355 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800356 mResources = Resources.getSystem();
357 mResources.startPreloading();
358 if (PRELOAD_RESOURCES) {
359 Log.i(TAG, "Preloading resources...");
360
361 long startTime = SystemClock.uptimeMillis();
362 TypedArray ar = mResources.obtainTypedArray(
363 com.android.internal.R.array.preloaded_drawables);
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800364 int N = preloadDrawables(ar);
Jeff Brown14577c42012-03-08 16:40:14 -0800365 ar.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800366 Log.i(TAG, "...preloaded " + N + " resources in "
367 + (SystemClock.uptimeMillis()-startTime) + "ms.");
368
369 startTime = SystemClock.uptimeMillis();
370 ar = mResources.obtainTypedArray(
371 com.android.internal.R.array.preloaded_color_state_lists);
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800372 N = preloadColorStateLists(ar);
Jeff Brown14577c42012-03-08 16:40:14 -0800373 ar.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800374 Log.i(TAG, "...preloaded " + N + " resources in "
375 + (SystemClock.uptimeMillis()-startTime) + "ms.");
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800376
377 if (mResources.getBoolean(
378 com.android.internal.R.bool.config_freeformWindowManagement)) {
379 startTime = SystemClock.uptimeMillis();
380 ar = mResources.obtainTypedArray(
381 com.android.internal.R.array.preloaded_freeform_multi_window_drawables);
382 N = preloadDrawables(ar);
383 ar.recycle();
384 Log.i(TAG, "...preloaded " + N + " resource in "
385 + (SystemClock.uptimeMillis() - startTime) + "ms.");
386 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800387 }
388 mResources.finishPreloading();
389 } catch (RuntimeException e) {
390 Log.w(TAG, "Failure preloading resources", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800391 }
392 }
393
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800394 private static int preloadColorStateLists(TypedArray ar) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395 int N = ar.length();
396 for (int i=0; i<N; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800397 int id = ar.getResourceId(i, 0);
Joe Onorato43a17652011-04-06 19:22:23 -0700398 if (false) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800399 Log.v(TAG, "Preloading resource #" + Integer.toHexString(id));
400 }
401 if (id != 0) {
Alan Viverette77bb6f12015-02-11 17:24:33 -0800402 if (mResources.getColorStateList(id, null) == null) {
Dianne Hackborndde331c2012-08-03 14:01:57 -0700403 throw new IllegalArgumentException(
404 "Unable to find preloaded color resource #0x"
405 + Integer.toHexString(id)
406 + " (" + ar.getString(i) + ")");
407 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800408 }
409 }
410 return N;
411 }
412
413
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800414 private static int preloadDrawables(TypedArray ar) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800415 int N = ar.length();
416 for (int i=0; i<N; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800417 int id = ar.getResourceId(i, 0);
Joe Onorato43a17652011-04-06 19:22:23 -0700418 if (false) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800419 Log.v(TAG, "Preloading resource #" + Integer.toHexString(id));
420 }
421 if (id != 0) {
Alan Viverette84e001a2014-09-22 00:04:22 -0700422 if (mResources.getDrawable(id, null) == null) {
Dianne Hackborndde331c2012-08-03 14:01:57 -0700423 throw new IllegalArgumentException(
424 "Unable to find preloaded drawable resource #0x"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800425 + Integer.toHexString(id)
Dianne Hackborndde331c2012-08-03 14:01:57 -0700426 + " (" + ar.getString(i) + ")");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800427 }
428 }
429 }
430 return N;
431 }
432
433 /**
434 * Runs several special GCs to try to clean up a few generations of
435 * softly- and final-reachable objects, along with any other garbage.
436 * This is only useful just before a fork().
437 */
Mathieu Chartier9a88f102014-08-20 10:24:11 -0700438 /*package*/ static void gcAndFinalize() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800439 final VMRuntime runtime = VMRuntime.getRuntime();
440
441 /* runFinalizationSync() lets finalizers be called in Zygote,
442 * which doesn't have a HeapWorker thread.
443 */
Brian Carlstrom08065b92011-04-01 15:49:41 -0700444 System.gc();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800445 runtime.runFinalizationSync();
Brian Carlstrom08065b92011-04-01 15:49:41 -0700446 System.gc();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800447 }
448
449 /**
450 * Finish remaining work for the newly forked system server process.
451 */
Narayan Kamathbf99d062017-07-05 14:45:38 +0100452 private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
Mike Lockwood90960e82010-08-06 09:15:25 -0400453 // set umask to 0077 so new files and directories will default to owner-only permissions.
Elliott Hughes860c5912014-04-28 19:19:13 -0700454 Os.umask(S_IRWXG | S_IRWXO);
Mike Lockwood90960e82010-08-06 09:15:25 -0400455
Jeff Brownebed7d62011-05-16 17:08:42 -0700456 if (parsedArgs.niceName != null) {
457 Process.setArgV0(parsedArgs.niceName);
458 }
459
Narayan Kamath29564cd2014-08-07 10:57:40 +0100460 final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
461 if (systemServerClasspath != null) {
462 performSystemServerDexOpt(systemServerClasspath);
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -0700463 // Capturing profiles is only supported for debug or eng builds since selinux normally
464 // prevents it.
465 boolean profileSystemServer = SystemProperties.getBoolean(
466 "dalvik.vm.profilesystemserver", false);
467 if (profileSystemServer && (Build.IS_USERDEBUG || Build.IS_ENG)) {
468 try {
469 File profileDir = Environment.getDataProfilesDePackageDirectory(
470 Process.SYSTEM_UID, "system_server");
471 File profile = new File(profileDir, "primary.prof");
472 profile.getParentFile().mkdirs();
473 profile.createNewFile();
474 String[] codePaths = systemServerClasspath.split(":");
475 VMRuntime.registerAppInfo(profile.getPath(), codePaths);
476 } catch (Exception e) {
477 Log.wtf(TAG, "Failed to set up system server profile", e);
478 }
479 }
Narayan Kamath29564cd2014-08-07 10:57:40 +0100480 }
481
Jeff Brownebed7d62011-05-16 17:08:42 -0700482 if (parsedArgs.invokeWith != null) {
Narayan Kamath29564cd2014-08-07 10:57:40 +0100483 String[] args = parsedArgs.remainingArgs;
484 // If we have a non-null system server class path, we'll have to duplicate the
485 // existing arguments and append the classpath to it. ART will handle the classpath
486 // correctly when we exec a new process.
487 if (systemServerClasspath != null) {
488 String[] amendedArgs = new String[args.length + 2];
489 amendedArgs[0] = "-cp";
490 amendedArgs[1] = systemServerClasspath;
tony.ys_liu34738172016-12-14 18:50:29 +0800491 System.arraycopy(args, 0, amendedArgs, 2, args.length);
492 args = amendedArgs;
Narayan Kamath29564cd2014-08-07 10:57:40 +0100493 }
494
Jeff Brownebed7d62011-05-16 17:08:42 -0700495 WrapperInit.execApplication(parsedArgs.invokeWith,
Elliott Hughese1dfcb72011-07-08 11:08:07 -0700496 parsedArgs.niceName, parsedArgs.targetSdkVersion,
Narayan Kamath37ad4b02015-01-19 16:05:24 +0000497 VMRuntime.getCurrentInstructionSet(), null, args);
Narayan Kamathbf99d062017-07-05 14:45:38 +0100498
499 throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
Jeff Brownebed7d62011-05-16 17:08:42 -0700500 } else {
Narayan Kamath29564cd2014-08-07 10:57:40 +0100501 ClassLoader cl = null;
502 if (systemServerClasspath != null) {
tony.ys_liu34738172016-12-14 18:50:29 +0800503 cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700504
Narayan Kamath29564cd2014-08-07 10:57:40 +0100505 Thread.currentThread().setContextClassLoader(cl);
506 }
507
Jeff Brownebed7d62011-05-16 17:08:42 -0700508 /*
509 * Pass the remaining arguments to SystemServer.
510 */
Narayan Kamathbf99d062017-07-05 14:45:38 +0100511 return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
Jeff Brownebed7d62011-05-16 17:08:42 -0700512 }
513
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800514 /* should never reach here */
515 }
516
Mathew Inwood8faeab82018-03-16 14:26:08 +0000517 public static void setApiBlacklistExemptions(String[] exemptions) {
518 VMRuntime.getRuntime().setHiddenApiExemptions(exemptions);
519 }
520
Mathew Inwood04194fe2018-04-04 14:48:03 +0100521 public static void setHiddenApiAccessLogSampleRate(int percent) {
522 VMRuntime.getRuntime().setHiddenApiAccessLogSamplingRate(percent);
523 }
524
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800525 /**
tony.ys_liu34738172016-12-14 18:50:29 +0800526 * Creates a PathClassLoader for the given class path that is associated with a shared
527 * namespace, i.e., this classloader can access platform-private native libraries. The
528 * classloader will use java.library.path as the native library path.
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700529 */
Narayan Kamathf9419f02017-06-15 11:35:38 +0100530 static ClassLoader createPathClassLoader(String classPath, int targetSdkVersion) {
531 String libraryPath = System.getProperty("java.library.path");
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700532
Narayan Kamathf9419f02017-06-15 11:35:38 +0100533 return ClassLoaderFactory.createClassLoader(classPath, libraryPath, libraryPath,
534 ClassLoader.getSystemClassLoader(), targetSdkVersion, true /* isNamespaceShared */,
535 null /* classLoaderName */);
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700536 }
537
538 /**
Narayan Kamath29564cd2014-08-07 10:57:40 +0100539 * Performs dex-opt on the elements of {@code classPath}, if needed. We
540 * choose the instruction set of the current runtime.
541 */
542 private static void performSystemServerDexOpt(String classPath) {
543 final String[] classPathElements = classPath.split(":");
Jeff Sharkey740f5232016-12-09 14:31:26 -0700544 final IInstalld installd = IInstalld.Stub
545 .asInterface(ServiceManager.getService("installd"));
Narayan Kamath29564cd2014-08-07 10:57:40 +0100546 final String instructionSet = VMRuntime.getRuntime().vmInstructionSet();
547
Calin Juravle2f09ff32017-07-24 15:29:56 -0700548 String classPathForElement = "";
Jeff Sharkey740f5232016-12-09 14:31:26 -0700549 for (String classPathElement : classPathElements) {
550 // System server is fully AOTed and never profiled
551 // for profile guided compilation.
Mathieu Chartier5e07a0d2017-06-15 19:09:38 -0700552 String systemServerFilter = SystemProperties.get(
553 "dalvik.vm.systemservercompilerfilter", "speed");
Andreas Gampee7bc1522016-08-09 20:44:04 -0700554
Jeff Sharkey740f5232016-12-09 14:31:26 -0700555 int dexoptNeeded;
556 try {
557 dexoptNeeded = DexFile.getDexOptNeeded(
Shubham Ajmera246dccf2017-05-24 17:46:36 -0700558 classPathElement, instructionSet, systemServerFilter,
Calin Juravle576e6c02017-09-12 00:58:33 -0700559 null /* classLoaderContext */, false /* newProfile */, false /* downgrade */);
Jeff Sharkey740f5232016-12-09 14:31:26 -0700560 } catch (FileNotFoundException ignored) {
561 // Do not add to the classpath.
562 Log.w(TAG, "Missing classpath element for system server: " + classPathElement);
563 continue;
564 } catch (IOException e) {
565 // Not fully clear what to do here as we don't know the cause of the
566 // IO exception. Add to the classpath to be conservative, but don't
567 // attempt to compile it.
568 Log.w(TAG, "Error checking classpath element for system server: "
569 + classPathElement, e);
570 dexoptNeeded = DexFile.NO_DEXOPT_NEEDED;
Narayan Kamath29564cd2014-08-07 10:57:40 +0100571 }
Jeff Sharkey740f5232016-12-09 14:31:26 -0700572
573 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
574 final String packageName = "*";
575 final String outputPath = null;
David Brazdilf7e31c02018-02-13 17:04:26 +0000576 final int dexFlags = 0;
Mathieu Chartier5e07a0d2017-06-15 19:09:38 -0700577 final String compilerFilter = systemServerFilter;
Jeff Sharkey740f5232016-12-09 14:31:26 -0700578 final String uuid = StorageManager.UUID_PRIVATE_INTERNAL;
Calin Juravle811a75a2017-04-05 22:49:38 -0700579 final String seInfo = null;
Calin Juravle2f09ff32017-07-24 15:29:56 -0700580 final String classLoaderContext =
581 getSystemServerClassLoaderContext(classPathForElement);
David Brazdil3d44ed02018-01-16 20:01:47 +0000582 final int targetSdkVersion = 0; // SystemServer targets the system's SDK version
Jeff Sharkey740f5232016-12-09 14:31:26 -0700583 try {
584 installd.dexopt(classPathElement, Process.SYSTEM_UID, packageName,
585 instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter,
David Brazdil3d44ed02018-01-16 20:01:47 +0000586 uuid, classLoaderContext, seInfo, false /* downgrade */,
Calin Juravle4bc8f4d2018-02-12 12:00:44 -0800587 targetSdkVersion, /*profileName*/ null, /*dexMetadataPath*/ null,
588 "server-dexopt");
Jeff Sharkey740f5232016-12-09 14:31:26 -0700589 } catch (RemoteException | ServiceSpecificException e) {
590 // Ignore (but log), we need this on the classpath for fallback mode.
591 Log.w(TAG, "Failed compiling classpath element for system server: "
592 + classPathElement, e);
593 }
594 }
595
Calin Juravle2f09ff32017-07-24 15:29:56 -0700596 classPathForElement = encodeSystemServerClassPath(
597 classPathForElement, classPathElement);
Narayan Kamath29564cd2014-08-07 10:57:40 +0100598 }
599 }
600
601 /**
Calin Juravle2f09ff32017-07-24 15:29:56 -0700602 * Encodes the system server class loader context in a format that is accepted by dexopt.
603 * This assumes the system server is always loaded with a {@link dalvik.system.PathClassLoader}.
604 *
605 * Note that ideally we would use the {@code DexoptUtils} to compute this. However we have no
606 * dependency here on the server so we hard code the logic again.
607 */
608 private static String getSystemServerClassLoaderContext(String classPath) {
609 return classPath == null ? "PCL[]" : "PCL[" + classPath + "]";
610 }
611
612 /**
613 * Encodes the class path in a format accepted by dexopt.
614 * @param classPath the old class path (may be empty).
615 * @param newElement the new class path elements
616 * @return the class path encoding resulted from appending {@code newElement} to
617 * {@code classPath}.
618 */
619 private static String encodeSystemServerClassPath(String classPath, String newElement) {
620 return (classPath == null || classPath.isEmpty())
621 ? newElement
622 : classPath + ":" + newElement;
623 }
624
625 /**
Narayan Kamathbf99d062017-07-05 14:45:38 +0100626 * Prepare the arguments and forks for the system server process.
627 *
628 * Returns an {@code Runnable} that provides an entrypoint into system_server code in the
629 * child process, and {@code null} in the parent.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800630 */
Narayan Kamathbf99d062017-07-05 14:45:38 +0100631 private static Runnable forkSystemServer(String abiList, String socketName,
632 ZygoteServer zygoteServer) {
Alex Klyubin48a06e72013-04-19 10:01:42 -0700633 long capabilities = posixCapabilitiesAsBits(
Philip Cuadra7bd0fdd2016-04-28 15:26:49 -0700634 OsConstants.CAP_IPC_LOCK,
Alex Klyubin48a06e72013-04-19 10:01:42 -0700635 OsConstants.CAP_KILL,
636 OsConstants.CAP_NET_ADMIN,
637 OsConstants.CAP_NET_BIND_SERVICE,
638 OsConstants.CAP_NET_BROADCAST,
639 OsConstants.CAP_NET_RAW,
Alex Klyubin48a06e72013-04-19 10:01:42 -0700640 OsConstants.CAP_SYS_MODULE,
641 OsConstants.CAP_SYS_NICE,
Nick Kralevich3082eb72017-02-15 15:12:31 -0800642 OsConstants.CAP_SYS_PTRACE,
Alex Klyubin48a06e72013-04-19 10:01:42 -0700643 OsConstants.CAP_SYS_TIME,
John Stultz5733f382016-07-28 12:35:31 -0700644 OsConstants.CAP_SYS_TTY_CONFIG,
Luis Hector Chavez72042c92017-07-12 10:03:30 -0700645 OsConstants.CAP_WAKE_ALARM,
646 OsConstants.CAP_BLOCK_SUSPEND
Alex Klyubin48a06e72013-04-19 10:01:42 -0700647 );
Luis Hector Chavez72042c92017-07-12 10:03:30 -0700648 /* Containers run without some capabilities, so drop any caps that are not available. */
649 StructCapUserHeader header = new StructCapUserHeader(
650 OsConstants._LINUX_CAPABILITY_VERSION_3, 0);
651 StructCapUserData[] data;
652 try {
653 data = Os.capget(header);
654 } catch (ErrnoException ex) {
655 throw new RuntimeException("Failed to capget()", ex);
Luis Hector Chavez5dd239a2015-10-06 14:01:45 -0700656 }
Luis Hector Chavez72042c92017-07-12 10:03:30 -0700657 capabilities &= ((long) data[0].effective) | (((long) data[1].effective) << 32);
658
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800659 /* Hardcoded command line to start the system server */
660 String args[] = {
661 "--setuid=1000",
662 "--setgid=1000",
Jerry Zhang6d319b82017-12-06 16:03:57 -0800663 "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1024,1032,1065,3001,3002,3003,3006,3007,3009,3010",
Alex Klyubin48a06e72013-04-19 10:01:42 -0700664 "--capabilities=" + capabilities + "," + capabilities,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800665 "--nice-name=system_server",
Narayan Kamathb6b044a2015-02-13 17:31:25 +0000666 "--runtime-args",
Jeff Sharkey27e4b742018-02-16 17:25:14 -0700667 "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800668 "com.android.server.SystemServer",
669 };
670 ZygoteConnection.Arguments parsedArgs = null;
671
672 int pid;
673
674 try {
675 parsedArgs = new ZygoteConnection.Arguments(args);
Jeff Brownebed7d62011-05-16 17:08:42 -0700676 ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
677 ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800678
679 /* Request to fork the system server process */
680 pid = Zygote.forkSystemServer(
681 parsedArgs.uid, parsedArgs.gid,
Elliott Hughese1dfcb72011-07-08 11:08:07 -0700682 parsedArgs.gids,
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100683 parsedArgs.runtimeFlags,
Elliott Hughese1dfcb72011-07-08 11:08:07 -0700684 null,
Andy McFadden1b4c7962010-10-27 11:26:05 -0700685 parsedArgs.permittedCapabilities,
686 parsedArgs.effectiveCapabilities);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800687 } catch (IllegalArgumentException ex) {
688 throw new RuntimeException(ex);
Bob Leee5408332009-09-04 18:31:17 -0700689 }
690
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800691 /* For child process */
692 if (pid == 0) {
Narayan Kamath64cd9072014-05-13 13:35:14 +0100693 if (hasSecondZygote(abiList)) {
694 waitForSecondaryZygote(socketName);
695 }
696
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000697 zygoteServer.closeServerSocket();
Narayan Kamathbf99d062017-07-05 14:45:38 +0100698 return handleSystemServerProcess(parsedArgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800699 }
700
Narayan Kamathbf99d062017-07-05 14:45:38 +0100701 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800702 }
703
Alex Klyubin48a06e72013-04-19 10:01:42 -0700704 /**
705 * Gets the bit array representation of the provided list of POSIX capabilities.
706 */
707 private static long posixCapabilitiesAsBits(int... capabilities) {
708 long result = 0;
709 for (int capability : capabilities) {
710 if ((capability < 0) || (capability > OsConstants.CAP_LAST_CAP)) {
711 throw new IllegalArgumentException(String.valueOf(capability));
712 }
713 result |= (1L << capability);
714 }
715 return result;
716 }
717
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800718 public static void main(String argv[]) {
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000719 ZygoteServer zygoteServer = new ZygoteServer();
720
Andreas Gampe1ef8aef2016-04-11 08:39:52 -0700721 // Mark zygote start. This ensures that thread creation will throw
722 // an error.
723 ZygoteHooks.startZygoteNoThreadCreation();
724
Robert Seseke4f8d692016-09-13 19:13:01 -0400725 // Zygote goes into its own process group.
726 try {
727 Os.setpgid(0, 0);
728 } catch (ErrnoException ex) {
729 throw new RuntimeException("Failed to setpgid(0,0)", ex);
730 }
731
Narayan Kamathbf99d062017-07-05 14:45:38 +0100732 final Runnable caller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800733 try {
Fyodor Kupolov6733e6c2017-01-06 18:27:05 -0800734 // Report Zygote start time to tron unless it is a runtime restart
735 if (!"1".equals(SystemProperties.get("sys.boot_completed"))) {
736 MetricsLogger.histogram(null, "boot_zygote_init",
737 (int) SystemClock.elapsedRealtime());
738 }
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800739
740 String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
Fyodor Kupolov6e3461b2017-08-10 17:00:43 -0700741 TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag,
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800742 Trace.TRACE_TAG_DALVIK);
743 bootTimingsTraceLog.traceBegin("ZygoteInit");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900744 RuntimeInit.enableDdms();
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900745
Narayan Kamathc41638c2014-04-07 13:56:15 +0100746 boolean startSystemServer = false;
747 String socketName = "zygote";
748 String abiList = null;
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000749 boolean enableLazyPreload = false;
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900750 for (int i = 1; i < argv.length; i++) {
751 if ("start-system-server".equals(argv[i])) {
752 startSystemServer = true;
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000753 } else if ("--enable-lazy-preload".equals(argv[i])) {
754 enableLazyPreload = true;
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900755 } else if (argv[i].startsWith(ABI_LIST_ARG)) {
756 abiList = argv[i].substring(ABI_LIST_ARG.length());
757 } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
758 socketName = argv[i].substring(SOCKET_NAME_ARG.length());
759 } else {
760 throw new RuntimeException("Unknown command line argument: " + argv[i]);
Narayan Kamathc41638c2014-04-07 13:56:15 +0100761 }
762 }
763
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900764 if (abiList == null) {
765 throw new RuntimeException("No ABI list supplied.");
766 }
767
Robert Sesekd0a190df2018-02-12 18:46:01 -0500768 zygoteServer.registerServerSocketFromEnv(socketName);
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000769 // In some configurations, we avoid preloading resources and classes eagerly.
770 // In such cases, we will preload things prior to our first fork.
771 if (!enableLazyPreload) {
772 bootTimingsTraceLog.traceBegin("ZygotePreload");
773 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
774 SystemClock.uptimeMillis());
775 preload(bootTimingsTraceLog);
776 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
777 SystemClock.uptimeMillis());
778 bootTimingsTraceLog.traceEnd(); // ZygotePreload
Narayan Kamathb49996d2017-02-06 20:24:08 +0000779 } else {
Hiroshi Yamauchi1e3db872017-03-02 13:39:07 -0800780 Zygote.resetNicePriority();
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000781 }
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900782
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900783 // Do an initial gc to clean up after startup
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800784 bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900785 gcAndFinalize();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800786 bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900787
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800788 bootTimingsTraceLog.traceEnd(); // ZygoteInit
Jamie Gennis6ad04522013-04-15 18:53:24 -0700789 // Disable tracing so that forked processes do not inherit stale tracing tags from
790 // Zygote.
John Reck62cc1192017-05-12 15:39:51 -0700791 Trace.setTracingEnabled(false, 0);
Jamie Gennis6ad04522013-04-15 18:53:24 -0700792
Victor Hsiehc8176ef2018-01-08 12:43:00 -0800793 Zygote.nativeSecurityInit();
794
doheon1.lee885b7422016-01-20 13:07:27 +0900795 // Zygote process unmounts root storage spaces.
796 Zygote.nativeUnmountStorageOnInit();
797
Andreas Gampe1ef8aef2016-04-11 08:39:52 -0700798 ZygoteHooks.stopZygoteNoThreadCreation();
799
Narayan Kamathc41638c2014-04-07 13:56:15 +0100800 if (startSystemServer) {
Narayan Kamathbf99d062017-07-05 14:45:38 +0100801 Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
802
803 // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
804 // child (system_server) process.
805 if (r != null) {
806 r.run();
807 return;
808 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800809 }
810
811 Log.i(TAG, "Accepting command socket connections");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800812
Narayan Kamathbf99d062017-07-05 14:45:38 +0100813 // The select loop returns early in the child process after a fork and
814 // loops forever in the zygote.
815 caller = zygoteServer.runSelectLoop(abiList);
Christopher Ferrisea8b5de2016-06-17 15:29:58 -0700816 } catch (Throwable ex) {
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000817 Log.e(TAG, "System zygote died with exception", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800818 throw ex;
Narayan Kamathbf99d062017-07-05 14:45:38 +0100819 } finally {
820 zygoteServer.closeServerSocket();
821 }
822
823 // We're in the child process and have exited the select loop. Proceed to execute the
824 // command.
825 if (caller != null) {
826 caller.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800827 }
828 }
829
830 /**
Narayan Kamath64cd9072014-05-13 13:35:14 +0100831 * Return {@code true} if this device configuration has another zygote.
832 *
833 * We determine this by comparing the device ABI list with this zygotes
834 * list. If this zygote supports all ABIs this device supports, there won't
835 * be another zygote.
836 */
837 private static boolean hasSecondZygote(String abiList) {
838 return !SystemProperties.get("ro.product.cpu.abilist").equals(abiList);
839 }
840
841 private static void waitForSecondaryZygote(String socketName) {
842 String otherZygoteName = Process.ZYGOTE_SOCKET.equals(socketName) ?
843 Process.SECONDARY_ZYGOTE_SOCKET : Process.ZYGOTE_SOCKET;
Gustav Senntonf0c52b52017-04-27 17:00:50 +0100844 ZygoteProcess.waitForConnectionToZygote(otherZygoteName);
Narayan Kamath64cd9072014-05-13 13:35:14 +0100845 }
846
Narayan Kamath669afcc2017-02-06 20:24:08 +0000847 static boolean isPreloadComplete() {
848 return sPreloadComplete;
849 }
850
Narayan Kamath64cd9072014-05-13 13:35:14 +0100851 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800852 * Class not instantiable.
853 */
854 private ZygoteInit() {
855 }
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800856
857 /**
858 * The main function called when started through the zygote process. This
859 * could be unified with main(), if the native code in nativeFinishInit()
860 * were rationalized with Zygote startup.<p>
861 *
862 * Current recognized args:
863 * <ul>
864 * <li> <code> [--] &lt;start class name&gt; &lt;args&gt;
865 * </ul>
866 *
867 * @param targetSdkVersion target SDK version
868 * @param argv arg strings
869 */
Narayan Kamathbf99d062017-07-05 14:45:38 +0100870 public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800871 if (RuntimeInit.DEBUG) {
872 Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
873 }
874
875 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
876 RuntimeInit.redirectLogStreams();
877
878 RuntimeInit.commonInit();
879 ZygoteInit.nativeZygoteInit();
Narayan Kamathbf99d062017-07-05 14:45:38 +0100880 return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800881 }
882
Robert Sesekd0a190df2018-02-12 18:46:01 -0500883 /**
884 * The main function called when starting a child zygote process. This is used as an
885 * alternative to zygoteInit(), which skips calling into initialization routines that
886 * start the Binder threadpool.
887 */
888 static final Runnable childZygoteInit(
889 int targetSdkVersion, String[] argv, ClassLoader classLoader) {
890 RuntimeInit.Arguments args = new RuntimeInit.Arguments(argv);
891 return RuntimeInit.findStaticMain(args.startClass, args.startArgs, classLoader);
892 }
893
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800894 private static final native void nativeZygoteInit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800895}