blob: 3cda820eb27679ca01247b4a78bf6d12874ffb4d [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;
Jeff Sharkey740f5232016-12-09 14:31:26 -070029import android.os.IInstalld;
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -070030import android.os.Environment;
Jeff Brownebed7d62011-05-16 17:08:42 -070031import android.os.Process;
Jeff Sharkey740f5232016-12-09 14:31:26 -070032import android.os.RemoteException;
Paul Lawrenceef854772017-01-31 09:54:31 -080033import android.os.Seccomp;
Jeff Sharkey740f5232016-12-09 14:31:26 -070034import android.os.ServiceManager;
35import android.os.ServiceSpecificException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036import android.os.SystemClock;
Romain Guyc5e36382013-05-09 11:08:17 -070037import android.os.SystemProperties;
Jamie Gennis6ad04522013-04-15 18:53:24 -070038import android.os.Trace;
Robert Sesek8f8d1872016-03-18 16:52:57 -040039import android.os.ZygoteProcess;
Jeff Sharkeyc98c7bc2016-12-07 14:57:34 -070040import android.os.storage.StorageManager;
Sergio Giro69de3202016-05-17 16:52:33 +010041import android.security.keystore.AndroidKeyStoreProvider;
Bill Yi9a76e9b2014-04-29 18:52:48 -070042import android.system.ErrnoException;
Elliott Hughes860c5912014-04-28 19:19:13 -070043import android.system.Os;
44import android.system.OsConstants;
Luis Hector Chavez72042c92017-07-12 10:03:30 -070045import android.system.StructCapUserData;
46import android.system.StructCapUserHeader;
Raph Levienc3dd1c12015-04-06 10:37:57 -070047import android.text.Hyphenator;
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -080048import android.util.BootTimingsTraceLog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049import android.util.EventLog;
50import android.util.Log;
Andreas Gampe76d4fc82017-02-07 19:44:37 -080051import android.util.Slog;
Torne (Richard Coles)08cfaf62014-05-08 16:07:05 +010052import android.webkit.WebViewFactory;
Andreas Gampeddc13972016-02-26 16:54:59 -080053import android.widget.TextView;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -080055import com.android.internal.logging.MetricsLogger;
Jeff Sharkeyfdeeeea2016-01-11 17:34:24 -070056
Narayan Kamath669afcc2017-02-06 20:24:08 +000057import com.android.internal.util.Preconditions;
Narayan Kamath29564cd2014-08-07 10:57:40 +010058import dalvik.system.DexFile;
59import dalvik.system.PathClassLoader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060import dalvik.system.VMRuntime;
Andreas Gampe1ef8aef2016-04-11 08:39:52 -070061import dalvik.system.ZygoteHooks;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062
Brian Carlstrom46703b02011-04-06 15:41:29 -070063import libcore.io.IoUtils;
64
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065import java.io.BufferedReader;
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -070066import java.io.File;
Ying Wangd0c45352014-11-13 15:22:47 -080067import java.io.FileInputStream;
68import java.io.FileNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069import java.io.IOException;
70import java.io.InputStream;
71import java.io.InputStreamReader;
Sergio Giro6cb7b1c2016-05-13 16:34:46 +010072import java.security.Security;
73import java.security.Provider;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074
75/**
76 * Startup class for the zygote process.
77 *
78 * Pre-initializes some classes, and then waits for commands on a UNIX domain
Elliott Hughese1dfcb72011-07-08 11:08:07 -070079 * socket. Based on these commands, forks off child processes that inherit
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080 * the initial state of the VM.
81 *
82 * Please see {@link ZygoteConnection.Arguments} for documentation on the
83 * client protocol.
84 *
85 * @hide
86 */
87public class ZygoteInit {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088 private static final String TAG = "Zygote";
89
Jesse Hall2852a282017-01-17 10:17:41 -080090 private static final String PROPERTY_DISABLE_OPENGL_PRELOADING = "ro.zygote.disable_gl_preload";
Jesse Hallba0370e2017-02-09 14:43:14 -080091 private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
Romain Guyc5e36382013-05-09 11:08:17 -070092
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093 private static final int LOG_BOOT_PROGRESS_PRELOAD_START = 3020;
94 private static final int LOG_BOOT_PROGRESS_PRELOAD_END = 3030;
95
96 /** when preloading, GC after allocating this many bytes */
97 private static final int PRELOAD_GC_THRESHOLD = 50000;
98
Narayan Kamathc41638c2014-04-07 13:56:15 +010099 private static final String ABI_LIST_ARG = "--abi-list=";
100
101 private static final String SOCKET_NAME_ARG = "--socket-name=";
Barry Hayes0b3533a2010-01-20 12:46:47 -0800102
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103 /**
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000104 * Used to pre-load resources.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105 */
106 private static Resources mResources;
Bob Leee5408332009-09-04 18:31:17 -0700107
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108 /**
Ying Wangd0c45352014-11-13 15:22:47 -0800109 * The path of a file that contains classes to preload.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110 */
Ying Wangd0c45352014-11-13 15:22:47 -0800111 private static final String PRELOADED_CLASSES = "/system/etc/preloaded-classes";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112
113 /** Controls whether we should preload resources during zygote init. */
Steve Paik3c27a232015-06-10 18:25:44 -0700114 public static final boolean PRELOAD_RESOURCES = true;
Andy McFadden599c9182009-04-08 00:35:56 -0700115
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116 private static final int UNPRIVILEGED_UID = 9999;
117 private static final int UNPRIVILEGED_GID = 9999;
118
119 private static final int ROOT_UID = 0;
120 private static final int ROOT_GID = 0;
121
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000122 private static boolean sPreloadComplete;
123
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800124 static void preload(BootTimingsTraceLog bootTimingsTraceLog) {
Bill Yi9a76e9b2014-04-29 18:52:48 -0700125 Log.d(TAG, "begin preload");
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800126 bootTimingsTraceLog.traceBegin("BeginIcuCachePinning");
Neil Fuller4f41f612016-05-09 16:55:36 +0100127 beginIcuCachePinning();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800128 bootTimingsTraceLog.traceEnd(); // BeginIcuCachePinning
129 bootTimingsTraceLog.traceBegin("PreloadClasses");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900130 preloadClasses();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800131 bootTimingsTraceLog.traceEnd(); // PreloadClasses
132 bootTimingsTraceLog.traceBegin("PreloadResources");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900133 preloadResources();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800134 bootTimingsTraceLog.traceEnd(); // PreloadResources
Jesse Hall42cf26e2017-07-06 15:30:39 -0700135 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs");
136 nativePreloadAppProcessHALs();
137 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Jesse Hallba0370e2017-02-09 14:43:14 -0800138 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadOpenGL");
139 preloadOpenGL();
140 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Brian Carlstrom6c9af962014-09-11 15:36:00 -0700141 preloadSharedLibraries();
Raph Levienc3dd1c12015-04-06 10:37:57 -0700142 preloadTextResources();
Torne (Richard Coles)08cfaf62014-05-08 16:07:05 +0100143 // Ask the WebViewFactory to do any initialization that must run in the zygote process,
144 // for memory sharing purposes.
145 WebViewFactory.prepareWebViewInZygote();
Neil Fuller4f41f612016-05-09 16:55:36 +0100146 endIcuCachePinning();
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100147 warmUpJcaProviders();
Bill Yi9a76e9b2014-04-29 18:52:48 -0700148 Log.d(TAG, "end preload");
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000149
150 sPreloadComplete = true;
151 }
152
Narayan Kamath669afcc2017-02-06 20:24:08 +0000153 public static void lazyPreload() {
154 Preconditions.checkState(!sPreloadComplete);
155 Log.i(TAG, "Lazily preloading resources.");
156
157 preload(new BootTimingsTraceLog("ZygoteInitTiming_lazy", Trace.TRACE_TAG_DALVIK));
Romain Guy74c69122013-05-08 17:54:20 -0700158 }
159
Neil Fuller4f41f612016-05-09 16:55:36 +0100160 private static void beginIcuCachePinning() {
161 // Pin ICU data in memory from this point that would normally be held by soft references.
162 // Without this, any references created immediately below or during class preloading
163 // would be collected when the Zygote GC runs in gcAndFinalize().
164 Log.i(TAG, "Installing ICU cache reference pinning...");
165
166 CacheValue.setStrength(CacheValue.Strength.STRONG);
167
168 Log.i(TAG, "Preloading ICU data...");
169 // Explicitly exercise code to cache data apps are likely to need.
170 ULocale[] localesToPin = { ULocale.ROOT, ULocale.US, ULocale.getDefault() };
171 for (ULocale uLocale : localesToPin) {
172 new DecimalFormatSymbols(uLocale);
173 }
174 }
175
176 private static void endIcuCachePinning() {
177 // All cache references created by ICU from this point will be soft.
178 CacheValue.setStrength(CacheValue.Strength.SOFT);
179
180 Log.i(TAG, "Uninstalled ICU cache reference pinning...");
181 }
182
Brian Carlstrom6c9af962014-09-11 15:36:00 -0700183 private static void preloadSharedLibraries() {
184 Log.i(TAG, "Preloading shared libraries...");
185 System.loadLibrary("android");
186 System.loadLibrary("compiler_rt");
187 System.loadLibrary("jnigraphics");
188 }
189
Jesse Hall42cf26e2017-07-06 15:30:39 -0700190 native private static void nativePreloadAppProcessHALs();
191
Jesse Hallba0370e2017-02-09 14:43:14 -0800192 private static void preloadOpenGL() {
193 String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
Jesse Hall5d911fe2017-04-13 15:44:24 -0700194 if (!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING, false) &&
195 (driverPackageName == null || driverPackageName.isEmpty())) {
Jesse Hallba0370e2017-02-09 14:43:14 -0800196 EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
197 }
198 }
199
Raph Levienc3dd1c12015-04-06 10:37:57 -0700200 private static void preloadTextResources() {
201 Hyphenator.init();
Andreas Gampeddc13972016-02-26 16:54:59 -0800202 TextView.preloadFontCache();
Raph Levienc3dd1c12015-04-06 10:37:57 -0700203 }
204
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800205 /**
Sergio Giro69de3202016-05-17 16:52:33 +0100206 * Register AndroidKeyStoreProvider and warm up the providers that are already registered.
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100207 *
208 * By doing it here we avoid that each app does it when requesting a service from the
209 * provider for the first time.
210 */
211 private static void warmUpJcaProviders() {
212 long startTime = SystemClock.uptimeMillis();
213 Trace.traceBegin(
Sergio Giro69de3202016-05-17 16:52:33 +0100214 Trace.TRACE_TAG_DALVIK, "Starting installation of AndroidKeyStoreProvider");
215 // AndroidKeyStoreProvider.install() manipulates the list of JCA providers to insert
216 // preferred providers. Note this is not done via security.properties as the JCA providers
217 // are not on the classpath in the case of, for example, raw dalvikvm runtimes.
218 AndroidKeyStoreProvider.install();
219 Log.i(TAG, "Installed AndroidKeyStoreProvider in "
220 + (SystemClock.uptimeMillis() - startTime) + "ms.");
221 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
222
223 startTime = SystemClock.uptimeMillis();
224 Trace.traceBegin(
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100225 Trace.TRACE_TAG_DALVIK, "Starting warm up of JCA providers");
226 for (Provider p : Security.getProviders()) {
227 p.warmUpServiceProvision();
228 }
229 Log.i(TAG, "Warmed up JCA providers in "
Sergio Giro69de3202016-05-17 16:52:33 +0100230 + (SystemClock.uptimeMillis() - startTime) + "ms.");
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100231 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
232 }
233
234 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800235 * Performs Zygote process initialization. Loads and initializes
236 * commonly used classes.
237 *
238 * Most classes only cause a few hundred bytes to be allocated, but
239 * a few will allocate a dozen Kbytes (in one case, 500+K).
240 */
241 private static void preloadClasses() {
242 final VMRuntime runtime = VMRuntime.getRuntime();
Bob Leee5408332009-09-04 18:31:17 -0700243
Ying Wangd0c45352014-11-13 15:22:47 -0800244 InputStream is;
245 try {
246 is = new FileInputStream(PRELOADED_CLASSES);
247 } catch (FileNotFoundException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800248 Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + ".");
Ying Wangd0c45352014-11-13 15:22:47 -0800249 return;
250 }
Bob Leee5408332009-09-04 18:31:17 -0700251
Ying Wangd0c45352014-11-13 15:22:47 -0800252 Log.i(TAG, "Preloading classes...");
253 long startTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800254
Ying Wangd0c45352014-11-13 15:22:47 -0800255 // Drop root perms while running static initializers.
Narayan Kamath23e68782015-01-16 17:22:41 +0000256 final int reuid = Os.getuid();
257 final int regid = Os.getgid();
258
259 // We need to drop root perms only if we're already root. In the case of "wrapped"
260 // processes (see WrapperInit), this function is called from an unprivileged uid
261 // and gid.
262 boolean droppedPriviliges = false;
263 if (reuid == ROOT_UID && regid == ROOT_GID) {
264 try {
265 Os.setregid(ROOT_GID, UNPRIVILEGED_GID);
266 Os.setreuid(ROOT_UID, UNPRIVILEGED_UID);
267 } catch (ErrnoException ex) {
268 throw new RuntimeException("Failed to drop root", ex);
269 }
270
271 droppedPriviliges = true;
Elliott Hughes26b56e62014-12-17 12:28:29 -0800272 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800273
Ying Wangd0c45352014-11-13 15:22:47 -0800274 // Alter the target heap utilization. With explicit GCs this
275 // is not likely to have any effect.
276 float defaultUtilization = runtime.getTargetHeapUtilization();
277 runtime.setTargetHeapUtilization(0.8f);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800278
Ying Wangd0c45352014-11-13 15:22:47 -0800279 try {
280 BufferedReader br
281 = new BufferedReader(new InputStreamReader(is), 256);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800282
Ying Wangd0c45352014-11-13 15:22:47 -0800283 int count = 0;
284 String line;
285 while ((line = br.readLine()) != null) {
286 // Skip comments and blank lines.
287 line = line.trim();
288 if (line.startsWith("#") || line.equals("")) {
289 continue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800290 }
291
Andreas Gampec4253622016-10-28 18:19:30 -0700292 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, line);
Ying Wangd0c45352014-11-13 15:22:47 -0800293 try {
294 if (false) {
295 Log.v(TAG, "Preloading " + line + "...");
296 }
Andreas Gampedd8e5fb2015-04-21 09:01:51 -0700297 // Load and explicitly initialize the given class. Use
298 // Class.forName(String, boolean, ClassLoader) to avoid repeated stack lookups
299 // (to derive the caller's class-loader). Use true to force initialization, and
300 // null for the boot classpath class-loader (could as well cache the
301 // class-loader of this class in a variable).
Andreas Gampec917f742015-04-20 19:16:37 -0700302 Class.forName(line, true, null);
Ying Wangd0c45352014-11-13 15:22:47 -0800303 count++;
304 } catch (ClassNotFoundException e) {
305 Log.w(TAG, "Class not found for preloading: " + line);
306 } catch (UnsatisfiedLinkError e) {
307 Log.w(TAG, "Problem preloading " + line + ": " + e);
308 } catch (Throwable t) {
309 Log.e(TAG, "Error preloading " + line + ".", t);
310 if (t instanceof Error) {
311 throw (Error) t;
312 }
313 if (t instanceof RuntimeException) {
314 throw (RuntimeException) t;
315 }
316 throw new RuntimeException(t);
317 }
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900318 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800319 }
Ying Wangd0c45352014-11-13 15:22:47 -0800320
321 Log.i(TAG, "...preloaded " + count + " classes in "
322 + (SystemClock.uptimeMillis()-startTime) + "ms.");
323 } catch (IOException e) {
324 Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);
325 } finally {
326 IoUtils.closeQuietly(is);
327 // Restore default.
328 runtime.setTargetHeapUtilization(defaultUtilization);
329
330 // Fill in dex caches with classes, fields, and methods brought in by preloading.
Yasuhiro Matsuda1ab43d52015-06-30 17:07:32 +0900331 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadDexCaches");
Ying Wangd0c45352014-11-13 15:22:47 -0800332 runtime.preloadDexCaches();
Yasuhiro Matsuda1ab43d52015-06-30 17:07:32 +0900333 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Ying Wangd0c45352014-11-13 15:22:47 -0800334
Narayan Kamath23e68782015-01-16 17:22:41 +0000335 // Bring back root. We'll need it later if we're in the zygote.
336 if (droppedPriviliges) {
337 try {
338 Os.setreuid(ROOT_UID, ROOT_UID);
339 Os.setregid(ROOT_GID, ROOT_GID);
340 } catch (ErrnoException ex) {
341 throw new RuntimeException("Failed to restore root", ex);
342 }
Elliott Hughes26b56e62014-12-17 12:28:29 -0800343 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800344 }
345 }
346
347 /**
348 * Load in commonly used resources, so they can be shared across
349 * processes.
350 *
351 * These tend to be a few Kbytes, but are frequently in the 20-40K
352 * range, and occasionally even larger.
353 */
354 private static void preloadResources() {
355 final VMRuntime runtime = VMRuntime.getRuntime();
Bob Leee5408332009-09-04 18:31:17 -0700356
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800357 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800358 mResources = Resources.getSystem();
359 mResources.startPreloading();
360 if (PRELOAD_RESOURCES) {
361 Log.i(TAG, "Preloading resources...");
362
363 long startTime = SystemClock.uptimeMillis();
364 TypedArray ar = mResources.obtainTypedArray(
365 com.android.internal.R.array.preloaded_drawables);
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800366 int N = preloadDrawables(ar);
Jeff Brown14577c42012-03-08 16:40:14 -0800367 ar.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800368 Log.i(TAG, "...preloaded " + N + " resources in "
369 + (SystemClock.uptimeMillis()-startTime) + "ms.");
370
371 startTime = SystemClock.uptimeMillis();
372 ar = mResources.obtainTypedArray(
373 com.android.internal.R.array.preloaded_color_state_lists);
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800374 N = preloadColorStateLists(ar);
Jeff Brown14577c42012-03-08 16:40:14 -0800375 ar.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800376 Log.i(TAG, "...preloaded " + N + " resources in "
377 + (SystemClock.uptimeMillis()-startTime) + "ms.");
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800378
379 if (mResources.getBoolean(
380 com.android.internal.R.bool.config_freeformWindowManagement)) {
381 startTime = SystemClock.uptimeMillis();
382 ar = mResources.obtainTypedArray(
383 com.android.internal.R.array.preloaded_freeform_multi_window_drawables);
384 N = preloadDrawables(ar);
385 ar.recycle();
386 Log.i(TAG, "...preloaded " + N + " resource in "
387 + (SystemClock.uptimeMillis() - startTime) + "ms.");
388 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389 }
390 mResources.finishPreloading();
391 } catch (RuntimeException e) {
392 Log.w(TAG, "Failure preloading resources", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800393 }
394 }
395
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800396 private static int preloadColorStateLists(TypedArray ar) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800397 int N = ar.length();
398 for (int i=0; i<N; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800399 int id = ar.getResourceId(i, 0);
Joe Onorato43a17652011-04-06 19:22:23 -0700400 if (false) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800401 Log.v(TAG, "Preloading resource #" + Integer.toHexString(id));
402 }
403 if (id != 0) {
Alan Viverette77bb6f12015-02-11 17:24:33 -0800404 if (mResources.getColorStateList(id, null) == null) {
Dianne Hackborndde331c2012-08-03 14:01:57 -0700405 throw new IllegalArgumentException(
406 "Unable to find preloaded color resource #0x"
407 + Integer.toHexString(id)
408 + " (" + ar.getString(i) + ")");
409 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800410 }
411 }
412 return N;
413 }
414
415
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800416 private static int preloadDrawables(TypedArray ar) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800417 int N = ar.length();
418 for (int i=0; i<N; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800419 int id = ar.getResourceId(i, 0);
Joe Onorato43a17652011-04-06 19:22:23 -0700420 if (false) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800421 Log.v(TAG, "Preloading resource #" + Integer.toHexString(id));
422 }
423 if (id != 0) {
Alan Viverette84e001a2014-09-22 00:04:22 -0700424 if (mResources.getDrawable(id, null) == null) {
Dianne Hackborndde331c2012-08-03 14:01:57 -0700425 throw new IllegalArgumentException(
426 "Unable to find preloaded drawable resource #0x"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800427 + Integer.toHexString(id)
Dianne Hackborndde331c2012-08-03 14:01:57 -0700428 + " (" + ar.getString(i) + ")");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800429 }
430 }
431 }
432 return N;
433 }
434
435 /**
436 * Runs several special GCs to try to clean up a few generations of
437 * softly- and final-reachable objects, along with any other garbage.
438 * This is only useful just before a fork().
439 */
Mathieu Chartier9a88f102014-08-20 10:24:11 -0700440 /*package*/ static void gcAndFinalize() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800441 final VMRuntime runtime = VMRuntime.getRuntime();
442
443 /* runFinalizationSync() lets finalizers be called in Zygote,
444 * which doesn't have a HeapWorker thread.
445 */
Brian Carlstrom08065b92011-04-01 15:49:41 -0700446 System.gc();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800447 runtime.runFinalizationSync();
Brian Carlstrom08065b92011-04-01 15:49:41 -0700448 System.gc();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800449 }
450
451 /**
452 * Finish remaining work for the newly forked system server process.
453 */
Narayan Kamathac0b4be2017-07-05 14:45:38 +0100454 private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
Mike Lockwood90960e82010-08-06 09:15:25 -0400455 // set umask to 0077 so new files and directories will default to owner-only permissions.
Elliott Hughes860c5912014-04-28 19:19:13 -0700456 Os.umask(S_IRWXG | S_IRWXO);
Mike Lockwood90960e82010-08-06 09:15:25 -0400457
Jeff Brownebed7d62011-05-16 17:08:42 -0700458 if (parsedArgs.niceName != null) {
459 Process.setArgV0(parsedArgs.niceName);
460 }
461
Narayan Kamath29564cd2014-08-07 10:57:40 +0100462 final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
463 if (systemServerClasspath != null) {
464 performSystemServerDexOpt(systemServerClasspath);
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -0700465 // Capturing profiles is only supported for debug or eng builds since selinux normally
466 // prevents it.
467 boolean profileSystemServer = SystemProperties.getBoolean(
468 "dalvik.vm.profilesystemserver", false);
469 if (profileSystemServer && (Build.IS_USERDEBUG || Build.IS_ENG)) {
470 try {
471 File profileDir = Environment.getDataProfilesDePackageDirectory(
472 Process.SYSTEM_UID, "system_server");
473 File profile = new File(profileDir, "primary.prof");
474 profile.getParentFile().mkdirs();
475 profile.createNewFile();
476 String[] codePaths = systemServerClasspath.split(":");
477 VMRuntime.registerAppInfo(profile.getPath(), codePaths);
478 } catch (Exception e) {
479 Log.wtf(TAG, "Failed to set up system server profile", e);
480 }
481 }
Narayan Kamath29564cd2014-08-07 10:57:40 +0100482 }
483
Jeff Brownebed7d62011-05-16 17:08:42 -0700484 if (parsedArgs.invokeWith != null) {
Narayan Kamath29564cd2014-08-07 10:57:40 +0100485 String[] args = parsedArgs.remainingArgs;
486 // If we have a non-null system server class path, we'll have to duplicate the
487 // existing arguments and append the classpath to it. ART will handle the classpath
488 // correctly when we exec a new process.
489 if (systemServerClasspath != null) {
490 String[] amendedArgs = new String[args.length + 2];
491 amendedArgs[0] = "-cp";
492 amendedArgs[1] = systemServerClasspath;
tony.ys_liu34738172016-12-14 18:50:29 +0800493 System.arraycopy(args, 0, amendedArgs, 2, args.length);
494 args = amendedArgs;
Narayan Kamath29564cd2014-08-07 10:57:40 +0100495 }
496
Jeff Brownebed7d62011-05-16 17:08:42 -0700497 WrapperInit.execApplication(parsedArgs.invokeWith,
Elliott Hughese1dfcb72011-07-08 11:08:07 -0700498 parsedArgs.niceName, parsedArgs.targetSdkVersion,
Narayan Kamath37ad4b02015-01-19 16:05:24 +0000499 VMRuntime.getCurrentInstructionSet(), null, args);
Narayan Kamathac0b4be2017-07-05 14:45:38 +0100500
501 throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
Jeff Brownebed7d62011-05-16 17:08:42 -0700502 } else {
Narayan Kamath29564cd2014-08-07 10:57:40 +0100503 ClassLoader cl = null;
504 if (systemServerClasspath != null) {
tony.ys_liu34738172016-12-14 18:50:29 +0800505 cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700506
Narayan Kamath29564cd2014-08-07 10:57:40 +0100507 Thread.currentThread().setContextClassLoader(cl);
508 }
509
Jeff Brownebed7d62011-05-16 17:08:42 -0700510 /*
511 * Pass the remaining arguments to SystemServer.
512 */
Narayan Kamathac0b4be2017-07-05 14:45:38 +0100513 return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
Jeff Brownebed7d62011-05-16 17:08:42 -0700514 }
515
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800516 /* should never reach here */
517 }
518
519 /**
tony.ys_liu34738172016-12-14 18:50:29 +0800520 * Creates a PathClassLoader for the given class path that is associated with a shared
521 * namespace, i.e., this classloader can access platform-private native libraries. The
522 * classloader will use java.library.path as the native library path.
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700523 */
tony.ys_liu34738172016-12-14 18:50:29 +0800524 static PathClassLoader createPathClassLoader(String classPath, int targetSdkVersion) {
Dimitry Ivanov9e9061f2016-09-20 10:50:40 -0700525 String libraryPath = System.getProperty("java.library.path");
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700526
tony.ys_liu34738172016-12-14 18:50:29 +0800527 return PathClassLoaderFactory.createClassLoader(classPath,
Dimitry Ivanov9e9061f2016-09-20 10:50:40 -0700528 libraryPath,
529 libraryPath,
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700530 ClassLoader.getSystemClassLoader(),
531 targetSdkVersion,
532 true /* isNamespaceShared */);
533 }
534
535 /**
Narayan Kamath29564cd2014-08-07 10:57:40 +0100536 * Performs dex-opt on the elements of {@code classPath}, if needed. We
537 * choose the instruction set of the current runtime.
538 */
539 private static void performSystemServerDexOpt(String classPath) {
540 final String[] classPathElements = classPath.split(":");
Jeff Sharkey740f5232016-12-09 14:31:26 -0700541 final IInstalld installd = IInstalld.Stub
542 .asInterface(ServiceManager.getService("installd"));
Narayan Kamath29564cd2014-08-07 10:57:40 +0100543 final String instructionSet = VMRuntime.getRuntime().vmInstructionSet();
544
Jeff Sharkey740f5232016-12-09 14:31:26 -0700545 String sharedLibraries = "";
546 for (String classPathElement : classPathElements) {
547 // System server is fully AOTed and never profiled
548 // for profile guided compilation.
Mathieu Chartierc477ab12017-06-15 19:09:38 -0700549 String systemServerFilter = SystemProperties.get(
550 "dalvik.vm.systemservercompilerfilter", "speed");
Andreas Gampee7bc1522016-08-09 20:44:04 -0700551
Jeff Sharkey740f5232016-12-09 14:31:26 -0700552 int dexoptNeeded;
553 try {
554 dexoptNeeded = DexFile.getDexOptNeeded(
Mathieu Chartierc477ab12017-06-15 19:09:38 -0700555 classPathElement, instructionSet, systemServerFilter,
Calin Juravle7ba73dd2017-09-12 00:58:33 -0700556 null /* classLoaderContext */, false /* newProfile */, false /* downgrade */);
Jeff Sharkey740f5232016-12-09 14:31:26 -0700557 } catch (FileNotFoundException ignored) {
558 // Do not add to the classpath.
559 Log.w(TAG, "Missing classpath element for system server: " + classPathElement);
560 continue;
561 } catch (IOException e) {
562 // Not fully clear what to do here as we don't know the cause of the
563 // IO exception. Add to the classpath to be conservative, but don't
564 // attempt to compile it.
565 Log.w(TAG, "Error checking classpath element for system server: "
566 + classPathElement, e);
567 dexoptNeeded = DexFile.NO_DEXOPT_NEEDED;
Narayan Kamath29564cd2014-08-07 10:57:40 +0100568 }
Jeff Sharkey740f5232016-12-09 14:31:26 -0700569
570 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
571 final String packageName = "*";
572 final String outputPath = null;
573 final int dexFlags = 0;
Mathieu Chartierc477ab12017-06-15 19:09:38 -0700574 final String compilerFilter = systemServerFilter;
Jeff Sharkey740f5232016-12-09 14:31:26 -0700575 final String uuid = StorageManager.UUID_PRIVATE_INTERNAL;
Calin Juravle811a75a2017-04-05 22:49:38 -0700576 final String seInfo = null;
Jeff Sharkey740f5232016-12-09 14:31:26 -0700577 try {
578 installd.dexopt(classPathElement, Process.SYSTEM_UID, packageName,
579 instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter,
Shubham Ajmera3aeca172017-05-24 17:46:36 -0700580 uuid, sharedLibraries, seInfo, false /* downgrade */);
Jeff Sharkey740f5232016-12-09 14:31:26 -0700581 } catch (RemoteException | ServiceSpecificException e) {
582 // Ignore (but log), we need this on the classpath for fallback mode.
583 Log.w(TAG, "Failed compiling classpath element for system server: "
584 + classPathElement, e);
585 }
586 }
587
588 if (!sharedLibraries.isEmpty()) {
589 sharedLibraries += ":";
590 }
591 sharedLibraries += classPathElement;
Narayan Kamath29564cd2014-08-07 10:57:40 +0100592 }
593 }
594
595 /**
Narayan Kamathac0b4be2017-07-05 14:45:38 +0100596 * Prepare the arguments and forks for the system server process.
597 *
598 * Returns an {@code Runnable} that provides an entrypoint into system_server code in the
599 * child process, and {@code null} in the parent.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800600 */
Narayan Kamathac0b4be2017-07-05 14:45:38 +0100601 private static Runnable forkSystemServer(String abiList, String socketName,
602 ZygoteServer zygoteServer) {
Alex Klyubin48a06e72013-04-19 10:01:42 -0700603 long capabilities = posixCapabilitiesAsBits(
Philip Cuadra7bd0fdd2016-04-28 15:26:49 -0700604 OsConstants.CAP_IPC_LOCK,
Alex Klyubin48a06e72013-04-19 10:01:42 -0700605 OsConstants.CAP_KILL,
606 OsConstants.CAP_NET_ADMIN,
607 OsConstants.CAP_NET_BIND_SERVICE,
608 OsConstants.CAP_NET_BROADCAST,
609 OsConstants.CAP_NET_RAW,
Alex Klyubin48a06e72013-04-19 10:01:42 -0700610 OsConstants.CAP_SYS_MODULE,
611 OsConstants.CAP_SYS_NICE,
Nick Kralevich3082eb72017-02-15 15:12:31 -0800612 OsConstants.CAP_SYS_PTRACE,
Alex Klyubin48a06e72013-04-19 10:01:42 -0700613 OsConstants.CAP_SYS_TIME,
John Stultz5733f382016-07-28 12:35:31 -0700614 OsConstants.CAP_SYS_TTY_CONFIG,
Luis Hector Chavez72042c92017-07-12 10:03:30 -0700615 OsConstants.CAP_WAKE_ALARM,
616 OsConstants.CAP_BLOCK_SUSPEND
Alex Klyubin48a06e72013-04-19 10:01:42 -0700617 );
Luis Hector Chavez72042c92017-07-12 10:03:30 -0700618 /* Containers run without some capabilities, so drop any caps that are not available. */
619 StructCapUserHeader header = new StructCapUserHeader(
620 OsConstants._LINUX_CAPABILITY_VERSION_3, 0);
621 StructCapUserData[] data;
622 try {
623 data = Os.capget(header);
624 } catch (ErrnoException ex) {
625 throw new RuntimeException("Failed to capget()", ex);
Luis Hector Chavez5dd239a2015-10-06 14:01:45 -0700626 }
Luis Hector Chavez72042c92017-07-12 10:03:30 -0700627 capabilities &= ((long) data[0].effective) | (((long) data[1].effective) << 32);
628
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800629 /* Hardcoded command line to start the system server */
630 String args[] = {
631 "--setuid=1000",
632 "--setgid=1000",
Jeff Sharkey053a9092016-12-02 13:17:49 -0700633 "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
Alex Klyubin48a06e72013-04-19 10:01:42 -0700634 "--capabilities=" + capabilities + "," + capabilities,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800635 "--nice-name=system_server",
Narayan Kamathb6b044a2015-02-13 17:31:25 +0000636 "--runtime-args",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800637 "com.android.server.SystemServer",
638 };
639 ZygoteConnection.Arguments parsedArgs = null;
640
641 int pid;
642
643 try {
644 parsedArgs = new ZygoteConnection.Arguments(args);
Jeff Brownebed7d62011-05-16 17:08:42 -0700645 ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
646 ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800647
648 /* Request to fork the system server process */
649 pid = Zygote.forkSystemServer(
650 parsedArgs.uid, parsedArgs.gid,
Elliott Hughese1dfcb72011-07-08 11:08:07 -0700651 parsedArgs.gids,
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100652 parsedArgs.runtimeFlags,
Elliott Hughese1dfcb72011-07-08 11:08:07 -0700653 null,
Andy McFadden1b4c7962010-10-27 11:26:05 -0700654 parsedArgs.permittedCapabilities,
655 parsedArgs.effectiveCapabilities);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800656 } catch (IllegalArgumentException ex) {
657 throw new RuntimeException(ex);
Bob Leee5408332009-09-04 18:31:17 -0700658 }
659
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800660 /* For child process */
661 if (pid == 0) {
Narayan Kamath64cd9072014-05-13 13:35:14 +0100662 if (hasSecondZygote(abiList)) {
663 waitForSecondaryZygote(socketName);
664 }
665
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000666 zygoteServer.closeServerSocket();
Narayan Kamathac0b4be2017-07-05 14:45:38 +0100667 return handleSystemServerProcess(parsedArgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800668 }
669
Narayan Kamathac0b4be2017-07-05 14:45:38 +0100670 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800671 }
672
Alex Klyubin48a06e72013-04-19 10:01:42 -0700673 /**
674 * Gets the bit array representation of the provided list of POSIX capabilities.
675 */
676 private static long posixCapabilitiesAsBits(int... capabilities) {
677 long result = 0;
678 for (int capability : capabilities) {
679 if ((capability < 0) || (capability > OsConstants.CAP_LAST_CAP)) {
680 throw new IllegalArgumentException(String.valueOf(capability));
681 }
682 result |= (1L << capability);
683 }
684 return result;
685 }
686
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800687 public static void main(String argv[]) {
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000688 ZygoteServer zygoteServer = new ZygoteServer();
689
Andreas Gampe1ef8aef2016-04-11 08:39:52 -0700690 // Mark zygote start. This ensures that thread creation will throw
691 // an error.
692 ZygoteHooks.startZygoteNoThreadCreation();
693
Robert Seseke4f8d692016-09-13 19:13:01 -0400694 // Zygote goes into its own process group.
695 try {
696 Os.setpgid(0, 0);
697 } catch (ErrnoException ex) {
698 throw new RuntimeException("Failed to setpgid(0,0)", ex);
699 }
700
Narayan Kamathac0b4be2017-07-05 14:45:38 +0100701 final Runnable caller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800702 try {
Fyodor Kupolov6733e6c2017-01-06 18:27:05 -0800703 // Report Zygote start time to tron unless it is a runtime restart
704 if (!"1".equals(SystemProperties.get("sys.boot_completed"))) {
705 MetricsLogger.histogram(null, "boot_zygote_init",
706 (int) SystemClock.elapsedRealtime());
707 }
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800708
709 String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
710 BootTimingsTraceLog bootTimingsTraceLog = new BootTimingsTraceLog(bootTimeTag,
711 Trace.TRACE_TAG_DALVIK);
712 bootTimingsTraceLog.traceBegin("ZygoteInit");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900713 RuntimeInit.enableDdms();
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900714
Narayan Kamathc41638c2014-04-07 13:56:15 +0100715 boolean startSystemServer = false;
716 String socketName = "zygote";
717 String abiList = null;
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000718 boolean enableLazyPreload = false;
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900719 for (int i = 1; i < argv.length; i++) {
720 if ("start-system-server".equals(argv[i])) {
721 startSystemServer = true;
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000722 } else if ("--enable-lazy-preload".equals(argv[i])) {
723 enableLazyPreload = true;
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900724 } else if (argv[i].startsWith(ABI_LIST_ARG)) {
725 abiList = argv[i].substring(ABI_LIST_ARG.length());
726 } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
727 socketName = argv[i].substring(SOCKET_NAME_ARG.length());
728 } else {
729 throw new RuntimeException("Unknown command line argument: " + argv[i]);
Narayan Kamathc41638c2014-04-07 13:56:15 +0100730 }
731 }
732
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900733 if (abiList == null) {
734 throw new RuntimeException("No ABI list supplied.");
735 }
736
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000737 zygoteServer.registerServerSocket(socketName);
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000738 // In some configurations, we avoid preloading resources and classes eagerly.
739 // In such cases, we will preload things prior to our first fork.
740 if (!enableLazyPreload) {
741 bootTimingsTraceLog.traceBegin("ZygotePreload");
742 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
743 SystemClock.uptimeMillis());
744 preload(bootTimingsTraceLog);
745 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
746 SystemClock.uptimeMillis());
747 bootTimingsTraceLog.traceEnd(); // ZygotePreload
Narayan Kamathb49996d2017-02-06 20:24:08 +0000748 } else {
Hiroshi Yamauchi1e3db872017-03-02 13:39:07 -0800749 Zygote.resetNicePriority();
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000750 }
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900751
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900752 // Do an initial gc to clean up after startup
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800753 bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900754 gcAndFinalize();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800755 bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900756
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800757 bootTimingsTraceLog.traceEnd(); // ZygoteInit
Jamie Gennis6ad04522013-04-15 18:53:24 -0700758 // Disable tracing so that forked processes do not inherit stale tracing tags from
759 // Zygote.
John Reck62cc1192017-05-12 15:39:51 -0700760 Trace.setTracingEnabled(false, 0);
Jamie Gennis6ad04522013-04-15 18:53:24 -0700761
doheon1.lee885b7422016-01-20 13:07:27 +0900762 // Zygote process unmounts root storage spaces.
763 Zygote.nativeUnmountStorageOnInit();
764
Paul Lawrenceef854772017-01-31 09:54:31 -0800765 // Set seccomp policy
766 Seccomp.setPolicy();
767
Andreas Gampe1ef8aef2016-04-11 08:39:52 -0700768 ZygoteHooks.stopZygoteNoThreadCreation();
769
Narayan Kamathc41638c2014-04-07 13:56:15 +0100770 if (startSystemServer) {
Narayan Kamathac0b4be2017-07-05 14:45:38 +0100771 Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
772
773 // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
774 // child (system_server) process.
775 if (r != null) {
776 r.run();
777 return;
778 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800779 }
780
781 Log.i(TAG, "Accepting command socket connections");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800782
Narayan Kamathac0b4be2017-07-05 14:45:38 +0100783 // The select loop returns early in the child process after a fork and
784 // loops forever in the zygote.
785 caller = zygoteServer.runSelectLoop(abiList);
Christopher Ferrisea8b5de2016-06-17 15:29:58 -0700786 } catch (Throwable ex) {
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000787 Log.e(TAG, "System zygote died with exception", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800788 throw ex;
Narayan Kamathac0b4be2017-07-05 14:45:38 +0100789 } finally {
790 zygoteServer.closeServerSocket();
791 }
792
793 // We're in the child process and have exited the select loop. Proceed to execute the
794 // command.
795 if (caller != null) {
796 caller.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800797 }
798 }
799
800 /**
Narayan Kamath64cd9072014-05-13 13:35:14 +0100801 * Return {@code true} if this device configuration has another zygote.
802 *
803 * We determine this by comparing the device ABI list with this zygotes
804 * list. If this zygote supports all ABIs this device supports, there won't
805 * be another zygote.
806 */
807 private static boolean hasSecondZygote(String abiList) {
808 return !SystemProperties.get("ro.product.cpu.abilist").equals(abiList);
809 }
810
811 private static void waitForSecondaryZygote(String socketName) {
812 String otherZygoteName = Process.ZYGOTE_SOCKET.equals(socketName) ?
813 Process.SECONDARY_ZYGOTE_SOCKET : Process.ZYGOTE_SOCKET;
Gustav Senntonf0c52b52017-04-27 17:00:50 +0100814 ZygoteProcess.waitForConnectionToZygote(otherZygoteName);
Narayan Kamath64cd9072014-05-13 13:35:14 +0100815 }
816
Narayan Kamath669afcc2017-02-06 20:24:08 +0000817 static boolean isPreloadComplete() {
818 return sPreloadComplete;
819 }
820
Narayan Kamath64cd9072014-05-13 13:35:14 +0100821 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800822 * Class not instantiable.
823 */
824 private ZygoteInit() {
825 }
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800826
827 /**
828 * The main function called when started through the zygote process. This
829 * could be unified with main(), if the native code in nativeFinishInit()
830 * were rationalized with Zygote startup.<p>
831 *
832 * Current recognized args:
833 * <ul>
834 * <li> <code> [--] &lt;start class name&gt; &lt;args&gt;
835 * </ul>
836 *
837 * @param targetSdkVersion target SDK version
838 * @param argv arg strings
839 */
Narayan Kamathac0b4be2017-07-05 14:45:38 +0100840 public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800841 if (RuntimeInit.DEBUG) {
842 Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
843 }
844
845 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
846 RuntimeInit.redirectLogStreams();
847
848 RuntimeInit.commonInit();
849 ZygoteInit.nativeZygoteInit();
Narayan Kamathac0b4be2017-07-05 14:45:38 +0100850 return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800851 }
852
853 private static final native void nativeZygoteInit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800854}