blob: 39279b5055b1863191e1ed0690747165c5fc356d [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;
33import android.os.ServiceManager;
34import android.os.ServiceSpecificException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035import android.os.SystemClock;
Romain Guyc5e36382013-05-09 11:08:17 -070036import android.os.SystemProperties;
Jamie Gennis6ad04522013-04-15 18:53:24 -070037import android.os.Trace;
Robert Sesek8f8d1872016-03-18 16:52:57 -040038import android.os.ZygoteProcess;
Jeff Sharkeyc98c7bc2016-12-07 14:57:34 -070039import android.os.storage.StorageManager;
Sergio Giro69de3202016-05-17 16:52:33 +010040import android.security.keystore.AndroidKeyStoreProvider;
Bill Yi9a76e9b2014-04-29 18:52:48 -070041import android.system.ErrnoException;
Elliott Hughes860c5912014-04-28 19:19:13 -070042import android.system.Os;
43import android.system.OsConstants;
Luis Hector Chavez72042c92017-07-12 10:03:30 -070044import android.system.StructCapUserData;
45import android.system.StructCapUserHeader;
Raph Levienc3dd1c12015-04-06 10:37:57 -070046import android.text.Hyphenator;
Fyodor Kupolov6e3461b2017-08-10 17:00:43 -070047import android.util.TimingsTraceLog;
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;
Torne (Richard Coles)08cfaf62014-05-08 16:07:05 +010051import android.webkit.WebViewFactory;
Andreas Gampeddc13972016-02-26 16:54:59 -080052import android.widget.TextView;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -080054import com.android.internal.logging.MetricsLogger;
Jeff Sharkeyfdeeeea2016-01-11 17:34:24 -070055
Narayan Kamath669afcc2017-02-06 20:24:08 +000056import com.android.internal.util.Preconditions;
Narayan Kamath29564cd2014-08-07 10:57:40 +010057import dalvik.system.DexFile;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058import dalvik.system.VMRuntime;
Andreas Gampe1ef8aef2016-04-11 08:39:52 -070059import dalvik.system.ZygoteHooks;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060
Brian Carlstrom46703b02011-04-06 15:41:29 -070061import libcore.io.IoUtils;
62
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063import java.io.BufferedReader;
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -070064import java.io.File;
Ying Wangd0c45352014-11-13 15:22:47 -080065import java.io.FileInputStream;
66import java.io.FileNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067import java.io.IOException;
68import java.io.InputStream;
69import java.io.InputStreamReader;
Sergio Giro6cb7b1c2016-05-13 16:34:46 +010070import java.security.Security;
71import java.security.Provider;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072
73/**
74 * Startup class for the zygote process.
75 *
76 * Pre-initializes some classes, and then waits for commands on a UNIX domain
Elliott Hughese1dfcb72011-07-08 11:08:07 -070077 * socket. Based on these commands, forks off child processes that inherit
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078 * the initial state of the VM.
79 *
80 * Please see {@link ZygoteConnection.Arguments} for documentation on the
81 * client protocol.
82 *
83 * @hide
84 */
85public class ZygoteInit {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086 private static final String TAG = "Zygote";
87
Jesse Hall2852a282017-01-17 10:17:41 -080088 private static final String PROPERTY_DISABLE_OPENGL_PRELOADING = "ro.zygote.disable_gl_preload";
Jesse Hallba0370e2017-02-09 14:43:14 -080089 private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
Romain Guyc5e36382013-05-09 11:08:17 -070090
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091 private static final int LOG_BOOT_PROGRESS_PRELOAD_START = 3020;
92 private static final int LOG_BOOT_PROGRESS_PRELOAD_END = 3030;
93
94 /** when preloading, GC after allocating this many bytes */
95 private static final int PRELOAD_GC_THRESHOLD = 50000;
96
Narayan Kamathc41638c2014-04-07 13:56:15 +010097 private static final String ABI_LIST_ARG = "--abi-list=";
98
99 private static final String SOCKET_NAME_ARG = "--socket-name=";
Barry Hayes0b3533a2010-01-20 12:46:47 -0800100
David Brazdil464ed3d2018-01-18 15:25:18 +0000101 /* Dexopt flag to disable hidden API access checks when dexopting SystemServer.
102 * Must be kept in sync with com.android.server.pm.Installer. */
103 private static final int DEXOPT_DISABLE_HIDDEN_API_CHECKS = 1 << 10;
104
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105 /**
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000106 * Used to pre-load resources.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107 */
108 private static Resources mResources;
Bob Leee5408332009-09-04 18:31:17 -0700109
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110 /**
Ying Wangd0c45352014-11-13 15:22:47 -0800111 * The path of a file that contains classes to preload.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112 */
Ying Wangd0c45352014-11-13 15:22:47 -0800113 private static final String PRELOADED_CLASSES = "/system/etc/preloaded-classes";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114
115 /** Controls whether we should preload resources during zygote init. */
Steve Paik3c27a232015-06-10 18:25:44 -0700116 public static final boolean PRELOAD_RESOURCES = true;
Andy McFadden599c9182009-04-08 00:35:56 -0700117
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800118 private static final int UNPRIVILEGED_UID = 9999;
119 private static final int UNPRIVILEGED_GID = 9999;
120
121 private static final int ROOT_UID = 0;
122 private static final int ROOT_GID = 0;
123
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000124 private static boolean sPreloadComplete;
125
Fyodor Kupolov6e3461b2017-08-10 17:00:43 -0700126 static void preload(TimingsTraceLog bootTimingsTraceLog) {
Bill Yi9a76e9b2014-04-29 18:52:48 -0700127 Log.d(TAG, "begin preload");
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800128 bootTimingsTraceLog.traceBegin("BeginIcuCachePinning");
Neil Fuller4f41f612016-05-09 16:55:36 +0100129 beginIcuCachePinning();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800130 bootTimingsTraceLog.traceEnd(); // BeginIcuCachePinning
131 bootTimingsTraceLog.traceBegin("PreloadClasses");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900132 preloadClasses();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800133 bootTimingsTraceLog.traceEnd(); // PreloadClasses
134 bootTimingsTraceLog.traceBegin("PreloadResources");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900135 preloadResources();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800136 bootTimingsTraceLog.traceEnd(); // PreloadResources
Jesse Hall1fe1dc02017-07-06 15:30:39 -0700137 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs");
138 nativePreloadAppProcessHALs();
139 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Jesse Hallba0370e2017-02-09 14:43:14 -0800140 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadOpenGL");
141 preloadOpenGL();
142 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Brian Carlstrom6c9af962014-09-11 15:36:00 -0700143 preloadSharedLibraries();
Raph Levienc3dd1c12015-04-06 10:37:57 -0700144 preloadTextResources();
Torne (Richard Coles)08cfaf62014-05-08 16:07:05 +0100145 // Ask the WebViewFactory to do any initialization that must run in the zygote process,
146 // for memory sharing purposes.
147 WebViewFactory.prepareWebViewInZygote();
Neil Fuller4f41f612016-05-09 16:55:36 +0100148 endIcuCachePinning();
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100149 warmUpJcaProviders();
Bill Yi9a76e9b2014-04-29 18:52:48 -0700150 Log.d(TAG, "end preload");
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000151
152 sPreloadComplete = true;
153 }
154
Narayan Kamath669afcc2017-02-06 20:24:08 +0000155 public static void lazyPreload() {
156 Preconditions.checkState(!sPreloadComplete);
157 Log.i(TAG, "Lazily preloading resources.");
158
Fyodor Kupolov6e3461b2017-08-10 17:00:43 -0700159 preload(new TimingsTraceLog("ZygoteInitTiming_lazy", Trace.TRACE_TAG_DALVIK));
Romain Guy74c69122013-05-08 17:54:20 -0700160 }
161
Neil Fuller4f41f612016-05-09 16:55:36 +0100162 private static void beginIcuCachePinning() {
163 // Pin ICU data in memory from this point that would normally be held by soft references.
164 // Without this, any references created immediately below or during class preloading
165 // would be collected when the Zygote GC runs in gcAndFinalize().
166 Log.i(TAG, "Installing ICU cache reference pinning...");
167
168 CacheValue.setStrength(CacheValue.Strength.STRONG);
169
170 Log.i(TAG, "Preloading ICU data...");
171 // Explicitly exercise code to cache data apps are likely to need.
172 ULocale[] localesToPin = { ULocale.ROOT, ULocale.US, ULocale.getDefault() };
173 for (ULocale uLocale : localesToPin) {
174 new DecimalFormatSymbols(uLocale);
175 }
176 }
177
178 private static void endIcuCachePinning() {
179 // All cache references created by ICU from this point will be soft.
180 CacheValue.setStrength(CacheValue.Strength.SOFT);
181
182 Log.i(TAG, "Uninstalled ICU cache reference pinning...");
183 }
184
Brian Carlstrom6c9af962014-09-11 15:36:00 -0700185 private static void preloadSharedLibraries() {
186 Log.i(TAG, "Preloading shared libraries...");
187 System.loadLibrary("android");
188 System.loadLibrary("compiler_rt");
189 System.loadLibrary("jnigraphics");
190 }
191
Jesse Hall1fe1dc02017-07-06 15:30:39 -0700192 native private static void nativePreloadAppProcessHALs();
193
Jesse Hallba0370e2017-02-09 14:43:14 -0800194 private static void preloadOpenGL() {
195 String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
Jesse Hall5d911fe2017-04-13 15:44:24 -0700196 if (!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING, false) &&
197 (driverPackageName == null || driverPackageName.isEmpty())) {
Jesse Hallba0370e2017-02-09 14:43:14 -0800198 EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
199 }
200 }
201
Raph Levienc3dd1c12015-04-06 10:37:57 -0700202 private static void preloadTextResources() {
203 Hyphenator.init();
Andreas Gampeddc13972016-02-26 16:54:59 -0800204 TextView.preloadFontCache();
Raph Levienc3dd1c12015-04-06 10:37:57 -0700205 }
206
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207 /**
Sergio Giro69de3202016-05-17 16:52:33 +0100208 * Register AndroidKeyStoreProvider and warm up the providers that are already registered.
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100209 *
210 * By doing it here we avoid that each app does it when requesting a service from the
211 * provider for the first time.
212 */
213 private static void warmUpJcaProviders() {
214 long startTime = SystemClock.uptimeMillis();
215 Trace.traceBegin(
Sergio Giro69de3202016-05-17 16:52:33 +0100216 Trace.TRACE_TAG_DALVIK, "Starting installation of AndroidKeyStoreProvider");
217 // AndroidKeyStoreProvider.install() manipulates the list of JCA providers to insert
218 // preferred providers. Note this is not done via security.properties as the JCA providers
219 // are not on the classpath in the case of, for example, raw dalvikvm runtimes.
220 AndroidKeyStoreProvider.install();
221 Log.i(TAG, "Installed AndroidKeyStoreProvider in "
222 + (SystemClock.uptimeMillis() - startTime) + "ms.");
223 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
224
225 startTime = SystemClock.uptimeMillis();
226 Trace.traceBegin(
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100227 Trace.TRACE_TAG_DALVIK, "Starting warm up of JCA providers");
228 for (Provider p : Security.getProviders()) {
229 p.warmUpServiceProvision();
230 }
231 Log.i(TAG, "Warmed up JCA providers in "
Sergio Giro69de3202016-05-17 16:52:33 +0100232 + (SystemClock.uptimeMillis() - startTime) + "ms.");
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100233 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
234 }
235
236 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800237 * Performs Zygote process initialization. Loads and initializes
238 * commonly used classes.
239 *
240 * Most classes only cause a few hundred bytes to be allocated, but
241 * a few will allocate a dozen Kbytes (in one case, 500+K).
242 */
243 private static void preloadClasses() {
244 final VMRuntime runtime = VMRuntime.getRuntime();
Bob Leee5408332009-09-04 18:31:17 -0700245
Ying Wangd0c45352014-11-13 15:22:47 -0800246 InputStream is;
247 try {
248 is = new FileInputStream(PRELOADED_CLASSES);
249 } catch (FileNotFoundException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250 Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + ".");
Ying Wangd0c45352014-11-13 15:22:47 -0800251 return;
252 }
Bob Leee5408332009-09-04 18:31:17 -0700253
Ying Wangd0c45352014-11-13 15:22:47 -0800254 Log.i(TAG, "Preloading classes...");
255 long startTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800256
Ying Wangd0c45352014-11-13 15:22:47 -0800257 // Drop root perms while running static initializers.
Narayan Kamath23e68782015-01-16 17:22:41 +0000258 final int reuid = Os.getuid();
259 final int regid = Os.getgid();
260
261 // We need to drop root perms only if we're already root. In the case of "wrapped"
262 // processes (see WrapperInit), this function is called from an unprivileged uid
263 // and gid.
264 boolean droppedPriviliges = false;
265 if (reuid == ROOT_UID && regid == ROOT_GID) {
266 try {
267 Os.setregid(ROOT_GID, UNPRIVILEGED_GID);
268 Os.setreuid(ROOT_UID, UNPRIVILEGED_UID);
269 } catch (ErrnoException ex) {
270 throw new RuntimeException("Failed to drop root", ex);
271 }
272
273 droppedPriviliges = true;
Elliott Hughes26b56e62014-12-17 12:28:29 -0800274 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800275
Ying Wangd0c45352014-11-13 15:22:47 -0800276 // Alter the target heap utilization. With explicit GCs this
277 // is not likely to have any effect.
278 float defaultUtilization = runtime.getTargetHeapUtilization();
279 runtime.setTargetHeapUtilization(0.8f);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800280
Ying Wangd0c45352014-11-13 15:22:47 -0800281 try {
282 BufferedReader br
283 = new BufferedReader(new InputStreamReader(is), 256);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800284
Ying Wangd0c45352014-11-13 15:22:47 -0800285 int count = 0;
286 String line;
287 while ((line = br.readLine()) != null) {
288 // Skip comments and blank lines.
289 line = line.trim();
290 if (line.startsWith("#") || line.equals("")) {
291 continue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800292 }
293
Andreas Gampec4253622016-10-28 18:19:30 -0700294 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, line);
Ying Wangd0c45352014-11-13 15:22:47 -0800295 try {
296 if (false) {
297 Log.v(TAG, "Preloading " + line + "...");
298 }
Andreas Gampedd8e5fb2015-04-21 09:01:51 -0700299 // Load and explicitly initialize the given class. Use
300 // Class.forName(String, boolean, ClassLoader) to avoid repeated stack lookups
301 // (to derive the caller's class-loader). Use true to force initialization, and
302 // null for the boot classpath class-loader (could as well cache the
303 // class-loader of this class in a variable).
Andreas Gampec917f742015-04-20 19:16:37 -0700304 Class.forName(line, true, null);
Ying Wangd0c45352014-11-13 15:22:47 -0800305 count++;
306 } catch (ClassNotFoundException e) {
307 Log.w(TAG, "Class not found for preloading: " + line);
308 } catch (UnsatisfiedLinkError e) {
309 Log.w(TAG, "Problem preloading " + line + ": " + e);
310 } catch (Throwable t) {
311 Log.e(TAG, "Error preloading " + line + ".", t);
312 if (t instanceof Error) {
313 throw (Error) t;
314 }
315 if (t instanceof RuntimeException) {
316 throw (RuntimeException) t;
317 }
318 throw new RuntimeException(t);
319 }
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900320 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800321 }
Ying Wangd0c45352014-11-13 15:22:47 -0800322
323 Log.i(TAG, "...preloaded " + count + " classes in "
324 + (SystemClock.uptimeMillis()-startTime) + "ms.");
325 } catch (IOException e) {
326 Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);
327 } finally {
328 IoUtils.closeQuietly(is);
329 // Restore default.
330 runtime.setTargetHeapUtilization(defaultUtilization);
331
332 // Fill in dex caches with classes, fields, and methods brought in by preloading.
Yasuhiro Matsuda1ab43d52015-06-30 17:07:32 +0900333 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadDexCaches");
Ying Wangd0c45352014-11-13 15:22:47 -0800334 runtime.preloadDexCaches();
Yasuhiro Matsuda1ab43d52015-06-30 17:07:32 +0900335 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Ying Wangd0c45352014-11-13 15:22:47 -0800336
Narayan Kamath23e68782015-01-16 17:22:41 +0000337 // Bring back root. We'll need it later if we're in the zygote.
338 if (droppedPriviliges) {
339 try {
340 Os.setreuid(ROOT_UID, ROOT_UID);
341 Os.setregid(ROOT_GID, ROOT_GID);
342 } catch (ErrnoException ex) {
343 throw new RuntimeException("Failed to restore root", ex);
344 }
Elliott Hughes26b56e62014-12-17 12:28:29 -0800345 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800346 }
347 }
348
349 /**
350 * Load in commonly used resources, so they can be shared across
351 * processes.
352 *
353 * These tend to be a few Kbytes, but are frequently in the 20-40K
354 * range, and occasionally even larger.
355 */
356 private static void preloadResources() {
357 final VMRuntime runtime = VMRuntime.getRuntime();
Bob Leee5408332009-09-04 18:31:17 -0700358
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800359 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800360 mResources = Resources.getSystem();
361 mResources.startPreloading();
362 if (PRELOAD_RESOURCES) {
363 Log.i(TAG, "Preloading resources...");
364
365 long startTime = SystemClock.uptimeMillis();
366 TypedArray ar = mResources.obtainTypedArray(
367 com.android.internal.R.array.preloaded_drawables);
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800368 int N = preloadDrawables(ar);
Jeff Brown14577c42012-03-08 16:40:14 -0800369 ar.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800370 Log.i(TAG, "...preloaded " + N + " resources in "
371 + (SystemClock.uptimeMillis()-startTime) + "ms.");
372
373 startTime = SystemClock.uptimeMillis();
374 ar = mResources.obtainTypedArray(
375 com.android.internal.R.array.preloaded_color_state_lists);
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800376 N = preloadColorStateLists(ar);
Jeff Brown14577c42012-03-08 16:40:14 -0800377 ar.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800378 Log.i(TAG, "...preloaded " + N + " resources in "
379 + (SystemClock.uptimeMillis()-startTime) + "ms.");
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800380
381 if (mResources.getBoolean(
382 com.android.internal.R.bool.config_freeformWindowManagement)) {
383 startTime = SystemClock.uptimeMillis();
384 ar = mResources.obtainTypedArray(
385 com.android.internal.R.array.preloaded_freeform_multi_window_drawables);
386 N = preloadDrawables(ar);
387 ar.recycle();
388 Log.i(TAG, "...preloaded " + N + " resource in "
389 + (SystemClock.uptimeMillis() - startTime) + "ms.");
390 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800391 }
392 mResources.finishPreloading();
393 } catch (RuntimeException e) {
394 Log.w(TAG, "Failure preloading resources", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395 }
396 }
397
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800398 private static int preloadColorStateLists(TypedArray ar) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800399 int N = ar.length();
400 for (int i=0; i<N; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800401 int id = ar.getResourceId(i, 0);
Joe Onorato43a17652011-04-06 19:22:23 -0700402 if (false) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800403 Log.v(TAG, "Preloading resource #" + Integer.toHexString(id));
404 }
405 if (id != 0) {
Alan Viverette77bb6f12015-02-11 17:24:33 -0800406 if (mResources.getColorStateList(id, null) == null) {
Dianne Hackborndde331c2012-08-03 14:01:57 -0700407 throw new IllegalArgumentException(
408 "Unable to find preloaded color resource #0x"
409 + Integer.toHexString(id)
410 + " (" + ar.getString(i) + ")");
411 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800412 }
413 }
414 return N;
415 }
416
417
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800418 private static int preloadDrawables(TypedArray ar) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800419 int N = ar.length();
420 for (int i=0; i<N; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800421 int id = ar.getResourceId(i, 0);
Joe Onorato43a17652011-04-06 19:22:23 -0700422 if (false) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800423 Log.v(TAG, "Preloading resource #" + Integer.toHexString(id));
424 }
425 if (id != 0) {
Alan Viverette84e001a2014-09-22 00:04:22 -0700426 if (mResources.getDrawable(id, null) == null) {
Dianne Hackborndde331c2012-08-03 14:01:57 -0700427 throw new IllegalArgumentException(
428 "Unable to find preloaded drawable resource #0x"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800429 + Integer.toHexString(id)
Dianne Hackborndde331c2012-08-03 14:01:57 -0700430 + " (" + ar.getString(i) + ")");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800431 }
432 }
433 }
434 return N;
435 }
436
437 /**
438 * Runs several special GCs to try to clean up a few generations of
439 * softly- and final-reachable objects, along with any other garbage.
440 * This is only useful just before a fork().
441 */
Mathieu Chartier9a88f102014-08-20 10:24:11 -0700442 /*package*/ static void gcAndFinalize() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800443 final VMRuntime runtime = VMRuntime.getRuntime();
444
445 /* runFinalizationSync() lets finalizers be called in Zygote,
446 * which doesn't have a HeapWorker thread.
447 */
Brian Carlstrom08065b92011-04-01 15:49:41 -0700448 System.gc();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800449 runtime.runFinalizationSync();
Brian Carlstrom08065b92011-04-01 15:49:41 -0700450 System.gc();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800451 }
452
453 /**
454 * Finish remaining work for the newly forked system server process.
455 */
Narayan Kamathbf99d062017-07-05 14:45:38 +0100456 private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
Mike Lockwood90960e82010-08-06 09:15:25 -0400457 // set umask to 0077 so new files and directories will default to owner-only permissions.
Elliott Hughes860c5912014-04-28 19:19:13 -0700458 Os.umask(S_IRWXG | S_IRWXO);
Mike Lockwood90960e82010-08-06 09:15:25 -0400459
Jeff Brownebed7d62011-05-16 17:08:42 -0700460 if (parsedArgs.niceName != null) {
461 Process.setArgV0(parsedArgs.niceName);
462 }
463
Narayan Kamath29564cd2014-08-07 10:57:40 +0100464 final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
465 if (systemServerClasspath != null) {
466 performSystemServerDexOpt(systemServerClasspath);
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -0700467 // Capturing profiles is only supported for debug or eng builds since selinux normally
468 // prevents it.
469 boolean profileSystemServer = SystemProperties.getBoolean(
470 "dalvik.vm.profilesystemserver", false);
471 if (profileSystemServer && (Build.IS_USERDEBUG || Build.IS_ENG)) {
472 try {
473 File profileDir = Environment.getDataProfilesDePackageDirectory(
474 Process.SYSTEM_UID, "system_server");
475 File profile = new File(profileDir, "primary.prof");
476 profile.getParentFile().mkdirs();
477 profile.createNewFile();
478 String[] codePaths = systemServerClasspath.split(":");
479 VMRuntime.registerAppInfo(profile.getPath(), codePaths);
480 } catch (Exception e) {
481 Log.wtf(TAG, "Failed to set up system server profile", e);
482 }
483 }
Narayan Kamath29564cd2014-08-07 10:57:40 +0100484 }
485
Jeff Brownebed7d62011-05-16 17:08:42 -0700486 if (parsedArgs.invokeWith != null) {
Narayan Kamath29564cd2014-08-07 10:57:40 +0100487 String[] args = parsedArgs.remainingArgs;
488 // If we have a non-null system server class path, we'll have to duplicate the
489 // existing arguments and append the classpath to it. ART will handle the classpath
490 // correctly when we exec a new process.
491 if (systemServerClasspath != null) {
492 String[] amendedArgs = new String[args.length + 2];
493 amendedArgs[0] = "-cp";
494 amendedArgs[1] = systemServerClasspath;
tony.ys_liu34738172016-12-14 18:50:29 +0800495 System.arraycopy(args, 0, amendedArgs, 2, args.length);
496 args = amendedArgs;
Narayan Kamath29564cd2014-08-07 10:57:40 +0100497 }
498
Jeff Brownebed7d62011-05-16 17:08:42 -0700499 WrapperInit.execApplication(parsedArgs.invokeWith,
Elliott Hughese1dfcb72011-07-08 11:08:07 -0700500 parsedArgs.niceName, parsedArgs.targetSdkVersion,
Narayan Kamath37ad4b02015-01-19 16:05:24 +0000501 VMRuntime.getCurrentInstructionSet(), null, args);
Narayan Kamathbf99d062017-07-05 14:45:38 +0100502
503 throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
Jeff Brownebed7d62011-05-16 17:08:42 -0700504 } else {
Narayan Kamath29564cd2014-08-07 10:57:40 +0100505 ClassLoader cl = null;
506 if (systemServerClasspath != null) {
tony.ys_liu34738172016-12-14 18:50:29 +0800507 cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700508
Narayan Kamath29564cd2014-08-07 10:57:40 +0100509 Thread.currentThread().setContextClassLoader(cl);
510 }
511
Jeff Brownebed7d62011-05-16 17:08:42 -0700512 /*
513 * Pass the remaining arguments to SystemServer.
514 */
Narayan Kamathbf99d062017-07-05 14:45:38 +0100515 return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
Jeff Brownebed7d62011-05-16 17:08:42 -0700516 }
517
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800518 /* should never reach here */
519 }
520
521 /**
tony.ys_liu34738172016-12-14 18:50:29 +0800522 * Creates a PathClassLoader for the given class path that is associated with a shared
523 * namespace, i.e., this classloader can access platform-private native libraries. The
524 * classloader will use java.library.path as the native library path.
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700525 */
Narayan Kamathf9419f02017-06-15 11:35:38 +0100526 static ClassLoader createPathClassLoader(String classPath, int targetSdkVersion) {
527 String libraryPath = System.getProperty("java.library.path");
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700528
Narayan Kamathf9419f02017-06-15 11:35:38 +0100529 return ClassLoaderFactory.createClassLoader(classPath, libraryPath, libraryPath,
530 ClassLoader.getSystemClassLoader(), targetSdkVersion, true /* isNamespaceShared */,
531 null /* classLoaderName */);
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700532 }
533
534 /**
Narayan Kamath29564cd2014-08-07 10:57:40 +0100535 * Performs dex-opt on the elements of {@code classPath}, if needed. We
536 * choose the instruction set of the current runtime.
537 */
538 private static void performSystemServerDexOpt(String classPath) {
539 final String[] classPathElements = classPath.split(":");
Jeff Sharkey740f5232016-12-09 14:31:26 -0700540 final IInstalld installd = IInstalld.Stub
541 .asInterface(ServiceManager.getService("installd"));
Narayan Kamath29564cd2014-08-07 10:57:40 +0100542 final String instructionSet = VMRuntime.getRuntime().vmInstructionSet();
543
Calin Juravle2f09ff32017-07-24 15:29:56 -0700544 String classPathForElement = "";
Jeff Sharkey740f5232016-12-09 14:31:26 -0700545 for (String classPathElement : classPathElements) {
546 // System server is fully AOTed and never profiled
547 // for profile guided compilation.
Mathieu Chartier5e07a0d2017-06-15 19:09:38 -0700548 String systemServerFilter = SystemProperties.get(
549 "dalvik.vm.systemservercompilerfilter", "speed");
Andreas Gampee7bc1522016-08-09 20:44:04 -0700550
Jeff Sharkey740f5232016-12-09 14:31:26 -0700551 int dexoptNeeded;
552 try {
553 dexoptNeeded = DexFile.getDexOptNeeded(
Shubham Ajmera246dccf2017-05-24 17:46:36 -0700554 classPathElement, instructionSet, systemServerFilter,
Calin Juravle576e6c02017-09-12 00:58:33 -0700555 null /* classLoaderContext */, 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;
David Brazdil464ed3d2018-01-18 15:25:18 +0000572 // Dexopt with a flag which lifts restrictions on hidden API usage.
573 // Offending methods would otherwise be re-verified at runtime and
574 // we want to avoid the performance overhead of that.
575 final int dexFlags = DEXOPT_DISABLE_HIDDEN_API_CHECKS;
Mathieu Chartier5e07a0d2017-06-15 19:09:38 -0700576 final String compilerFilter = systemServerFilter;
Jeff Sharkey740f5232016-12-09 14:31:26 -0700577 final String uuid = StorageManager.UUID_PRIVATE_INTERNAL;
Calin Juravle811a75a2017-04-05 22:49:38 -0700578 final String seInfo = null;
Calin Juravle2f09ff32017-07-24 15:29:56 -0700579 final String classLoaderContext =
580 getSystemServerClassLoaderContext(classPathForElement);
David Brazdil3d44ed02018-01-16 20:01:47 +0000581 final int targetSdkVersion = 0; // SystemServer targets the system's SDK version
Jeff Sharkey740f5232016-12-09 14:31:26 -0700582 try {
583 installd.dexopt(classPathElement, Process.SYSTEM_UID, packageName,
584 instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter,
David Brazdil3d44ed02018-01-16 20:01:47 +0000585 uuid, classLoaderContext, seInfo, false /* downgrade */,
Calin Juravle6ae39fc2018-01-19 20:32:47 -0800586 targetSdkVersion, /*profileName*/ null);
Jeff Sharkey740f5232016-12-09 14:31:26 -0700587 } catch (RemoteException | ServiceSpecificException e) {
588 // Ignore (but log), we need this on the classpath for fallback mode.
589 Log.w(TAG, "Failed compiling classpath element for system server: "
590 + classPathElement, e);
591 }
592 }
593
Calin Juravle2f09ff32017-07-24 15:29:56 -0700594 classPathForElement = encodeSystemServerClassPath(
595 classPathForElement, classPathElement);
Narayan Kamath29564cd2014-08-07 10:57:40 +0100596 }
597 }
598
599 /**
Calin Juravle2f09ff32017-07-24 15:29:56 -0700600 * Encodes the system server class loader context in a format that is accepted by dexopt.
601 * This assumes the system server is always loaded with a {@link dalvik.system.PathClassLoader}.
602 *
603 * Note that ideally we would use the {@code DexoptUtils} to compute this. However we have no
604 * dependency here on the server so we hard code the logic again.
605 */
606 private static String getSystemServerClassLoaderContext(String classPath) {
607 return classPath == null ? "PCL[]" : "PCL[" + classPath + "]";
608 }
609
610 /**
611 * Encodes the class path in a format accepted by dexopt.
612 * @param classPath the old class path (may be empty).
613 * @param newElement the new class path elements
614 * @return the class path encoding resulted from appending {@code newElement} to
615 * {@code classPath}.
616 */
617 private static String encodeSystemServerClassPath(String classPath, String newElement) {
618 return (classPath == null || classPath.isEmpty())
619 ? newElement
620 : classPath + ":" + newElement;
621 }
622
623 /**
Narayan Kamathbf99d062017-07-05 14:45:38 +0100624 * Prepare the arguments and forks for the system server process.
625 *
626 * Returns an {@code Runnable} that provides an entrypoint into system_server code in the
627 * child process, and {@code null} in the parent.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800628 */
Narayan Kamathbf99d062017-07-05 14:45:38 +0100629 private static Runnable forkSystemServer(String abiList, String socketName,
630 ZygoteServer zygoteServer) {
Alex Klyubin48a06e72013-04-19 10:01:42 -0700631 long capabilities = posixCapabilitiesAsBits(
Philip Cuadra7bd0fdd2016-04-28 15:26:49 -0700632 OsConstants.CAP_IPC_LOCK,
Alex Klyubin48a06e72013-04-19 10:01:42 -0700633 OsConstants.CAP_KILL,
634 OsConstants.CAP_NET_ADMIN,
635 OsConstants.CAP_NET_BIND_SERVICE,
636 OsConstants.CAP_NET_BROADCAST,
637 OsConstants.CAP_NET_RAW,
Alex Klyubin48a06e72013-04-19 10:01:42 -0700638 OsConstants.CAP_SYS_MODULE,
639 OsConstants.CAP_SYS_NICE,
Nick Kralevich3082eb72017-02-15 15:12:31 -0800640 OsConstants.CAP_SYS_PTRACE,
Alex Klyubin48a06e72013-04-19 10:01:42 -0700641 OsConstants.CAP_SYS_TIME,
John Stultz5733f382016-07-28 12:35:31 -0700642 OsConstants.CAP_SYS_TTY_CONFIG,
Luis Hector Chavez72042c92017-07-12 10:03:30 -0700643 OsConstants.CAP_WAKE_ALARM,
644 OsConstants.CAP_BLOCK_SUSPEND
Alex Klyubin48a06e72013-04-19 10:01:42 -0700645 );
Luis Hector Chavez72042c92017-07-12 10:03:30 -0700646 /* Containers run without some capabilities, so drop any caps that are not available. */
647 StructCapUserHeader header = new StructCapUserHeader(
648 OsConstants._LINUX_CAPABILITY_VERSION_3, 0);
649 StructCapUserData[] data;
650 try {
651 data = Os.capget(header);
652 } catch (ErrnoException ex) {
653 throw new RuntimeException("Failed to capget()", ex);
Luis Hector Chavez5dd239a2015-10-06 14:01:45 -0700654 }
Luis Hector Chavez72042c92017-07-12 10:03:30 -0700655 capabilities &= ((long) data[0].effective) | (((long) data[1].effective) << 32);
656
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800657 /* Hardcoded command line to start the system server */
658 String args[] = {
659 "--setuid=1000",
660 "--setgid=1000",
Jeff Sharkey4a539442018-01-05 17:09:52 -0700661 "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,1065,3001,3002,3003,3006,3007,3009,3010",
Alex Klyubin48a06e72013-04-19 10:01:42 -0700662 "--capabilities=" + capabilities + "," + capabilities,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800663 "--nice-name=system_server",
Narayan Kamathb6b044a2015-02-13 17:31:25 +0000664 "--runtime-args",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800665 "com.android.server.SystemServer",
666 };
667 ZygoteConnection.Arguments parsedArgs = null;
668
669 int pid;
670
671 try {
672 parsedArgs = new ZygoteConnection.Arguments(args);
Jeff Brownebed7d62011-05-16 17:08:42 -0700673 ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
674 ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800675
676 /* Request to fork the system server process */
677 pid = Zygote.forkSystemServer(
678 parsedArgs.uid, parsedArgs.gid,
Elliott Hughese1dfcb72011-07-08 11:08:07 -0700679 parsedArgs.gids,
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100680 parsedArgs.runtimeFlags,
Elliott Hughese1dfcb72011-07-08 11:08:07 -0700681 null,
Andy McFadden1b4c7962010-10-27 11:26:05 -0700682 parsedArgs.permittedCapabilities,
683 parsedArgs.effectiveCapabilities);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800684 } catch (IllegalArgumentException ex) {
685 throw new RuntimeException(ex);
Bob Leee5408332009-09-04 18:31:17 -0700686 }
687
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800688 /* For child process */
689 if (pid == 0) {
Narayan Kamath64cd9072014-05-13 13:35:14 +0100690 if (hasSecondZygote(abiList)) {
691 waitForSecondaryZygote(socketName);
692 }
693
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000694 zygoteServer.closeServerSocket();
Narayan Kamathbf99d062017-07-05 14:45:38 +0100695 return handleSystemServerProcess(parsedArgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800696 }
697
Narayan Kamathbf99d062017-07-05 14:45:38 +0100698 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800699 }
700
Alex Klyubin48a06e72013-04-19 10:01:42 -0700701 /**
702 * Gets the bit array representation of the provided list of POSIX capabilities.
703 */
704 private static long posixCapabilitiesAsBits(int... capabilities) {
705 long result = 0;
706 for (int capability : capabilities) {
707 if ((capability < 0) || (capability > OsConstants.CAP_LAST_CAP)) {
708 throw new IllegalArgumentException(String.valueOf(capability));
709 }
710 result |= (1L << capability);
711 }
712 return result;
713 }
714
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800715 public static void main(String argv[]) {
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000716 ZygoteServer zygoteServer = new ZygoteServer();
717
Andreas Gampe1ef8aef2016-04-11 08:39:52 -0700718 // Mark zygote start. This ensures that thread creation will throw
719 // an error.
720 ZygoteHooks.startZygoteNoThreadCreation();
721
Robert Seseke4f8d692016-09-13 19:13:01 -0400722 // Zygote goes into its own process group.
723 try {
724 Os.setpgid(0, 0);
725 } catch (ErrnoException ex) {
726 throw new RuntimeException("Failed to setpgid(0,0)", ex);
727 }
728
Narayan Kamathbf99d062017-07-05 14:45:38 +0100729 final Runnable caller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800730 try {
Fyodor Kupolov6733e6c2017-01-06 18:27:05 -0800731 // Report Zygote start time to tron unless it is a runtime restart
732 if (!"1".equals(SystemProperties.get("sys.boot_completed"))) {
733 MetricsLogger.histogram(null, "boot_zygote_init",
734 (int) SystemClock.elapsedRealtime());
735 }
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800736
737 String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
Fyodor Kupolov6e3461b2017-08-10 17:00:43 -0700738 TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag,
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800739 Trace.TRACE_TAG_DALVIK);
740 bootTimingsTraceLog.traceBegin("ZygoteInit");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900741 RuntimeInit.enableDdms();
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900742
Narayan Kamathc41638c2014-04-07 13:56:15 +0100743 boolean startSystemServer = false;
744 String socketName = "zygote";
745 String abiList = null;
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000746 boolean enableLazyPreload = false;
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900747 for (int i = 1; i < argv.length; i++) {
748 if ("start-system-server".equals(argv[i])) {
749 startSystemServer = true;
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000750 } else if ("--enable-lazy-preload".equals(argv[i])) {
751 enableLazyPreload = true;
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900752 } else if (argv[i].startsWith(ABI_LIST_ARG)) {
753 abiList = argv[i].substring(ABI_LIST_ARG.length());
754 } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
755 socketName = argv[i].substring(SOCKET_NAME_ARG.length());
756 } else {
757 throw new RuntimeException("Unknown command line argument: " + argv[i]);
Narayan Kamathc41638c2014-04-07 13:56:15 +0100758 }
759 }
760
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900761 if (abiList == null) {
762 throw new RuntimeException("No ABI list supplied.");
763 }
764
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000765 zygoteServer.registerServerSocket(socketName);
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000766 // In some configurations, we avoid preloading resources and classes eagerly.
767 // In such cases, we will preload things prior to our first fork.
768 if (!enableLazyPreload) {
769 bootTimingsTraceLog.traceBegin("ZygotePreload");
770 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
771 SystemClock.uptimeMillis());
772 preload(bootTimingsTraceLog);
773 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
774 SystemClock.uptimeMillis());
775 bootTimingsTraceLog.traceEnd(); // ZygotePreload
Narayan Kamathb49996d2017-02-06 20:24:08 +0000776 } else {
Hiroshi Yamauchi1e3db872017-03-02 13:39:07 -0800777 Zygote.resetNicePriority();
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000778 }
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900779
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900780 // Do an initial gc to clean up after startup
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800781 bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900782 gcAndFinalize();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800783 bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900784
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800785 bootTimingsTraceLog.traceEnd(); // ZygoteInit
Jamie Gennis6ad04522013-04-15 18:53:24 -0700786 // Disable tracing so that forked processes do not inherit stale tracing tags from
787 // Zygote.
John Reck62cc1192017-05-12 15:39:51 -0700788 Trace.setTracingEnabled(false, 0);
Jamie Gennis6ad04522013-04-15 18:53:24 -0700789
Victor Hsiehc8176ef2018-01-08 12:43:00 -0800790 Zygote.nativeSecurityInit();
791
doheon1.lee885b7422016-01-20 13:07:27 +0900792 // Zygote process unmounts root storage spaces.
793 Zygote.nativeUnmountStorageOnInit();
794
Andreas Gampe1ef8aef2016-04-11 08:39:52 -0700795 ZygoteHooks.stopZygoteNoThreadCreation();
796
Narayan Kamathc41638c2014-04-07 13:56:15 +0100797 if (startSystemServer) {
Narayan Kamathbf99d062017-07-05 14:45:38 +0100798 Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
799
800 // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
801 // child (system_server) process.
802 if (r != null) {
803 r.run();
804 return;
805 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800806 }
807
808 Log.i(TAG, "Accepting command socket connections");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800809
Narayan Kamathbf99d062017-07-05 14:45:38 +0100810 // The select loop returns early in the child process after a fork and
811 // loops forever in the zygote.
812 caller = zygoteServer.runSelectLoop(abiList);
Christopher Ferrisea8b5de2016-06-17 15:29:58 -0700813 } catch (Throwable ex) {
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000814 Log.e(TAG, "System zygote died with exception", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800815 throw ex;
Narayan Kamathbf99d062017-07-05 14:45:38 +0100816 } finally {
817 zygoteServer.closeServerSocket();
818 }
819
820 // We're in the child process and have exited the select loop. Proceed to execute the
821 // command.
822 if (caller != null) {
823 caller.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800824 }
825 }
826
827 /**
Narayan Kamath64cd9072014-05-13 13:35:14 +0100828 * Return {@code true} if this device configuration has another zygote.
829 *
830 * We determine this by comparing the device ABI list with this zygotes
831 * list. If this zygote supports all ABIs this device supports, there won't
832 * be another zygote.
833 */
834 private static boolean hasSecondZygote(String abiList) {
835 return !SystemProperties.get("ro.product.cpu.abilist").equals(abiList);
836 }
837
838 private static void waitForSecondaryZygote(String socketName) {
839 String otherZygoteName = Process.ZYGOTE_SOCKET.equals(socketName) ?
840 Process.SECONDARY_ZYGOTE_SOCKET : Process.ZYGOTE_SOCKET;
Gustav Senntonf0c52b52017-04-27 17:00:50 +0100841 ZygoteProcess.waitForConnectionToZygote(otherZygoteName);
Narayan Kamath64cd9072014-05-13 13:35:14 +0100842 }
843
Narayan Kamath669afcc2017-02-06 20:24:08 +0000844 static boolean isPreloadComplete() {
845 return sPreloadComplete;
846 }
847
Narayan Kamath64cd9072014-05-13 13:35:14 +0100848 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800849 * Class not instantiable.
850 */
851 private ZygoteInit() {
852 }
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800853
854 /**
855 * The main function called when started through the zygote process. This
856 * could be unified with main(), if the native code in nativeFinishInit()
857 * were rationalized with Zygote startup.<p>
858 *
859 * Current recognized args:
860 * <ul>
861 * <li> <code> [--] &lt;start class name&gt; &lt;args&gt;
862 * </ul>
863 *
864 * @param targetSdkVersion target SDK version
865 * @param argv arg strings
866 */
Narayan Kamathbf99d062017-07-05 14:45:38 +0100867 public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800868 if (RuntimeInit.DEBUG) {
869 Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
870 }
871
872 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
873 RuntimeInit.redirectLogStreams();
874
875 RuntimeInit.commonInit();
876 ZygoteInit.nativeZygoteInit();
Narayan Kamathbf99d062017-07-05 14:45:38 +0100877 return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800878 }
879
880 private static final native void nativeZygoteInit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800881}