blob: 6d8b81170e21ccad96a69e596043b32a08067e3e [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.
549 // TODO: Make this configurable between INTERPRET_ONLY, SPEED, SPACE and EVERYTHING?
Andreas Gampee7bc1522016-08-09 20:44:04 -0700550
Jeff Sharkey740f5232016-12-09 14:31:26 -0700551 int dexoptNeeded;
552 try {
553 dexoptNeeded = DexFile.getDexOptNeeded(
554 classPathElement, instructionSet, "speed",
Shubham Ajmera52c86202017-07-24 15:21:04 -0700555 false /* newProfile */, false /* downgrade */);
Jeff Sharkey740f5232016-12-09 14:31:26 -0700556 } catch (FileNotFoundException ignored) {
557 // Do not add to the classpath.
558 Log.w(TAG, "Missing classpath element for system server: " + classPathElement);
559 continue;
560 } catch (IOException e) {
561 // Not fully clear what to do here as we don't know the cause of the
562 // IO exception. Add to the classpath to be conservative, but don't
563 // attempt to compile it.
564 Log.w(TAG, "Error checking classpath element for system server: "
565 + classPathElement, e);
566 dexoptNeeded = DexFile.NO_DEXOPT_NEEDED;
Narayan Kamath29564cd2014-08-07 10:57:40 +0100567 }
Jeff Sharkey740f5232016-12-09 14:31:26 -0700568
569 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
570 final String packageName = "*";
571 final String outputPath = null;
572 final int dexFlags = 0;
573 final String compilerFilter = "speed";
574 final String uuid = StorageManager.UUID_PRIVATE_INTERNAL;
Calin Juravle811a75a2017-04-05 22:49:38 -0700575 final String seInfo = null;
Jeff Sharkey740f5232016-12-09 14:31:26 -0700576 try {
577 installd.dexopt(classPathElement, Process.SYSTEM_UID, packageName,
578 instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter,
Calin Juravle811a75a2017-04-05 22:49:38 -0700579 uuid, sharedLibraries, seInfo);
Jeff Sharkey740f5232016-12-09 14:31:26 -0700580 } catch (RemoteException | ServiceSpecificException e) {
581 // Ignore (but log), we need this on the classpath for fallback mode.
582 Log.w(TAG, "Failed compiling classpath element for system server: "
583 + classPathElement, e);
584 }
585 }
586
587 if (!sharedLibraries.isEmpty()) {
588 sharedLibraries += ":";
589 }
590 sharedLibraries += classPathElement;
Narayan Kamath29564cd2014-08-07 10:57:40 +0100591 }
592 }
593
594 /**
Narayan Kamathac0b4be2017-07-05 14:45:38 +0100595 * Prepare the arguments and forks for the system server process.
596 *
597 * Returns an {@code Runnable} that provides an entrypoint into system_server code in the
598 * child process, and {@code null} in the parent.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800599 */
Narayan Kamathac0b4be2017-07-05 14:45:38 +0100600 private static Runnable forkSystemServer(String abiList, String socketName,
601 ZygoteServer zygoteServer) {
Alex Klyubin48a06e72013-04-19 10:01:42 -0700602 long capabilities = posixCapabilitiesAsBits(
Philip Cuadra7bd0fdd2016-04-28 15:26:49 -0700603 OsConstants.CAP_IPC_LOCK,
Alex Klyubin48a06e72013-04-19 10:01:42 -0700604 OsConstants.CAP_KILL,
605 OsConstants.CAP_NET_ADMIN,
606 OsConstants.CAP_NET_BIND_SERVICE,
607 OsConstants.CAP_NET_BROADCAST,
608 OsConstants.CAP_NET_RAW,
Alex Klyubin48a06e72013-04-19 10:01:42 -0700609 OsConstants.CAP_SYS_MODULE,
610 OsConstants.CAP_SYS_NICE,
Nick Kralevich3082eb72017-02-15 15:12:31 -0800611 OsConstants.CAP_SYS_PTRACE,
Alex Klyubin48a06e72013-04-19 10:01:42 -0700612 OsConstants.CAP_SYS_TIME,
John Stultz5733f382016-07-28 12:35:31 -0700613 OsConstants.CAP_SYS_TTY_CONFIG,
Luis Hector Chavez72042c92017-07-12 10:03:30 -0700614 OsConstants.CAP_WAKE_ALARM,
615 OsConstants.CAP_BLOCK_SUSPEND
Alex Klyubin48a06e72013-04-19 10:01:42 -0700616 );
Luis Hector Chavez72042c92017-07-12 10:03:30 -0700617 /* Containers run without some capabilities, so drop any caps that are not available. */
618 StructCapUserHeader header = new StructCapUserHeader(
619 OsConstants._LINUX_CAPABILITY_VERSION_3, 0);
620 StructCapUserData[] data;
621 try {
622 data = Os.capget(header);
623 } catch (ErrnoException ex) {
624 throw new RuntimeException("Failed to capget()", ex);
Luis Hector Chavez5dd239a2015-10-06 14:01:45 -0700625 }
Luis Hector Chavez72042c92017-07-12 10:03:30 -0700626 capabilities &= ((long) data[0].effective) | (((long) data[1].effective) << 32);
627
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800628 /* Hardcoded command line to start the system server */
629 String args[] = {
630 "--setuid=1000",
631 "--setgid=1000",
Jeff Sharkey053a9092016-12-02 13:17:49 -0700632 "--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 -0700633 "--capabilities=" + capabilities + "," + capabilities,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800634 "--nice-name=system_server",
Narayan Kamathb6b044a2015-02-13 17:31:25 +0000635 "--runtime-args",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800636 "com.android.server.SystemServer",
637 };
638 ZygoteConnection.Arguments parsedArgs = null;
639
640 int pid;
641
642 try {
643 parsedArgs = new ZygoteConnection.Arguments(args);
Jeff Brownebed7d62011-05-16 17:08:42 -0700644 ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
645 ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800646
647 /* Request to fork the system server process */
648 pid = Zygote.forkSystemServer(
649 parsedArgs.uid, parsedArgs.gid,
Elliott Hughese1dfcb72011-07-08 11:08:07 -0700650 parsedArgs.gids,
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100651 parsedArgs.runtimeFlags,
Elliott Hughese1dfcb72011-07-08 11:08:07 -0700652 null,
Andy McFadden1b4c7962010-10-27 11:26:05 -0700653 parsedArgs.permittedCapabilities,
654 parsedArgs.effectiveCapabilities);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800655 } catch (IllegalArgumentException ex) {
656 throw new RuntimeException(ex);
Bob Leee5408332009-09-04 18:31:17 -0700657 }
658
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800659 /* For child process */
660 if (pid == 0) {
Narayan Kamath64cd9072014-05-13 13:35:14 +0100661 if (hasSecondZygote(abiList)) {
662 waitForSecondaryZygote(socketName);
663 }
664
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000665 zygoteServer.closeServerSocket();
Narayan Kamathac0b4be2017-07-05 14:45:38 +0100666 return handleSystemServerProcess(parsedArgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800667 }
668
Narayan Kamathac0b4be2017-07-05 14:45:38 +0100669 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800670 }
671
Alex Klyubin48a06e72013-04-19 10:01:42 -0700672 /**
673 * Gets the bit array representation of the provided list of POSIX capabilities.
674 */
675 private static long posixCapabilitiesAsBits(int... capabilities) {
676 long result = 0;
677 for (int capability : capabilities) {
678 if ((capability < 0) || (capability > OsConstants.CAP_LAST_CAP)) {
679 throw new IllegalArgumentException(String.valueOf(capability));
680 }
681 result |= (1L << capability);
682 }
683 return result;
684 }
685
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800686 public static void main(String argv[]) {
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000687 ZygoteServer zygoteServer = new ZygoteServer();
688
Andreas Gampe1ef8aef2016-04-11 08:39:52 -0700689 // Mark zygote start. This ensures that thread creation will throw
690 // an error.
691 ZygoteHooks.startZygoteNoThreadCreation();
692
Robert Seseke4f8d692016-09-13 19:13:01 -0400693 // Zygote goes into its own process group.
694 try {
695 Os.setpgid(0, 0);
696 } catch (ErrnoException ex) {
697 throw new RuntimeException("Failed to setpgid(0,0)", ex);
698 }
699
Narayan Kamathac0b4be2017-07-05 14:45:38 +0100700 final Runnable caller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800701 try {
Fyodor Kupolov6733e6c2017-01-06 18:27:05 -0800702 // Report Zygote start time to tron unless it is a runtime restart
703 if (!"1".equals(SystemProperties.get("sys.boot_completed"))) {
704 MetricsLogger.histogram(null, "boot_zygote_init",
705 (int) SystemClock.elapsedRealtime());
706 }
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800707
708 String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
709 BootTimingsTraceLog bootTimingsTraceLog = new BootTimingsTraceLog(bootTimeTag,
710 Trace.TRACE_TAG_DALVIK);
711 bootTimingsTraceLog.traceBegin("ZygoteInit");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900712 RuntimeInit.enableDdms();
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900713
Narayan Kamathc41638c2014-04-07 13:56:15 +0100714 boolean startSystemServer = false;
715 String socketName = "zygote";
716 String abiList = null;
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000717 boolean enableLazyPreload = false;
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900718 for (int i = 1; i < argv.length; i++) {
719 if ("start-system-server".equals(argv[i])) {
720 startSystemServer = true;
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000721 } else if ("--enable-lazy-preload".equals(argv[i])) {
722 enableLazyPreload = true;
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900723 } else if (argv[i].startsWith(ABI_LIST_ARG)) {
724 abiList = argv[i].substring(ABI_LIST_ARG.length());
725 } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
726 socketName = argv[i].substring(SOCKET_NAME_ARG.length());
727 } else {
728 throw new RuntimeException("Unknown command line argument: " + argv[i]);
Narayan Kamathc41638c2014-04-07 13:56:15 +0100729 }
730 }
731
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900732 if (abiList == null) {
733 throw new RuntimeException("No ABI list supplied.");
734 }
735
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000736 zygoteServer.registerServerSocket(socketName);
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000737 // In some configurations, we avoid preloading resources and classes eagerly.
738 // In such cases, we will preload things prior to our first fork.
739 if (!enableLazyPreload) {
740 bootTimingsTraceLog.traceBegin("ZygotePreload");
741 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
742 SystemClock.uptimeMillis());
743 preload(bootTimingsTraceLog);
744 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
745 SystemClock.uptimeMillis());
746 bootTimingsTraceLog.traceEnd(); // ZygotePreload
Narayan Kamathb49996d2017-02-06 20:24:08 +0000747 } else {
Hiroshi Yamauchi1e3db872017-03-02 13:39:07 -0800748 Zygote.resetNicePriority();
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000749 }
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900750
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900751 // Do an initial gc to clean up after startup
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800752 bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900753 gcAndFinalize();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800754 bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900755
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800756 bootTimingsTraceLog.traceEnd(); // ZygoteInit
Jamie Gennis6ad04522013-04-15 18:53:24 -0700757 // Disable tracing so that forked processes do not inherit stale tracing tags from
758 // Zygote.
John Reck62cc1192017-05-12 15:39:51 -0700759 Trace.setTracingEnabled(false, 0);
Jamie Gennis6ad04522013-04-15 18:53:24 -0700760
doheon1.lee885b7422016-01-20 13:07:27 +0900761 // Zygote process unmounts root storage spaces.
762 Zygote.nativeUnmountStorageOnInit();
763
Paul Lawrenceef854772017-01-31 09:54:31 -0800764 // Set seccomp policy
765 Seccomp.setPolicy();
766
Andreas Gampe1ef8aef2016-04-11 08:39:52 -0700767 ZygoteHooks.stopZygoteNoThreadCreation();
768
Narayan Kamathc41638c2014-04-07 13:56:15 +0100769 if (startSystemServer) {
Narayan Kamathac0b4be2017-07-05 14:45:38 +0100770 Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
771
772 // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
773 // child (system_server) process.
774 if (r != null) {
775 r.run();
776 return;
777 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800778 }
779
780 Log.i(TAG, "Accepting command socket connections");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800781
Narayan Kamathac0b4be2017-07-05 14:45:38 +0100782 // The select loop returns early in the child process after a fork and
783 // loops forever in the zygote.
784 caller = zygoteServer.runSelectLoop(abiList);
Christopher Ferrisea8b5de2016-06-17 15:29:58 -0700785 } catch (Throwable ex) {
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000786 Log.e(TAG, "System zygote died with exception", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800787 throw ex;
Narayan Kamathac0b4be2017-07-05 14:45:38 +0100788 } finally {
789 zygoteServer.closeServerSocket();
790 }
791
792 // We're in the child process and have exited the select loop. Proceed to execute the
793 // command.
794 if (caller != null) {
795 caller.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800796 }
797 }
798
799 /**
Narayan Kamath64cd9072014-05-13 13:35:14 +0100800 * Return {@code true} if this device configuration has another zygote.
801 *
802 * We determine this by comparing the device ABI list with this zygotes
803 * list. If this zygote supports all ABIs this device supports, there won't
804 * be another zygote.
805 */
806 private static boolean hasSecondZygote(String abiList) {
807 return !SystemProperties.get("ro.product.cpu.abilist").equals(abiList);
808 }
809
810 private static void waitForSecondaryZygote(String socketName) {
811 String otherZygoteName = Process.ZYGOTE_SOCKET.equals(socketName) ?
812 Process.SECONDARY_ZYGOTE_SOCKET : Process.ZYGOTE_SOCKET;
Gustav Senntonf0c52b52017-04-27 17:00:50 +0100813 ZygoteProcess.waitForConnectionToZygote(otherZygoteName);
Narayan Kamath64cd9072014-05-13 13:35:14 +0100814 }
815
Narayan Kamath669afcc2017-02-06 20:24:08 +0000816 static boolean isPreloadComplete() {
817 return sPreloadComplete;
818 }
819
Narayan Kamath64cd9072014-05-13 13:35:14 +0100820 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800821 * Class not instantiable.
822 */
823 private ZygoteInit() {
824 }
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800825
826 /**
827 * The main function called when started through the zygote process. This
828 * could be unified with main(), if the native code in nativeFinishInit()
829 * were rationalized with Zygote startup.<p>
830 *
831 * Current recognized args:
832 * <ul>
833 * <li> <code> [--] &lt;start class name&gt; &lt;args&gt;
834 * </ul>
835 *
836 * @param targetSdkVersion target SDK version
837 * @param argv arg strings
838 */
Narayan Kamathac0b4be2017-07-05 14:45:38 +0100839 public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800840 if (RuntimeInit.DEBUG) {
841 Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
842 }
843
844 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
845 RuntimeInit.redirectLogStreams();
846
847 RuntimeInit.commonInit();
848 ZygoteInit.nativeZygoteInit();
Narayan Kamathac0b4be2017-07-05 14:45:38 +0100849 return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800850 }
851
852 private static final native void nativeZygoteInit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800853}