blob: da195601f725e847bf88599ce300f97ed870114f [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;
Calin Juravle3f3a08a2018-05-02 23:39:19 -070038import android.os.UserHandle;
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;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048import android.util.EventLog;
49import android.util.Log;
Andreas Gampe76d4fc82017-02-07 19:44:37 -080050import android.util.Slog;
Mathew Inwood04194fe2018-04-04 14:48:03 +010051import android.util.TimingsTraceLog;
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;
Narayan Kamath669afcc2017-02-06 20:24:08 +000056import com.android.internal.util.Preconditions;
Mathew Inwood04194fe2018-04-04 14:48:03 +010057
Narayan Kamath29564cd2014-08-07 10:57:40 +010058import dalvik.system.DexFile;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059import dalvik.system.VMRuntime;
Andreas Gampe1ef8aef2016-04-11 08:39:52 -070060import dalvik.system.ZygoteHooks;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061
Brian Carlstrom46703b02011-04-06 15:41:29 -070062import libcore.io.IoUtils;
63
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064import java.io.BufferedReader;
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -070065import java.io.File;
Ying Wangd0c45352014-11-13 15:22:47 -080066import java.io.FileInputStream;
67import java.io.FileNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068import java.io.IOException;
69import java.io.InputStream;
70import java.io.InputStreamReader;
Sergio Giro6cb7b1c2016-05-13 16:34:46 +010071import java.security.Provider;
Mathew Inwood04194fe2018-04-04 14:48:03 +010072import java.security.Security;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073
74/**
75 * Startup class for the zygote process.
76 *
77 * Pre-initializes some classes, and then waits for commands on a UNIX domain
Elliott Hughese1dfcb72011-07-08 11:08:07 -070078 * socket. Based on these commands, forks off child processes that inherit
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079 * the initial state of the VM.
80 *
81 * Please see {@link ZygoteConnection.Arguments} for documentation on the
82 * client protocol.
83 *
84 * @hide
85 */
86public class ZygoteInit {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087 private static final String TAG = "Zygote";
88
Jesse Hall2852a282017-01-17 10:17:41 -080089 private static final String PROPERTY_DISABLE_OPENGL_PRELOADING = "ro.zygote.disable_gl_preload";
Jesse Hallba0370e2017-02-09 14:43:14 -080090 private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
Romain Guyc5e36382013-05-09 11:08:17 -070091
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092 private static final int LOG_BOOT_PROGRESS_PRELOAD_START = 3020;
93 private static final int LOG_BOOT_PROGRESS_PRELOAD_END = 3030;
94
95 /** when preloading, GC after allocating this many bytes */
96 private static final int PRELOAD_GC_THRESHOLD = 50000;
97
Narayan Kamathc41638c2014-04-07 13:56:15 +010098 private static final String ABI_LIST_ARG = "--abi-list=";
99
100 private static final String SOCKET_NAME_ARG = "--socket-name=";
Barry Hayes0b3533a2010-01-20 12:46:47 -0800101
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102 /**
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000103 * Used to pre-load resources.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104 */
105 private static Resources mResources;
Bob Leee5408332009-09-04 18:31:17 -0700106
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107 /**
Ying Wangd0c45352014-11-13 15:22:47 -0800108 * The path of a file that contains classes to preload.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109 */
Ying Wangd0c45352014-11-13 15:22:47 -0800110 private static final String PRELOADED_CLASSES = "/system/etc/preloaded-classes";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111
112 /** Controls whether we should preload resources during zygote init. */
Steve Paik3c27a232015-06-10 18:25:44 -0700113 public static final boolean PRELOAD_RESOURCES = true;
Andy McFadden599c9182009-04-08 00:35:56 -0700114
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115 private static final int UNPRIVILEGED_UID = 9999;
116 private static final int UNPRIVILEGED_GID = 9999;
117
118 private static final int ROOT_UID = 0;
119 private static final int ROOT_GID = 0;
120
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000121 private static boolean sPreloadComplete;
122
Fyodor Kupolov6e3461b2017-08-10 17:00:43 -0700123 static void preload(TimingsTraceLog bootTimingsTraceLog) {
Bill Yi9a76e9b2014-04-29 18:52:48 -0700124 Log.d(TAG, "begin preload");
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800125 bootTimingsTraceLog.traceBegin("BeginIcuCachePinning");
Neil Fuller4f41f612016-05-09 16:55:36 +0100126 beginIcuCachePinning();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800127 bootTimingsTraceLog.traceEnd(); // BeginIcuCachePinning
128 bootTimingsTraceLog.traceBegin("PreloadClasses");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900129 preloadClasses();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800130 bootTimingsTraceLog.traceEnd(); // PreloadClasses
131 bootTimingsTraceLog.traceBegin("PreloadResources");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900132 preloadResources();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800133 bootTimingsTraceLog.traceEnd(); // PreloadResources
Jesse Hall1fe1dc02017-07-06 15:30:39 -0700134 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs");
135 nativePreloadAppProcessHALs();
136 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Jesse Hallba0370e2017-02-09 14:43:14 -0800137 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadOpenGL");
138 preloadOpenGL();
139 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Brian Carlstrom6c9af962014-09-11 15:36:00 -0700140 preloadSharedLibraries();
Raph Levienc3dd1c12015-04-06 10:37:57 -0700141 preloadTextResources();
Torne (Richard Coles)08cfaf62014-05-08 16:07:05 +0100142 // Ask the WebViewFactory to do any initialization that must run in the zygote process,
143 // for memory sharing purposes.
144 WebViewFactory.prepareWebViewInZygote();
Neil Fuller4f41f612016-05-09 16:55:36 +0100145 endIcuCachePinning();
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100146 warmUpJcaProviders();
Bill Yi9a76e9b2014-04-29 18:52:48 -0700147 Log.d(TAG, "end preload");
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000148
149 sPreloadComplete = true;
150 }
151
Narayan Kamath669afcc2017-02-06 20:24:08 +0000152 public static void lazyPreload() {
153 Preconditions.checkState(!sPreloadComplete);
154 Log.i(TAG, "Lazily preloading resources.");
155
Fyodor Kupolov6e3461b2017-08-10 17:00:43 -0700156 preload(new TimingsTraceLog("ZygoteInitTiming_lazy", Trace.TRACE_TAG_DALVIK));
Romain Guy74c69122013-05-08 17:54:20 -0700157 }
158
Neil Fuller4f41f612016-05-09 16:55:36 +0100159 private static void beginIcuCachePinning() {
160 // Pin ICU data in memory from this point that would normally be held by soft references.
161 // Without this, any references created immediately below or during class preloading
162 // would be collected when the Zygote GC runs in gcAndFinalize().
163 Log.i(TAG, "Installing ICU cache reference pinning...");
164
165 CacheValue.setStrength(CacheValue.Strength.STRONG);
166
167 Log.i(TAG, "Preloading ICU data...");
168 // Explicitly exercise code to cache data apps are likely to need.
169 ULocale[] localesToPin = { ULocale.ROOT, ULocale.US, ULocale.getDefault() };
170 for (ULocale uLocale : localesToPin) {
171 new DecimalFormatSymbols(uLocale);
172 }
173 }
174
175 private static void endIcuCachePinning() {
176 // All cache references created by ICU from this point will be soft.
177 CacheValue.setStrength(CacheValue.Strength.SOFT);
178
179 Log.i(TAG, "Uninstalled ICU cache reference pinning...");
180 }
181
Brian Carlstrom6c9af962014-09-11 15:36:00 -0700182 private static void preloadSharedLibraries() {
183 Log.i(TAG, "Preloading shared libraries...");
184 System.loadLibrary("android");
185 System.loadLibrary("compiler_rt");
186 System.loadLibrary("jnigraphics");
187 }
188
Jesse Hall1fe1dc02017-07-06 15:30:39 -0700189 native private static void nativePreloadAppProcessHALs();
190
Jesse Hallba0370e2017-02-09 14:43:14 -0800191 private static void preloadOpenGL() {
192 String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
Jesse Hall5d911fe2017-04-13 15:44:24 -0700193 if (!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING, false) &&
194 (driverPackageName == null || driverPackageName.isEmpty())) {
Jesse Hallba0370e2017-02-09 14:43:14 -0800195 EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
196 }
197 }
198
Raph Levienc3dd1c12015-04-06 10:37:57 -0700199 private static void preloadTextResources() {
200 Hyphenator.init();
Andreas Gampeddc13972016-02-26 16:54:59 -0800201 TextView.preloadFontCache();
Raph Levienc3dd1c12015-04-06 10:37:57 -0700202 }
203
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800204 /**
Sergio Giro69de3202016-05-17 16:52:33 +0100205 * Register AndroidKeyStoreProvider and warm up the providers that are already registered.
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100206 *
207 * By doing it here we avoid that each app does it when requesting a service from the
208 * provider for the first time.
209 */
210 private static void warmUpJcaProviders() {
211 long startTime = SystemClock.uptimeMillis();
212 Trace.traceBegin(
Sergio Giro69de3202016-05-17 16:52:33 +0100213 Trace.TRACE_TAG_DALVIK, "Starting installation of AndroidKeyStoreProvider");
214 // AndroidKeyStoreProvider.install() manipulates the list of JCA providers to insert
215 // preferred providers. Note this is not done via security.properties as the JCA providers
216 // are not on the classpath in the case of, for example, raw dalvikvm runtimes.
217 AndroidKeyStoreProvider.install();
218 Log.i(TAG, "Installed AndroidKeyStoreProvider in "
219 + (SystemClock.uptimeMillis() - startTime) + "ms.");
220 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
221
222 startTime = SystemClock.uptimeMillis();
223 Trace.traceBegin(
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100224 Trace.TRACE_TAG_DALVIK, "Starting warm up of JCA providers");
225 for (Provider p : Security.getProviders()) {
226 p.warmUpServiceProvision();
227 }
228 Log.i(TAG, "Warmed up JCA providers in "
Sergio Giro69de3202016-05-17 16:52:33 +0100229 + (SystemClock.uptimeMillis() - startTime) + "ms.");
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100230 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
231 }
232
233 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800234 * Performs Zygote process initialization. Loads and initializes
235 * commonly used classes.
236 *
237 * Most classes only cause a few hundred bytes to be allocated, but
238 * a few will allocate a dozen Kbytes (in one case, 500+K).
239 */
240 private static void preloadClasses() {
241 final VMRuntime runtime = VMRuntime.getRuntime();
Bob Leee5408332009-09-04 18:31:17 -0700242
Ying Wangd0c45352014-11-13 15:22:47 -0800243 InputStream is;
244 try {
245 is = new FileInputStream(PRELOADED_CLASSES);
246 } catch (FileNotFoundException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247 Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + ".");
Ying Wangd0c45352014-11-13 15:22:47 -0800248 return;
249 }
Bob Leee5408332009-09-04 18:31:17 -0700250
Ying Wangd0c45352014-11-13 15:22:47 -0800251 Log.i(TAG, "Preloading classes...");
252 long startTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800253
Ying Wangd0c45352014-11-13 15:22:47 -0800254 // Drop root perms while running static initializers.
Narayan Kamath23e68782015-01-16 17:22:41 +0000255 final int reuid = Os.getuid();
256 final int regid = Os.getgid();
257
258 // We need to drop root perms only if we're already root. In the case of "wrapped"
259 // processes (see WrapperInit), this function is called from an unprivileged uid
260 // and gid.
261 boolean droppedPriviliges = false;
262 if (reuid == ROOT_UID && regid == ROOT_GID) {
263 try {
264 Os.setregid(ROOT_GID, UNPRIVILEGED_GID);
265 Os.setreuid(ROOT_UID, UNPRIVILEGED_UID);
266 } catch (ErrnoException ex) {
267 throw new RuntimeException("Failed to drop root", ex);
268 }
269
270 droppedPriviliges = true;
Elliott Hughes26b56e62014-12-17 12:28:29 -0800271 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800272
Ying Wangd0c45352014-11-13 15:22:47 -0800273 // Alter the target heap utilization. With explicit GCs this
274 // is not likely to have any effect.
275 float defaultUtilization = runtime.getTargetHeapUtilization();
276 runtime.setTargetHeapUtilization(0.8f);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277
Ying Wangd0c45352014-11-13 15:22:47 -0800278 try {
279 BufferedReader br
280 = new BufferedReader(new InputStreamReader(is), 256);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800281
Ying Wangd0c45352014-11-13 15:22:47 -0800282 int count = 0;
283 String line;
284 while ((line = br.readLine()) != null) {
285 // Skip comments and blank lines.
286 line = line.trim();
287 if (line.startsWith("#") || line.equals("")) {
288 continue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800289 }
290
Andreas Gampec4253622016-10-28 18:19:30 -0700291 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, line);
Ying Wangd0c45352014-11-13 15:22:47 -0800292 try {
293 if (false) {
294 Log.v(TAG, "Preloading " + line + "...");
295 }
Andreas Gampedd8e5fb2015-04-21 09:01:51 -0700296 // Load and explicitly initialize the given class. Use
297 // Class.forName(String, boolean, ClassLoader) to avoid repeated stack lookups
298 // (to derive the caller's class-loader). Use true to force initialization, and
299 // null for the boot classpath class-loader (could as well cache the
300 // class-loader of this class in a variable).
Andreas Gampec917f742015-04-20 19:16:37 -0700301 Class.forName(line, true, null);
Ying Wangd0c45352014-11-13 15:22:47 -0800302 count++;
303 } catch (ClassNotFoundException e) {
304 Log.w(TAG, "Class not found for preloading: " + line);
305 } catch (UnsatisfiedLinkError e) {
306 Log.w(TAG, "Problem preloading " + line + ": " + e);
307 } catch (Throwable t) {
308 Log.e(TAG, "Error preloading " + line + ".", t);
309 if (t instanceof Error) {
310 throw (Error) t;
311 }
312 if (t instanceof RuntimeException) {
313 throw (RuntimeException) t;
314 }
315 throw new RuntimeException(t);
316 }
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900317 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800318 }
Ying Wangd0c45352014-11-13 15:22:47 -0800319
320 Log.i(TAG, "...preloaded " + count + " classes in "
321 + (SystemClock.uptimeMillis()-startTime) + "ms.");
322 } catch (IOException e) {
323 Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);
324 } finally {
325 IoUtils.closeQuietly(is);
326 // Restore default.
327 runtime.setTargetHeapUtilization(defaultUtilization);
328
329 // Fill in dex caches with classes, fields, and methods brought in by preloading.
Yasuhiro Matsuda1ab43d52015-06-30 17:07:32 +0900330 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadDexCaches");
Ying Wangd0c45352014-11-13 15:22:47 -0800331 runtime.preloadDexCaches();
Yasuhiro Matsuda1ab43d52015-06-30 17:07:32 +0900332 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Ying Wangd0c45352014-11-13 15:22:47 -0800333
Narayan Kamath23e68782015-01-16 17:22:41 +0000334 // Bring back root. We'll need it later if we're in the zygote.
335 if (droppedPriviliges) {
336 try {
337 Os.setreuid(ROOT_UID, ROOT_UID);
338 Os.setregid(ROOT_GID, ROOT_GID);
339 } catch (ErrnoException ex) {
340 throw new RuntimeException("Failed to restore root", ex);
341 }
Elliott Hughes26b56e62014-12-17 12:28:29 -0800342 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800343 }
344 }
345
346 /**
347 * Load in commonly used resources, so they can be shared across
348 * processes.
349 *
350 * These tend to be a few Kbytes, but are frequently in the 20-40K
351 * range, and occasionally even larger.
352 */
353 private static void preloadResources() {
354 final VMRuntime runtime = VMRuntime.getRuntime();
Bob Leee5408332009-09-04 18:31:17 -0700355
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800356 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800357 mResources = Resources.getSystem();
358 mResources.startPreloading();
359 if (PRELOAD_RESOURCES) {
360 Log.i(TAG, "Preloading resources...");
361
362 long startTime = SystemClock.uptimeMillis();
363 TypedArray ar = mResources.obtainTypedArray(
364 com.android.internal.R.array.preloaded_drawables);
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800365 int N = preloadDrawables(ar);
Jeff Brown14577c42012-03-08 16:40:14 -0800366 ar.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800367 Log.i(TAG, "...preloaded " + N + " resources in "
368 + (SystemClock.uptimeMillis()-startTime) + "ms.");
369
370 startTime = SystemClock.uptimeMillis();
371 ar = mResources.obtainTypedArray(
372 com.android.internal.R.array.preloaded_color_state_lists);
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800373 N = preloadColorStateLists(ar);
Jeff Brown14577c42012-03-08 16:40:14 -0800374 ar.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800375 Log.i(TAG, "...preloaded " + N + " resources in "
376 + (SystemClock.uptimeMillis()-startTime) + "ms.");
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800377
378 if (mResources.getBoolean(
379 com.android.internal.R.bool.config_freeformWindowManagement)) {
380 startTime = SystemClock.uptimeMillis();
381 ar = mResources.obtainTypedArray(
382 com.android.internal.R.array.preloaded_freeform_multi_window_drawables);
383 N = preloadDrawables(ar);
384 ar.recycle();
385 Log.i(TAG, "...preloaded " + N + " resource in "
386 + (SystemClock.uptimeMillis() - startTime) + "ms.");
387 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800388 }
389 mResources.finishPreloading();
390 } catch (RuntimeException e) {
391 Log.w(TAG, "Failure preloading resources", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800392 }
393 }
394
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800395 private static int preloadColorStateLists(TypedArray ar) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800396 int N = ar.length();
397 for (int i=0; i<N; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398 int id = ar.getResourceId(i, 0);
Joe Onorato43a17652011-04-06 19:22:23 -0700399 if (false) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800400 Log.v(TAG, "Preloading resource #" + Integer.toHexString(id));
401 }
402 if (id != 0) {
Alan Viverette77bb6f12015-02-11 17:24:33 -0800403 if (mResources.getColorStateList(id, null) == null) {
Dianne Hackborndde331c2012-08-03 14:01:57 -0700404 throw new IllegalArgumentException(
405 "Unable to find preloaded color resource #0x"
406 + Integer.toHexString(id)
407 + " (" + ar.getString(i) + ")");
408 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800409 }
410 }
411 return N;
412 }
413
414
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800415 private static int preloadDrawables(TypedArray ar) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800416 int N = ar.length();
417 for (int i=0; i<N; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800418 int id = ar.getResourceId(i, 0);
Joe Onorato43a17652011-04-06 19:22:23 -0700419 if (false) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800420 Log.v(TAG, "Preloading resource #" + Integer.toHexString(id));
421 }
422 if (id != 0) {
Alan Viverette84e001a2014-09-22 00:04:22 -0700423 if (mResources.getDrawable(id, null) == null) {
Dianne Hackborndde331c2012-08-03 14:01:57 -0700424 throw new IllegalArgumentException(
425 "Unable to find preloaded drawable resource #0x"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800426 + Integer.toHexString(id)
Dianne Hackborndde331c2012-08-03 14:01:57 -0700427 + " (" + ar.getString(i) + ")");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800428 }
429 }
430 }
431 return N;
432 }
433
434 /**
435 * Runs several special GCs to try to clean up a few generations of
436 * softly- and final-reachable objects, along with any other garbage.
437 * This is only useful just before a fork().
438 */
Mathieu Chartier9a88f102014-08-20 10:24:11 -0700439 /*package*/ static void gcAndFinalize() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800440 final VMRuntime runtime = VMRuntime.getRuntime();
441
442 /* runFinalizationSync() lets finalizers be called in Zygote,
443 * which doesn't have a HeapWorker thread.
444 */
Brian Carlstrom08065b92011-04-01 15:49:41 -0700445 System.gc();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800446 runtime.runFinalizationSync();
Brian Carlstrom08065b92011-04-01 15:49:41 -0700447 System.gc();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800448 }
449
450 /**
451 * Finish remaining work for the newly forked system server process.
452 */
Narayan Kamathbf99d062017-07-05 14:45:38 +0100453 private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
Mike Lockwood90960e82010-08-06 09:15:25 -0400454 // set umask to 0077 so new files and directories will default to owner-only permissions.
Elliott Hughes860c5912014-04-28 19:19:13 -0700455 Os.umask(S_IRWXG | S_IRWXO);
Mike Lockwood90960e82010-08-06 09:15:25 -0400456
Jeff Brownebed7d62011-05-16 17:08:42 -0700457 if (parsedArgs.niceName != null) {
458 Process.setArgV0(parsedArgs.niceName);
459 }
460
Narayan Kamath29564cd2014-08-07 10:57:40 +0100461 final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
462 if (systemServerClasspath != null) {
463 performSystemServerDexOpt(systemServerClasspath);
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -0700464 // Capturing profiles is only supported for debug or eng builds since selinux normally
465 // prevents it.
466 boolean profileSystemServer = SystemProperties.getBoolean(
467 "dalvik.vm.profilesystemserver", false);
468 if (profileSystemServer && (Build.IS_USERDEBUG || Build.IS_ENG)) {
469 try {
Calin Juravle3f3a08a2018-05-02 23:39:19 -0700470 prepareSystemServerProfile(systemServerClasspath);
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -0700471 } catch (Exception e) {
472 Log.wtf(TAG, "Failed to set up system server profile", e);
473 }
474 }
Narayan Kamath29564cd2014-08-07 10:57:40 +0100475 }
476
Jeff Brownebed7d62011-05-16 17:08:42 -0700477 if (parsedArgs.invokeWith != null) {
Narayan Kamath29564cd2014-08-07 10:57:40 +0100478 String[] args = parsedArgs.remainingArgs;
479 // If we have a non-null system server class path, we'll have to duplicate the
480 // existing arguments and append the classpath to it. ART will handle the classpath
481 // correctly when we exec a new process.
482 if (systemServerClasspath != null) {
483 String[] amendedArgs = new String[args.length + 2];
484 amendedArgs[0] = "-cp";
485 amendedArgs[1] = systemServerClasspath;
tony.ys_liu34738172016-12-14 18:50:29 +0800486 System.arraycopy(args, 0, amendedArgs, 2, args.length);
487 args = amendedArgs;
Narayan Kamath29564cd2014-08-07 10:57:40 +0100488 }
489
Jeff Brownebed7d62011-05-16 17:08:42 -0700490 WrapperInit.execApplication(parsedArgs.invokeWith,
Elliott Hughese1dfcb72011-07-08 11:08:07 -0700491 parsedArgs.niceName, parsedArgs.targetSdkVersion,
Narayan Kamath37ad4b02015-01-19 16:05:24 +0000492 VMRuntime.getCurrentInstructionSet(), null, args);
Narayan Kamathbf99d062017-07-05 14:45:38 +0100493
494 throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
Jeff Brownebed7d62011-05-16 17:08:42 -0700495 } else {
Narayan Kamath29564cd2014-08-07 10:57:40 +0100496 ClassLoader cl = null;
497 if (systemServerClasspath != null) {
tony.ys_liu34738172016-12-14 18:50:29 +0800498 cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700499
Narayan Kamath29564cd2014-08-07 10:57:40 +0100500 Thread.currentThread().setContextClassLoader(cl);
501 }
502
Jeff Brownebed7d62011-05-16 17:08:42 -0700503 /*
504 * Pass the remaining arguments to SystemServer.
505 */
Narayan Kamathbf99d062017-07-05 14:45:38 +0100506 return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
Jeff Brownebed7d62011-05-16 17:08:42 -0700507 }
508
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800509 /* should never reach here */
510 }
511
Calin Juravle3f3a08a2018-05-02 23:39:19 -0700512 /**
513 * Note that preparing the profiles for system server does not require special
514 * selinux permissions. From the installer perspective the system server is a regular package
515 * which can capture profile information.
516 */
517 private static void prepareSystemServerProfile(String systemServerClasspath)
518 throws RemoteException {
519 if (systemServerClasspath.isEmpty()) {
520 return;
521 }
522 String[] codePaths = systemServerClasspath.split(":");
523
524 final IInstalld installd = IInstalld.Stub
525 .asInterface(ServiceManager.getService("installd"));
526
527 String systemServerPackageName = "android";
528 String systemServerProfileName = "primary.prof";
529 installd.prepareAppProfile(
530 systemServerPackageName,
531 UserHandle.USER_SYSTEM,
532 UserHandle.getAppId(Process.SYSTEM_UID),
533 systemServerProfileName,
534 codePaths[0],
535 /*dexMetadata*/ null);
536
537 File profileDir = Environment.getDataProfilesDePackageDirectory(
538 UserHandle.USER_SYSTEM, systemServerPackageName);
539 String profilePath = new File(profileDir, systemServerProfileName).getAbsolutePath();
540 VMRuntime.registerAppInfo(profilePath, codePaths);
541 }
542
Mathew Inwood8faeab82018-03-16 14:26:08 +0000543 public static void setApiBlacklistExemptions(String[] exemptions) {
544 VMRuntime.getRuntime().setHiddenApiExemptions(exemptions);
545 }
546
Mathew Inwood04194fe2018-04-04 14:48:03 +0100547 public static void setHiddenApiAccessLogSampleRate(int percent) {
548 VMRuntime.getRuntime().setHiddenApiAccessLogSamplingRate(percent);
549 }
550
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800551 /**
tony.ys_liu34738172016-12-14 18:50:29 +0800552 * Creates a PathClassLoader for the given class path that is associated with a shared
553 * namespace, i.e., this classloader can access platform-private native libraries. The
554 * classloader will use java.library.path as the native library path.
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700555 */
Narayan Kamathf9419f02017-06-15 11:35:38 +0100556 static ClassLoader createPathClassLoader(String classPath, int targetSdkVersion) {
557 String libraryPath = System.getProperty("java.library.path");
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700558
Narayan Kamathf9419f02017-06-15 11:35:38 +0100559 return ClassLoaderFactory.createClassLoader(classPath, libraryPath, libraryPath,
560 ClassLoader.getSystemClassLoader(), targetSdkVersion, true /* isNamespaceShared */,
561 null /* classLoaderName */);
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700562 }
563
564 /**
Narayan Kamath29564cd2014-08-07 10:57:40 +0100565 * Performs dex-opt on the elements of {@code classPath}, if needed. We
566 * choose the instruction set of the current runtime.
567 */
568 private static void performSystemServerDexOpt(String classPath) {
569 final String[] classPathElements = classPath.split(":");
Jeff Sharkey740f5232016-12-09 14:31:26 -0700570 final IInstalld installd = IInstalld.Stub
571 .asInterface(ServiceManager.getService("installd"));
Narayan Kamath29564cd2014-08-07 10:57:40 +0100572 final String instructionSet = VMRuntime.getRuntime().vmInstructionSet();
573
Calin Juravle2f09ff32017-07-24 15:29:56 -0700574 String classPathForElement = "";
Jeff Sharkey740f5232016-12-09 14:31:26 -0700575 for (String classPathElement : classPathElements) {
576 // System server is fully AOTed and never profiled
577 // for profile guided compilation.
Mathieu Chartier5e07a0d2017-06-15 19:09:38 -0700578 String systemServerFilter = SystemProperties.get(
579 "dalvik.vm.systemservercompilerfilter", "speed");
Andreas Gampee7bc1522016-08-09 20:44:04 -0700580
Jeff Sharkey740f5232016-12-09 14:31:26 -0700581 int dexoptNeeded;
582 try {
583 dexoptNeeded = DexFile.getDexOptNeeded(
Shubham Ajmera246dccf2017-05-24 17:46:36 -0700584 classPathElement, instructionSet, systemServerFilter,
Calin Juravle576e6c02017-09-12 00:58:33 -0700585 null /* classLoaderContext */, false /* newProfile */, false /* downgrade */);
Jeff Sharkey740f5232016-12-09 14:31:26 -0700586 } catch (FileNotFoundException ignored) {
587 // Do not add to the classpath.
588 Log.w(TAG, "Missing classpath element for system server: " + classPathElement);
589 continue;
590 } catch (IOException e) {
591 // Not fully clear what to do here as we don't know the cause of the
592 // IO exception. Add to the classpath to be conservative, but don't
593 // attempt to compile it.
594 Log.w(TAG, "Error checking classpath element for system server: "
595 + classPathElement, e);
596 dexoptNeeded = DexFile.NO_DEXOPT_NEEDED;
Narayan Kamath29564cd2014-08-07 10:57:40 +0100597 }
Jeff Sharkey740f5232016-12-09 14:31:26 -0700598
599 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
600 final String packageName = "*";
601 final String outputPath = null;
David Brazdilf7e31c02018-02-13 17:04:26 +0000602 final int dexFlags = 0;
Mathieu Chartier5e07a0d2017-06-15 19:09:38 -0700603 final String compilerFilter = systemServerFilter;
Jeff Sharkey740f5232016-12-09 14:31:26 -0700604 final String uuid = StorageManager.UUID_PRIVATE_INTERNAL;
Calin Juravle811a75a2017-04-05 22:49:38 -0700605 final String seInfo = null;
Calin Juravle2f09ff32017-07-24 15:29:56 -0700606 final String classLoaderContext =
607 getSystemServerClassLoaderContext(classPathForElement);
David Brazdil3d44ed02018-01-16 20:01:47 +0000608 final int targetSdkVersion = 0; // SystemServer targets the system's SDK version
Jeff Sharkey740f5232016-12-09 14:31:26 -0700609 try {
610 installd.dexopt(classPathElement, Process.SYSTEM_UID, packageName,
611 instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter,
David Brazdil3d44ed02018-01-16 20:01:47 +0000612 uuid, classLoaderContext, seInfo, false /* downgrade */,
Calin Juravle4bc8f4d2018-02-12 12:00:44 -0800613 targetSdkVersion, /*profileName*/ null, /*dexMetadataPath*/ null,
614 "server-dexopt");
Jeff Sharkey740f5232016-12-09 14:31:26 -0700615 } catch (RemoteException | ServiceSpecificException e) {
616 // Ignore (but log), we need this on the classpath for fallback mode.
617 Log.w(TAG, "Failed compiling classpath element for system server: "
618 + classPathElement, e);
619 }
620 }
621
Calin Juravle2f09ff32017-07-24 15:29:56 -0700622 classPathForElement = encodeSystemServerClassPath(
623 classPathForElement, classPathElement);
Narayan Kamath29564cd2014-08-07 10:57:40 +0100624 }
625 }
626
627 /**
Calin Juravle2f09ff32017-07-24 15:29:56 -0700628 * Encodes the system server class loader context in a format that is accepted by dexopt.
629 * This assumes the system server is always loaded with a {@link dalvik.system.PathClassLoader}.
630 *
631 * Note that ideally we would use the {@code DexoptUtils} to compute this. However we have no
632 * dependency here on the server so we hard code the logic again.
633 */
634 private static String getSystemServerClassLoaderContext(String classPath) {
635 return classPath == null ? "PCL[]" : "PCL[" + classPath + "]";
636 }
637
638 /**
639 * Encodes the class path in a format accepted by dexopt.
640 * @param classPath the old class path (may be empty).
641 * @param newElement the new class path elements
642 * @return the class path encoding resulted from appending {@code newElement} to
643 * {@code classPath}.
644 */
645 private static String encodeSystemServerClassPath(String classPath, String newElement) {
646 return (classPath == null || classPath.isEmpty())
647 ? newElement
648 : classPath + ":" + newElement;
649 }
650
651 /**
Narayan Kamathbf99d062017-07-05 14:45:38 +0100652 * Prepare the arguments and forks for the system server process.
653 *
654 * Returns an {@code Runnable} that provides an entrypoint into system_server code in the
655 * child process, and {@code null} in the parent.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800656 */
Narayan Kamathbf99d062017-07-05 14:45:38 +0100657 private static Runnable forkSystemServer(String abiList, String socketName,
658 ZygoteServer zygoteServer) {
Alex Klyubin48a06e72013-04-19 10:01:42 -0700659 long capabilities = posixCapabilitiesAsBits(
Philip Cuadra7bd0fdd2016-04-28 15:26:49 -0700660 OsConstants.CAP_IPC_LOCK,
Alex Klyubin48a06e72013-04-19 10:01:42 -0700661 OsConstants.CAP_KILL,
662 OsConstants.CAP_NET_ADMIN,
663 OsConstants.CAP_NET_BIND_SERVICE,
664 OsConstants.CAP_NET_BROADCAST,
665 OsConstants.CAP_NET_RAW,
Alex Klyubin48a06e72013-04-19 10:01:42 -0700666 OsConstants.CAP_SYS_MODULE,
667 OsConstants.CAP_SYS_NICE,
Nick Kralevich3082eb72017-02-15 15:12:31 -0800668 OsConstants.CAP_SYS_PTRACE,
Alex Klyubin48a06e72013-04-19 10:01:42 -0700669 OsConstants.CAP_SYS_TIME,
John Stultz5733f382016-07-28 12:35:31 -0700670 OsConstants.CAP_SYS_TTY_CONFIG,
Luis Hector Chavez72042c92017-07-12 10:03:30 -0700671 OsConstants.CAP_WAKE_ALARM,
672 OsConstants.CAP_BLOCK_SUSPEND
Alex Klyubin48a06e72013-04-19 10:01:42 -0700673 );
Luis Hector Chavez72042c92017-07-12 10:03:30 -0700674 /* Containers run without some capabilities, so drop any caps that are not available. */
675 StructCapUserHeader header = new StructCapUserHeader(
676 OsConstants._LINUX_CAPABILITY_VERSION_3, 0);
677 StructCapUserData[] data;
678 try {
679 data = Os.capget(header);
680 } catch (ErrnoException ex) {
681 throw new RuntimeException("Failed to capget()", ex);
Luis Hector Chavez5dd239a2015-10-06 14:01:45 -0700682 }
Luis Hector Chavez72042c92017-07-12 10:03:30 -0700683 capabilities &= ((long) data[0].effective) | (((long) data[1].effective) << 32);
684
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800685 /* Hardcoded command line to start the system server */
686 String args[] = {
687 "--setuid=1000",
688 "--setgid=1000",
Jerry Zhang6d319b82017-12-06 16:03:57 -0800689 "--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 -0700690 "--capabilities=" + capabilities + "," + capabilities,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800691 "--nice-name=system_server",
Narayan Kamathb6b044a2015-02-13 17:31:25 +0000692 "--runtime-args",
Jeff Sharkey27e4b742018-02-16 17:25:14 -0700693 "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800694 "com.android.server.SystemServer",
695 };
696 ZygoteConnection.Arguments parsedArgs = null;
697
698 int pid;
699
700 try {
701 parsedArgs = new ZygoteConnection.Arguments(args);
Jeff Brownebed7d62011-05-16 17:08:42 -0700702 ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
703 ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800704
Calin Juravle8eb891b2018-05-03 19:51:18 -0700705 boolean profileSystemServer = SystemProperties.getBoolean(
706 "dalvik.vm.profilesystemserver", false);
707 if (profileSystemServer) {
708 parsedArgs.runtimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
709 }
710
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800711 /* Request to fork the system server process */
712 pid = Zygote.forkSystemServer(
713 parsedArgs.uid, parsedArgs.gid,
Elliott Hughese1dfcb72011-07-08 11:08:07 -0700714 parsedArgs.gids,
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100715 parsedArgs.runtimeFlags,
Elliott Hughese1dfcb72011-07-08 11:08:07 -0700716 null,
Andy McFadden1b4c7962010-10-27 11:26:05 -0700717 parsedArgs.permittedCapabilities,
718 parsedArgs.effectiveCapabilities);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800719 } catch (IllegalArgumentException ex) {
720 throw new RuntimeException(ex);
Bob Leee5408332009-09-04 18:31:17 -0700721 }
722
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800723 /* For child process */
724 if (pid == 0) {
Narayan Kamath64cd9072014-05-13 13:35:14 +0100725 if (hasSecondZygote(abiList)) {
726 waitForSecondaryZygote(socketName);
727 }
728
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000729 zygoteServer.closeServerSocket();
Narayan Kamathbf99d062017-07-05 14:45:38 +0100730 return handleSystemServerProcess(parsedArgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800731 }
732
Narayan Kamathbf99d062017-07-05 14:45:38 +0100733 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800734 }
735
Alex Klyubin48a06e72013-04-19 10:01:42 -0700736 /**
737 * Gets the bit array representation of the provided list of POSIX capabilities.
738 */
739 private static long posixCapabilitiesAsBits(int... capabilities) {
740 long result = 0;
741 for (int capability : capabilities) {
742 if ((capability < 0) || (capability > OsConstants.CAP_LAST_CAP)) {
743 throw new IllegalArgumentException(String.valueOf(capability));
744 }
745 result |= (1L << capability);
746 }
747 return result;
748 }
749
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800750 public static void main(String argv[]) {
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000751 ZygoteServer zygoteServer = new ZygoteServer();
752
Andreas Gampe1ef8aef2016-04-11 08:39:52 -0700753 // Mark zygote start. This ensures that thread creation will throw
754 // an error.
755 ZygoteHooks.startZygoteNoThreadCreation();
756
Robert Seseke4f8d692016-09-13 19:13:01 -0400757 // Zygote goes into its own process group.
758 try {
759 Os.setpgid(0, 0);
760 } catch (ErrnoException ex) {
761 throw new RuntimeException("Failed to setpgid(0,0)", ex);
762 }
763
Narayan Kamathbf99d062017-07-05 14:45:38 +0100764 final Runnable caller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800765 try {
Fyodor Kupolov6733e6c2017-01-06 18:27:05 -0800766 // Report Zygote start time to tron unless it is a runtime restart
767 if (!"1".equals(SystemProperties.get("sys.boot_completed"))) {
768 MetricsLogger.histogram(null, "boot_zygote_init",
769 (int) SystemClock.elapsedRealtime());
770 }
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800771
772 String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
Fyodor Kupolov6e3461b2017-08-10 17:00:43 -0700773 TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag,
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800774 Trace.TRACE_TAG_DALVIK);
775 bootTimingsTraceLog.traceBegin("ZygoteInit");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900776 RuntimeInit.enableDdms();
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900777
Narayan Kamathc41638c2014-04-07 13:56:15 +0100778 boolean startSystemServer = false;
779 String socketName = "zygote";
780 String abiList = null;
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000781 boolean enableLazyPreload = false;
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900782 for (int i = 1; i < argv.length; i++) {
783 if ("start-system-server".equals(argv[i])) {
784 startSystemServer = true;
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000785 } else if ("--enable-lazy-preload".equals(argv[i])) {
786 enableLazyPreload = true;
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900787 } else if (argv[i].startsWith(ABI_LIST_ARG)) {
788 abiList = argv[i].substring(ABI_LIST_ARG.length());
789 } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
790 socketName = argv[i].substring(SOCKET_NAME_ARG.length());
791 } else {
792 throw new RuntimeException("Unknown command line argument: " + argv[i]);
Narayan Kamathc41638c2014-04-07 13:56:15 +0100793 }
794 }
795
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900796 if (abiList == null) {
797 throw new RuntimeException("No ABI list supplied.");
798 }
799
Robert Sesekd0a190df2018-02-12 18:46:01 -0500800 zygoteServer.registerServerSocketFromEnv(socketName);
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000801 // In some configurations, we avoid preloading resources and classes eagerly.
802 // In such cases, we will preload things prior to our first fork.
803 if (!enableLazyPreload) {
804 bootTimingsTraceLog.traceBegin("ZygotePreload");
805 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
806 SystemClock.uptimeMillis());
807 preload(bootTimingsTraceLog);
808 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
809 SystemClock.uptimeMillis());
810 bootTimingsTraceLog.traceEnd(); // ZygotePreload
Narayan Kamathb49996d2017-02-06 20:24:08 +0000811 } else {
Hiroshi Yamauchi1e3db872017-03-02 13:39:07 -0800812 Zygote.resetNicePriority();
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000813 }
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900814
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900815 // Do an initial gc to clean up after startup
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800816 bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900817 gcAndFinalize();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800818 bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900819
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800820 bootTimingsTraceLog.traceEnd(); // ZygoteInit
Jamie Gennis6ad04522013-04-15 18:53:24 -0700821 // Disable tracing so that forked processes do not inherit stale tracing tags from
822 // Zygote.
John Reck62cc1192017-05-12 15:39:51 -0700823 Trace.setTracingEnabled(false, 0);
Jamie Gennis6ad04522013-04-15 18:53:24 -0700824
Victor Hsiehc8176ef2018-01-08 12:43:00 -0800825 Zygote.nativeSecurityInit();
826
doheon1.lee885b7422016-01-20 13:07:27 +0900827 // Zygote process unmounts root storage spaces.
828 Zygote.nativeUnmountStorageOnInit();
829
Andreas Gampe1ef8aef2016-04-11 08:39:52 -0700830 ZygoteHooks.stopZygoteNoThreadCreation();
831
Narayan Kamathc41638c2014-04-07 13:56:15 +0100832 if (startSystemServer) {
Narayan Kamathbf99d062017-07-05 14:45:38 +0100833 Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
834
835 // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
836 // child (system_server) process.
837 if (r != null) {
838 r.run();
839 return;
840 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800841 }
842
843 Log.i(TAG, "Accepting command socket connections");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800844
Narayan Kamathbf99d062017-07-05 14:45:38 +0100845 // The select loop returns early in the child process after a fork and
846 // loops forever in the zygote.
847 caller = zygoteServer.runSelectLoop(abiList);
Christopher Ferrisea8b5de2016-06-17 15:29:58 -0700848 } catch (Throwable ex) {
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000849 Log.e(TAG, "System zygote died with exception", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800850 throw ex;
Narayan Kamathbf99d062017-07-05 14:45:38 +0100851 } finally {
852 zygoteServer.closeServerSocket();
853 }
854
855 // We're in the child process and have exited the select loop. Proceed to execute the
856 // command.
857 if (caller != null) {
858 caller.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800859 }
860 }
861
862 /**
Narayan Kamath64cd9072014-05-13 13:35:14 +0100863 * Return {@code true} if this device configuration has another zygote.
864 *
865 * We determine this by comparing the device ABI list with this zygotes
866 * list. If this zygote supports all ABIs this device supports, there won't
867 * be another zygote.
868 */
869 private static boolean hasSecondZygote(String abiList) {
870 return !SystemProperties.get("ro.product.cpu.abilist").equals(abiList);
871 }
872
873 private static void waitForSecondaryZygote(String socketName) {
874 String otherZygoteName = Process.ZYGOTE_SOCKET.equals(socketName) ?
875 Process.SECONDARY_ZYGOTE_SOCKET : Process.ZYGOTE_SOCKET;
Gustav Senntonf0c52b52017-04-27 17:00:50 +0100876 ZygoteProcess.waitForConnectionToZygote(otherZygoteName);
Narayan Kamath64cd9072014-05-13 13:35:14 +0100877 }
878
Narayan Kamath669afcc2017-02-06 20:24:08 +0000879 static boolean isPreloadComplete() {
880 return sPreloadComplete;
881 }
882
Narayan Kamath64cd9072014-05-13 13:35:14 +0100883 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800884 * Class not instantiable.
885 */
886 private ZygoteInit() {
887 }
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800888
889 /**
890 * The main function called when started through the zygote process. This
891 * could be unified with main(), if the native code in nativeFinishInit()
892 * were rationalized with Zygote startup.<p>
893 *
894 * Current recognized args:
895 * <ul>
896 * <li> <code> [--] &lt;start class name&gt; &lt;args&gt;
897 * </ul>
898 *
899 * @param targetSdkVersion target SDK version
900 * @param argv arg strings
901 */
Narayan Kamathbf99d062017-07-05 14:45:38 +0100902 public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800903 if (RuntimeInit.DEBUG) {
904 Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
905 }
906
907 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
908 RuntimeInit.redirectLogStreams();
909
910 RuntimeInit.commonInit();
911 ZygoteInit.nativeZygoteInit();
Narayan Kamathbf99d062017-07-05 14:45:38 +0100912 return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800913 }
914
Robert Sesekd0a190df2018-02-12 18:46:01 -0500915 /**
916 * The main function called when starting a child zygote process. This is used as an
917 * alternative to zygoteInit(), which skips calling into initialization routines that
918 * start the Binder threadpool.
919 */
920 static final Runnable childZygoteInit(
921 int targetSdkVersion, String[] argv, ClassLoader classLoader) {
922 RuntimeInit.Arguments args = new RuntimeInit.Arguments(argv);
923 return RuntimeInit.findStaticMain(args.startClass, args.startArgs, classLoader);
924 }
925
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800926 private static final native void nativeZygoteInit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800927}