blob: 2671f2947530e87a329f24f1147c3c430e508624 [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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101 /**
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000102 * Used to pre-load resources.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103 */
104 private static Resources mResources;
Bob Leee5408332009-09-04 18:31:17 -0700105
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106 /**
Ying Wangd0c45352014-11-13 15:22:47 -0800107 * The path of a file that contains classes to preload.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108 */
Ying Wangd0c45352014-11-13 15:22:47 -0800109 private static final String PRELOADED_CLASSES = "/system/etc/preloaded-classes";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110
111 /** Controls whether we should preload resources during zygote init. */
Steve Paik3c27a232015-06-10 18:25:44 -0700112 public static final boolean PRELOAD_RESOURCES = true;
Andy McFadden599c9182009-04-08 00:35:56 -0700113
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114 private static final int UNPRIVILEGED_UID = 9999;
115 private static final int UNPRIVILEGED_GID = 9999;
116
117 private static final int ROOT_UID = 0;
118 private static final int ROOT_GID = 0;
119
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000120 private static boolean sPreloadComplete;
121
Fyodor Kupolov6e3461b2017-08-10 17:00:43 -0700122 static void preload(TimingsTraceLog bootTimingsTraceLog) {
Bill Yi9a76e9b2014-04-29 18:52:48 -0700123 Log.d(TAG, "begin preload");
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800124 bootTimingsTraceLog.traceBegin("BeginIcuCachePinning");
Neil Fuller4f41f612016-05-09 16:55:36 +0100125 beginIcuCachePinning();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800126 bootTimingsTraceLog.traceEnd(); // BeginIcuCachePinning
127 bootTimingsTraceLog.traceBegin("PreloadClasses");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900128 preloadClasses();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800129 bootTimingsTraceLog.traceEnd(); // PreloadClasses
130 bootTimingsTraceLog.traceBegin("PreloadResources");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900131 preloadResources();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800132 bootTimingsTraceLog.traceEnd(); // PreloadResources
Jesse Hall1fe1dc02017-07-06 15:30:39 -0700133 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs");
134 nativePreloadAppProcessHALs();
135 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Jesse Hallba0370e2017-02-09 14:43:14 -0800136 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadOpenGL");
137 preloadOpenGL();
138 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Brian Carlstrom6c9af962014-09-11 15:36:00 -0700139 preloadSharedLibraries();
Raph Levienc3dd1c12015-04-06 10:37:57 -0700140 preloadTextResources();
Torne (Richard Coles)08cfaf62014-05-08 16:07:05 +0100141 // Ask the WebViewFactory to do any initialization that must run in the zygote process,
142 // for memory sharing purposes.
143 WebViewFactory.prepareWebViewInZygote();
Neil Fuller4f41f612016-05-09 16:55:36 +0100144 endIcuCachePinning();
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100145 warmUpJcaProviders();
Bill Yi9a76e9b2014-04-29 18:52:48 -0700146 Log.d(TAG, "end preload");
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000147
148 sPreloadComplete = true;
149 }
150
Narayan Kamath669afcc2017-02-06 20:24:08 +0000151 public static void lazyPreload() {
152 Preconditions.checkState(!sPreloadComplete);
153 Log.i(TAG, "Lazily preloading resources.");
154
Fyodor Kupolov6e3461b2017-08-10 17:00:43 -0700155 preload(new TimingsTraceLog("ZygoteInitTiming_lazy", Trace.TRACE_TAG_DALVIK));
Romain Guy74c69122013-05-08 17:54:20 -0700156 }
157
Neil Fuller4f41f612016-05-09 16:55:36 +0100158 private static void beginIcuCachePinning() {
159 // Pin ICU data in memory from this point that would normally be held by soft references.
160 // Without this, any references created immediately below or during class preloading
161 // would be collected when the Zygote GC runs in gcAndFinalize().
162 Log.i(TAG, "Installing ICU cache reference pinning...");
163
164 CacheValue.setStrength(CacheValue.Strength.STRONG);
165
166 Log.i(TAG, "Preloading ICU data...");
167 // Explicitly exercise code to cache data apps are likely to need.
168 ULocale[] localesToPin = { ULocale.ROOT, ULocale.US, ULocale.getDefault() };
169 for (ULocale uLocale : localesToPin) {
170 new DecimalFormatSymbols(uLocale);
171 }
172 }
173
174 private static void endIcuCachePinning() {
175 // All cache references created by ICU from this point will be soft.
176 CacheValue.setStrength(CacheValue.Strength.SOFT);
177
178 Log.i(TAG, "Uninstalled ICU cache reference pinning...");
179 }
180
Brian Carlstrom6c9af962014-09-11 15:36:00 -0700181 private static void preloadSharedLibraries() {
182 Log.i(TAG, "Preloading shared libraries...");
183 System.loadLibrary("android");
184 System.loadLibrary("compiler_rt");
185 System.loadLibrary("jnigraphics");
186 }
187
Jesse Hall1fe1dc02017-07-06 15:30:39 -0700188 native private static void nativePreloadAppProcessHALs();
189
Jesse Hallba0370e2017-02-09 14:43:14 -0800190 private static void preloadOpenGL() {
191 String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
Jesse Hall5d911fe2017-04-13 15:44:24 -0700192 if (!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING, false) &&
193 (driverPackageName == null || driverPackageName.isEmpty())) {
Jesse Hallba0370e2017-02-09 14:43:14 -0800194 EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
195 }
196 }
197
Raph Levienc3dd1c12015-04-06 10:37:57 -0700198 private static void preloadTextResources() {
199 Hyphenator.init();
Andreas Gampeddc13972016-02-26 16:54:59 -0800200 TextView.preloadFontCache();
Raph Levienc3dd1c12015-04-06 10:37:57 -0700201 }
202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800203 /**
Sergio Giro69de3202016-05-17 16:52:33 +0100204 * Register AndroidKeyStoreProvider and warm up the providers that are already registered.
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100205 *
206 * By doing it here we avoid that each app does it when requesting a service from the
207 * provider for the first time.
208 */
209 private static void warmUpJcaProviders() {
210 long startTime = SystemClock.uptimeMillis();
211 Trace.traceBegin(
Sergio Giro69de3202016-05-17 16:52:33 +0100212 Trace.TRACE_TAG_DALVIK, "Starting installation of AndroidKeyStoreProvider");
213 // AndroidKeyStoreProvider.install() manipulates the list of JCA providers to insert
214 // preferred providers. Note this is not done via security.properties as the JCA providers
215 // are not on the classpath in the case of, for example, raw dalvikvm runtimes.
216 AndroidKeyStoreProvider.install();
217 Log.i(TAG, "Installed AndroidKeyStoreProvider in "
218 + (SystemClock.uptimeMillis() - startTime) + "ms.");
219 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
220
221 startTime = SystemClock.uptimeMillis();
222 Trace.traceBegin(
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100223 Trace.TRACE_TAG_DALVIK, "Starting warm up of JCA providers");
224 for (Provider p : Security.getProviders()) {
225 p.warmUpServiceProvision();
226 }
227 Log.i(TAG, "Warmed up JCA providers in "
Sergio Giro69de3202016-05-17 16:52:33 +0100228 + (SystemClock.uptimeMillis() - startTime) + "ms.");
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100229 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
230 }
231
232 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800233 * Performs Zygote process initialization. Loads and initializes
234 * commonly used classes.
235 *
236 * Most classes only cause a few hundred bytes to be allocated, but
237 * a few will allocate a dozen Kbytes (in one case, 500+K).
238 */
239 private static void preloadClasses() {
240 final VMRuntime runtime = VMRuntime.getRuntime();
Bob Leee5408332009-09-04 18:31:17 -0700241
Ying Wangd0c45352014-11-13 15:22:47 -0800242 InputStream is;
243 try {
244 is = new FileInputStream(PRELOADED_CLASSES);
245 } catch (FileNotFoundException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800246 Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + ".");
Ying Wangd0c45352014-11-13 15:22:47 -0800247 return;
248 }
Bob Leee5408332009-09-04 18:31:17 -0700249
Ying Wangd0c45352014-11-13 15:22:47 -0800250 Log.i(TAG, "Preloading classes...");
251 long startTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800252
Ying Wangd0c45352014-11-13 15:22:47 -0800253 // Drop root perms while running static initializers.
Narayan Kamath23e68782015-01-16 17:22:41 +0000254 final int reuid = Os.getuid();
255 final int regid = Os.getgid();
256
257 // We need to drop root perms only if we're already root. In the case of "wrapped"
258 // processes (see WrapperInit), this function is called from an unprivileged uid
259 // and gid.
260 boolean droppedPriviliges = false;
261 if (reuid == ROOT_UID && regid == ROOT_GID) {
262 try {
263 Os.setregid(ROOT_GID, UNPRIVILEGED_GID);
264 Os.setreuid(ROOT_UID, UNPRIVILEGED_UID);
265 } catch (ErrnoException ex) {
266 throw new RuntimeException("Failed to drop root", ex);
267 }
268
269 droppedPriviliges = true;
Elliott Hughes26b56e62014-12-17 12:28:29 -0800270 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800271
Ying Wangd0c45352014-11-13 15:22:47 -0800272 // Alter the target heap utilization. With explicit GCs this
273 // is not likely to have any effect.
274 float defaultUtilization = runtime.getTargetHeapUtilization();
275 runtime.setTargetHeapUtilization(0.8f);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800276
Ying Wangd0c45352014-11-13 15:22:47 -0800277 try {
278 BufferedReader br
279 = new BufferedReader(new InputStreamReader(is), 256);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800280
Ying Wangd0c45352014-11-13 15:22:47 -0800281 int count = 0;
282 String line;
283 while ((line = br.readLine()) != null) {
284 // Skip comments and blank lines.
285 line = line.trim();
286 if (line.startsWith("#") || line.equals("")) {
287 continue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800288 }
289
Andreas Gampec4253622016-10-28 18:19:30 -0700290 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, line);
Ying Wangd0c45352014-11-13 15:22:47 -0800291 try {
292 if (false) {
293 Log.v(TAG, "Preloading " + line + "...");
294 }
Andreas Gampedd8e5fb2015-04-21 09:01:51 -0700295 // Load and explicitly initialize the given class. Use
296 // Class.forName(String, boolean, ClassLoader) to avoid repeated stack lookups
297 // (to derive the caller's class-loader). Use true to force initialization, and
298 // null for the boot classpath class-loader (could as well cache the
299 // class-loader of this class in a variable).
Andreas Gampec917f742015-04-20 19:16:37 -0700300 Class.forName(line, true, null);
Ying Wangd0c45352014-11-13 15:22:47 -0800301 count++;
302 } catch (ClassNotFoundException e) {
303 Log.w(TAG, "Class not found for preloading: " + line);
304 } catch (UnsatisfiedLinkError e) {
305 Log.w(TAG, "Problem preloading " + line + ": " + e);
306 } catch (Throwable t) {
307 Log.e(TAG, "Error preloading " + line + ".", t);
308 if (t instanceof Error) {
309 throw (Error) t;
310 }
311 if (t instanceof RuntimeException) {
312 throw (RuntimeException) t;
313 }
314 throw new RuntimeException(t);
315 }
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900316 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800317 }
Ying Wangd0c45352014-11-13 15:22:47 -0800318
319 Log.i(TAG, "...preloaded " + count + " classes in "
320 + (SystemClock.uptimeMillis()-startTime) + "ms.");
321 } catch (IOException e) {
322 Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);
323 } finally {
324 IoUtils.closeQuietly(is);
325 // Restore default.
326 runtime.setTargetHeapUtilization(defaultUtilization);
327
328 // Fill in dex caches with classes, fields, and methods brought in by preloading.
Yasuhiro Matsuda1ab43d52015-06-30 17:07:32 +0900329 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadDexCaches");
Ying Wangd0c45352014-11-13 15:22:47 -0800330 runtime.preloadDexCaches();
Yasuhiro Matsuda1ab43d52015-06-30 17:07:32 +0900331 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Ying Wangd0c45352014-11-13 15:22:47 -0800332
Narayan Kamath23e68782015-01-16 17:22:41 +0000333 // Bring back root. We'll need it later if we're in the zygote.
334 if (droppedPriviliges) {
335 try {
336 Os.setreuid(ROOT_UID, ROOT_UID);
337 Os.setregid(ROOT_GID, ROOT_GID);
338 } catch (ErrnoException ex) {
339 throw new RuntimeException("Failed to restore root", ex);
340 }
Elliott Hughes26b56e62014-12-17 12:28:29 -0800341 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800342 }
343 }
344
345 /**
346 * Load in commonly used resources, so they can be shared across
347 * processes.
348 *
349 * These tend to be a few Kbytes, but are frequently in the 20-40K
350 * range, and occasionally even larger.
351 */
352 private static void preloadResources() {
353 final VMRuntime runtime = VMRuntime.getRuntime();
Bob Leee5408332009-09-04 18:31:17 -0700354
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800355 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800356 mResources = Resources.getSystem();
357 mResources.startPreloading();
358 if (PRELOAD_RESOURCES) {
359 Log.i(TAG, "Preloading resources...");
360
361 long startTime = SystemClock.uptimeMillis();
362 TypedArray ar = mResources.obtainTypedArray(
363 com.android.internal.R.array.preloaded_drawables);
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800364 int N = preloadDrawables(ar);
Jeff Brown14577c42012-03-08 16:40:14 -0800365 ar.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800366 Log.i(TAG, "...preloaded " + N + " resources in "
367 + (SystemClock.uptimeMillis()-startTime) + "ms.");
368
369 startTime = SystemClock.uptimeMillis();
370 ar = mResources.obtainTypedArray(
371 com.android.internal.R.array.preloaded_color_state_lists);
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800372 N = preloadColorStateLists(ar);
Jeff Brown14577c42012-03-08 16:40:14 -0800373 ar.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800374 Log.i(TAG, "...preloaded " + N + " resources in "
375 + (SystemClock.uptimeMillis()-startTime) + "ms.");
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800376
377 if (mResources.getBoolean(
378 com.android.internal.R.bool.config_freeformWindowManagement)) {
379 startTime = SystemClock.uptimeMillis();
380 ar = mResources.obtainTypedArray(
381 com.android.internal.R.array.preloaded_freeform_multi_window_drawables);
382 N = preloadDrawables(ar);
383 ar.recycle();
384 Log.i(TAG, "...preloaded " + N + " resource in "
385 + (SystemClock.uptimeMillis() - startTime) + "ms.");
386 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800387 }
388 mResources.finishPreloading();
389 } catch (RuntimeException e) {
390 Log.w(TAG, "Failure preloading resources", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800391 }
392 }
393
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800394 private static int preloadColorStateLists(TypedArray ar) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395 int N = ar.length();
396 for (int i=0; i<N; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800397 int id = ar.getResourceId(i, 0);
Joe Onorato43a17652011-04-06 19:22:23 -0700398 if (false) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800399 Log.v(TAG, "Preloading resource #" + Integer.toHexString(id));
400 }
401 if (id != 0) {
Alan Viverette77bb6f12015-02-11 17:24:33 -0800402 if (mResources.getColorStateList(id, null) == null) {
Dianne Hackborndde331c2012-08-03 14:01:57 -0700403 throw new IllegalArgumentException(
404 "Unable to find preloaded color resource #0x"
405 + Integer.toHexString(id)
406 + " (" + ar.getString(i) + ")");
407 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800408 }
409 }
410 return N;
411 }
412
413
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800414 private static int preloadDrawables(TypedArray ar) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800415 int N = ar.length();
416 for (int i=0; i<N; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800417 int id = ar.getResourceId(i, 0);
Joe Onorato43a17652011-04-06 19:22:23 -0700418 if (false) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800419 Log.v(TAG, "Preloading resource #" + Integer.toHexString(id));
420 }
421 if (id != 0) {
Alan Viverette84e001a2014-09-22 00:04:22 -0700422 if (mResources.getDrawable(id, null) == null) {
Dianne Hackborndde331c2012-08-03 14:01:57 -0700423 throw new IllegalArgumentException(
424 "Unable to find preloaded drawable resource #0x"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800425 + Integer.toHexString(id)
Dianne Hackborndde331c2012-08-03 14:01:57 -0700426 + " (" + ar.getString(i) + ")");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800427 }
428 }
429 }
430 return N;
431 }
432
433 /**
434 * Runs several special GCs to try to clean up a few generations of
435 * softly- and final-reachable objects, along with any other garbage.
436 * This is only useful just before a fork().
437 */
Mathieu Chartier9a88f102014-08-20 10:24:11 -0700438 /*package*/ static void gcAndFinalize() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800439 final VMRuntime runtime = VMRuntime.getRuntime();
440
441 /* runFinalizationSync() lets finalizers be called in Zygote,
442 * which doesn't have a HeapWorker thread.
443 */
Brian Carlstrom08065b92011-04-01 15:49:41 -0700444 System.gc();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800445 runtime.runFinalizationSync();
Brian Carlstrom08065b92011-04-01 15:49:41 -0700446 System.gc();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800447 }
448
449 /**
450 * Finish remaining work for the newly forked system server process.
451 */
Narayan Kamathbf99d062017-07-05 14:45:38 +0100452 private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
Mike Lockwood90960e82010-08-06 09:15:25 -0400453 // set umask to 0077 so new files and directories will default to owner-only permissions.
Elliott Hughes860c5912014-04-28 19:19:13 -0700454 Os.umask(S_IRWXG | S_IRWXO);
Mike Lockwood90960e82010-08-06 09:15:25 -0400455
Jeff Brownebed7d62011-05-16 17:08:42 -0700456 if (parsedArgs.niceName != null) {
457 Process.setArgV0(parsedArgs.niceName);
458 }
459
Narayan Kamath29564cd2014-08-07 10:57:40 +0100460 final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
461 if (systemServerClasspath != null) {
462 performSystemServerDexOpt(systemServerClasspath);
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -0700463 // Capturing profiles is only supported for debug or eng builds since selinux normally
464 // prevents it.
465 boolean profileSystemServer = SystemProperties.getBoolean(
466 "dalvik.vm.profilesystemserver", false);
467 if (profileSystemServer && (Build.IS_USERDEBUG || Build.IS_ENG)) {
468 try {
469 File profileDir = Environment.getDataProfilesDePackageDirectory(
470 Process.SYSTEM_UID, "system_server");
471 File profile = new File(profileDir, "primary.prof");
472 profile.getParentFile().mkdirs();
473 profile.createNewFile();
474 String[] codePaths = systemServerClasspath.split(":");
475 VMRuntime.registerAppInfo(profile.getPath(), codePaths);
476 } catch (Exception e) {
477 Log.wtf(TAG, "Failed to set up system server profile", e);
478 }
479 }
Narayan Kamath29564cd2014-08-07 10:57:40 +0100480 }
481
Jeff Brownebed7d62011-05-16 17:08:42 -0700482 if (parsedArgs.invokeWith != null) {
Narayan Kamath29564cd2014-08-07 10:57:40 +0100483 String[] args = parsedArgs.remainingArgs;
484 // If we have a non-null system server class path, we'll have to duplicate the
485 // existing arguments and append the classpath to it. ART will handle the classpath
486 // correctly when we exec a new process.
487 if (systemServerClasspath != null) {
488 String[] amendedArgs = new String[args.length + 2];
489 amendedArgs[0] = "-cp";
490 amendedArgs[1] = systemServerClasspath;
tony.ys_liu34738172016-12-14 18:50:29 +0800491 System.arraycopy(args, 0, amendedArgs, 2, args.length);
492 args = amendedArgs;
Narayan Kamath29564cd2014-08-07 10:57:40 +0100493 }
494
Jeff Brownebed7d62011-05-16 17:08:42 -0700495 WrapperInit.execApplication(parsedArgs.invokeWith,
Elliott Hughese1dfcb72011-07-08 11:08:07 -0700496 parsedArgs.niceName, parsedArgs.targetSdkVersion,
Narayan Kamath37ad4b02015-01-19 16:05:24 +0000497 VMRuntime.getCurrentInstructionSet(), null, args);
Narayan Kamathbf99d062017-07-05 14:45:38 +0100498
499 throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
Jeff Brownebed7d62011-05-16 17:08:42 -0700500 } else {
Narayan Kamath29564cd2014-08-07 10:57:40 +0100501 ClassLoader cl = null;
502 if (systemServerClasspath != null) {
tony.ys_liu34738172016-12-14 18:50:29 +0800503 cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700504
Narayan Kamath29564cd2014-08-07 10:57:40 +0100505 Thread.currentThread().setContextClassLoader(cl);
506 }
507
Jeff Brownebed7d62011-05-16 17:08:42 -0700508 /*
509 * Pass the remaining arguments to SystemServer.
510 */
Narayan Kamathbf99d062017-07-05 14:45:38 +0100511 return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
Jeff Brownebed7d62011-05-16 17:08:42 -0700512 }
513
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800514 /* should never reach here */
515 }
516
517 /**
tony.ys_liu34738172016-12-14 18:50:29 +0800518 * Creates a PathClassLoader for the given class path that is associated with a shared
519 * namespace, i.e., this classloader can access platform-private native libraries. The
520 * classloader will use java.library.path as the native library path.
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700521 */
Narayan Kamathf9419f02017-06-15 11:35:38 +0100522 static ClassLoader createPathClassLoader(String classPath, int targetSdkVersion) {
523 String libraryPath = System.getProperty("java.library.path");
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700524
Narayan Kamathf9419f02017-06-15 11:35:38 +0100525 return ClassLoaderFactory.createClassLoader(classPath, libraryPath, libraryPath,
526 ClassLoader.getSystemClassLoader(), targetSdkVersion, true /* isNamespaceShared */,
527 null /* classLoaderName */);
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700528 }
529
530 /**
Narayan Kamath29564cd2014-08-07 10:57:40 +0100531 * Performs dex-opt on the elements of {@code classPath}, if needed. We
532 * choose the instruction set of the current runtime.
533 */
534 private static void performSystemServerDexOpt(String classPath) {
535 final String[] classPathElements = classPath.split(":");
Jeff Sharkey740f5232016-12-09 14:31:26 -0700536 final IInstalld installd = IInstalld.Stub
537 .asInterface(ServiceManager.getService("installd"));
Narayan Kamath29564cd2014-08-07 10:57:40 +0100538 final String instructionSet = VMRuntime.getRuntime().vmInstructionSet();
539
Calin Juravle2f09ff32017-07-24 15:29:56 -0700540 String classPathForElement = "";
Jeff Sharkey740f5232016-12-09 14:31:26 -0700541 for (String classPathElement : classPathElements) {
542 // System server is fully AOTed and never profiled
543 // for profile guided compilation.
Mathieu Chartier5e07a0d2017-06-15 19:09:38 -0700544 String systemServerFilter = SystemProperties.get(
545 "dalvik.vm.systemservercompilerfilter", "speed");
Andreas Gampee7bc1522016-08-09 20:44:04 -0700546
Jeff Sharkey740f5232016-12-09 14:31:26 -0700547 int dexoptNeeded;
548 try {
549 dexoptNeeded = DexFile.getDexOptNeeded(
Shubham Ajmera246dccf2017-05-24 17:46:36 -0700550 classPathElement, instructionSet, systemServerFilter,
Calin Juravle576e6c02017-09-12 00:58:33 -0700551 null /* classLoaderContext */, false /* newProfile */, false /* downgrade */);
Jeff Sharkey740f5232016-12-09 14:31:26 -0700552 } catch (FileNotFoundException ignored) {
553 // Do not add to the classpath.
554 Log.w(TAG, "Missing classpath element for system server: " + classPathElement);
555 continue;
556 } catch (IOException e) {
557 // Not fully clear what to do here as we don't know the cause of the
558 // IO exception. Add to the classpath to be conservative, but don't
559 // attempt to compile it.
560 Log.w(TAG, "Error checking classpath element for system server: "
561 + classPathElement, e);
562 dexoptNeeded = DexFile.NO_DEXOPT_NEEDED;
Narayan Kamath29564cd2014-08-07 10:57:40 +0100563 }
Jeff Sharkey740f5232016-12-09 14:31:26 -0700564
565 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
566 final String packageName = "*";
567 final String outputPath = null;
568 final int dexFlags = 0;
Mathieu Chartier5e07a0d2017-06-15 19:09:38 -0700569 final String compilerFilter = systemServerFilter;
Jeff Sharkey740f5232016-12-09 14:31:26 -0700570 final String uuid = StorageManager.UUID_PRIVATE_INTERNAL;
Calin Juravle811a75a2017-04-05 22:49:38 -0700571 final String seInfo = null;
Calin Juravle2f09ff32017-07-24 15:29:56 -0700572 final String classLoaderContext =
573 getSystemServerClassLoaderContext(classPathForElement);
David Brazdil3d44ed02018-01-16 20:01:47 +0000574 final int targetSdkVersion = 0; // SystemServer targets the system's SDK version
Jeff Sharkey740f5232016-12-09 14:31:26 -0700575 try {
576 installd.dexopt(classPathElement, Process.SYSTEM_UID, packageName,
577 instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter,
David Brazdil3d44ed02018-01-16 20:01:47 +0000578 uuid, classLoaderContext, seInfo, false /* downgrade */,
579 targetSdkVersion);
Jeff Sharkey740f5232016-12-09 14:31:26 -0700580 } catch (RemoteException | ServiceSpecificException e) {
581 // Ignore (but log), we need this on the classpath for fallback mode.
582 Log.w(TAG, "Failed compiling classpath element for system server: "
583 + classPathElement, e);
584 }
585 }
586
Calin Juravle2f09ff32017-07-24 15:29:56 -0700587 classPathForElement = encodeSystemServerClassPath(
588 classPathForElement, classPathElement);
Narayan Kamath29564cd2014-08-07 10:57:40 +0100589 }
590 }
591
592 /**
Calin Juravle2f09ff32017-07-24 15:29:56 -0700593 * Encodes the system server class loader context in a format that is accepted by dexopt.
594 * This assumes the system server is always loaded with a {@link dalvik.system.PathClassLoader}.
595 *
596 * Note that ideally we would use the {@code DexoptUtils} to compute this. However we have no
597 * dependency here on the server so we hard code the logic again.
598 */
599 private static String getSystemServerClassLoaderContext(String classPath) {
600 return classPath == null ? "PCL[]" : "PCL[" + classPath + "]";
601 }
602
603 /**
604 * Encodes the class path in a format accepted by dexopt.
605 * @param classPath the old class path (may be empty).
606 * @param newElement the new class path elements
607 * @return the class path encoding resulted from appending {@code newElement} to
608 * {@code classPath}.
609 */
610 private static String encodeSystemServerClassPath(String classPath, String newElement) {
611 return (classPath == null || classPath.isEmpty())
612 ? newElement
613 : classPath + ":" + newElement;
614 }
615
616 /**
Narayan Kamathbf99d062017-07-05 14:45:38 +0100617 * Prepare the arguments and forks for the system server process.
618 *
619 * Returns an {@code Runnable} that provides an entrypoint into system_server code in the
620 * child process, and {@code null} in the parent.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800621 */
Narayan Kamathbf99d062017-07-05 14:45:38 +0100622 private static Runnable forkSystemServer(String abiList, String socketName,
623 ZygoteServer zygoteServer) {
Alex Klyubin48a06e72013-04-19 10:01:42 -0700624 long capabilities = posixCapabilitiesAsBits(
Philip Cuadra7bd0fdd2016-04-28 15:26:49 -0700625 OsConstants.CAP_IPC_LOCK,
Alex Klyubin48a06e72013-04-19 10:01:42 -0700626 OsConstants.CAP_KILL,
627 OsConstants.CAP_NET_ADMIN,
628 OsConstants.CAP_NET_BIND_SERVICE,
629 OsConstants.CAP_NET_BROADCAST,
630 OsConstants.CAP_NET_RAW,
Alex Klyubin48a06e72013-04-19 10:01:42 -0700631 OsConstants.CAP_SYS_MODULE,
632 OsConstants.CAP_SYS_NICE,
Nick Kralevich3082eb72017-02-15 15:12:31 -0800633 OsConstants.CAP_SYS_PTRACE,
Alex Klyubin48a06e72013-04-19 10:01:42 -0700634 OsConstants.CAP_SYS_TIME,
John Stultz5733f382016-07-28 12:35:31 -0700635 OsConstants.CAP_SYS_TTY_CONFIG,
Luis Hector Chavez72042c92017-07-12 10:03:30 -0700636 OsConstants.CAP_WAKE_ALARM,
637 OsConstants.CAP_BLOCK_SUSPEND
Alex Klyubin48a06e72013-04-19 10:01:42 -0700638 );
Luis Hector Chavez72042c92017-07-12 10:03:30 -0700639 /* Containers run without some capabilities, so drop any caps that are not available. */
640 StructCapUserHeader header = new StructCapUserHeader(
641 OsConstants._LINUX_CAPABILITY_VERSION_3, 0);
642 StructCapUserData[] data;
643 try {
644 data = Os.capget(header);
645 } catch (ErrnoException ex) {
646 throw new RuntimeException("Failed to capget()", ex);
Luis Hector Chavez5dd239a2015-10-06 14:01:45 -0700647 }
Luis Hector Chavez72042c92017-07-12 10:03:30 -0700648 capabilities &= ((long) data[0].effective) | (((long) data[1].effective) << 32);
649
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800650 /* Hardcoded command line to start the system server */
651 String args[] = {
652 "--setuid=1000",
653 "--setgid=1000",
Jeff Sharkey4a539442018-01-05 17:09:52 -0700654 "--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 -0700655 "--capabilities=" + capabilities + "," + capabilities,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800656 "--nice-name=system_server",
Narayan Kamathb6b044a2015-02-13 17:31:25 +0000657 "--runtime-args",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800658 "com.android.server.SystemServer",
659 };
660 ZygoteConnection.Arguments parsedArgs = null;
661
662 int pid;
663
664 try {
665 parsedArgs = new ZygoteConnection.Arguments(args);
Jeff Brownebed7d62011-05-16 17:08:42 -0700666 ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
667 ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800668
669 /* Request to fork the system server process */
670 pid = Zygote.forkSystemServer(
671 parsedArgs.uid, parsedArgs.gid,
Elliott Hughese1dfcb72011-07-08 11:08:07 -0700672 parsedArgs.gids,
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100673 parsedArgs.runtimeFlags,
Elliott Hughese1dfcb72011-07-08 11:08:07 -0700674 null,
Andy McFadden1b4c7962010-10-27 11:26:05 -0700675 parsedArgs.permittedCapabilities,
676 parsedArgs.effectiveCapabilities);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800677 } catch (IllegalArgumentException ex) {
678 throw new RuntimeException(ex);
Bob Leee5408332009-09-04 18:31:17 -0700679 }
680
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800681 /* For child process */
682 if (pid == 0) {
Narayan Kamath64cd9072014-05-13 13:35:14 +0100683 if (hasSecondZygote(abiList)) {
684 waitForSecondaryZygote(socketName);
685 }
686
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000687 zygoteServer.closeServerSocket();
Narayan Kamathbf99d062017-07-05 14:45:38 +0100688 return handleSystemServerProcess(parsedArgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800689 }
690
Narayan Kamathbf99d062017-07-05 14:45:38 +0100691 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800692 }
693
Alex Klyubin48a06e72013-04-19 10:01:42 -0700694 /**
695 * Gets the bit array representation of the provided list of POSIX capabilities.
696 */
697 private static long posixCapabilitiesAsBits(int... capabilities) {
698 long result = 0;
699 for (int capability : capabilities) {
700 if ((capability < 0) || (capability > OsConstants.CAP_LAST_CAP)) {
701 throw new IllegalArgumentException(String.valueOf(capability));
702 }
703 result |= (1L << capability);
704 }
705 return result;
706 }
707
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800708 public static void main(String argv[]) {
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000709 ZygoteServer zygoteServer = new ZygoteServer();
710
Andreas Gampe1ef8aef2016-04-11 08:39:52 -0700711 // Mark zygote start. This ensures that thread creation will throw
712 // an error.
713 ZygoteHooks.startZygoteNoThreadCreation();
714
Robert Seseke4f8d692016-09-13 19:13:01 -0400715 // Zygote goes into its own process group.
716 try {
717 Os.setpgid(0, 0);
718 } catch (ErrnoException ex) {
719 throw new RuntimeException("Failed to setpgid(0,0)", ex);
720 }
721
Narayan Kamathbf99d062017-07-05 14:45:38 +0100722 final Runnable caller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800723 try {
Fyodor Kupolov6733e6c2017-01-06 18:27:05 -0800724 // Report Zygote start time to tron unless it is a runtime restart
725 if (!"1".equals(SystemProperties.get("sys.boot_completed"))) {
726 MetricsLogger.histogram(null, "boot_zygote_init",
727 (int) SystemClock.elapsedRealtime());
728 }
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800729
730 String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
Fyodor Kupolov6e3461b2017-08-10 17:00:43 -0700731 TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag,
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800732 Trace.TRACE_TAG_DALVIK);
733 bootTimingsTraceLog.traceBegin("ZygoteInit");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900734 RuntimeInit.enableDdms();
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900735
Narayan Kamathc41638c2014-04-07 13:56:15 +0100736 boolean startSystemServer = false;
737 String socketName = "zygote";
738 String abiList = null;
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000739 boolean enableLazyPreload = false;
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900740 for (int i = 1; i < argv.length; i++) {
741 if ("start-system-server".equals(argv[i])) {
742 startSystemServer = true;
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000743 } else if ("--enable-lazy-preload".equals(argv[i])) {
744 enableLazyPreload = true;
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900745 } else if (argv[i].startsWith(ABI_LIST_ARG)) {
746 abiList = argv[i].substring(ABI_LIST_ARG.length());
747 } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
748 socketName = argv[i].substring(SOCKET_NAME_ARG.length());
749 } else {
750 throw new RuntimeException("Unknown command line argument: " + argv[i]);
Narayan Kamathc41638c2014-04-07 13:56:15 +0100751 }
752 }
753
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900754 if (abiList == null) {
755 throw new RuntimeException("No ABI list supplied.");
756 }
757
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000758 zygoteServer.registerServerSocket(socketName);
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000759 // In some configurations, we avoid preloading resources and classes eagerly.
760 // In such cases, we will preload things prior to our first fork.
761 if (!enableLazyPreload) {
762 bootTimingsTraceLog.traceBegin("ZygotePreload");
763 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
764 SystemClock.uptimeMillis());
765 preload(bootTimingsTraceLog);
766 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
767 SystemClock.uptimeMillis());
768 bootTimingsTraceLog.traceEnd(); // ZygotePreload
Narayan Kamathb49996d2017-02-06 20:24:08 +0000769 } else {
Hiroshi Yamauchi1e3db872017-03-02 13:39:07 -0800770 Zygote.resetNicePriority();
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000771 }
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900772
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900773 // Do an initial gc to clean up after startup
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800774 bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900775 gcAndFinalize();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800776 bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900777
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800778 bootTimingsTraceLog.traceEnd(); // ZygoteInit
Jamie Gennis6ad04522013-04-15 18:53:24 -0700779 // Disable tracing so that forked processes do not inherit stale tracing tags from
780 // Zygote.
John Reck62cc1192017-05-12 15:39:51 -0700781 Trace.setTracingEnabled(false, 0);
Jamie Gennis6ad04522013-04-15 18:53:24 -0700782
Victor Hsiehc8176ef2018-01-08 12:43:00 -0800783 Zygote.nativeSecurityInit();
784
doheon1.lee885b7422016-01-20 13:07:27 +0900785 // Zygote process unmounts root storage spaces.
786 Zygote.nativeUnmountStorageOnInit();
787
Andreas Gampe1ef8aef2016-04-11 08:39:52 -0700788 ZygoteHooks.stopZygoteNoThreadCreation();
789
Narayan Kamathc41638c2014-04-07 13:56:15 +0100790 if (startSystemServer) {
Narayan Kamathbf99d062017-07-05 14:45:38 +0100791 Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
792
793 // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
794 // child (system_server) process.
795 if (r != null) {
796 r.run();
797 return;
798 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800799 }
800
801 Log.i(TAG, "Accepting command socket connections");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800802
Narayan Kamathbf99d062017-07-05 14:45:38 +0100803 // The select loop returns early in the child process after a fork and
804 // loops forever in the zygote.
805 caller = zygoteServer.runSelectLoop(abiList);
Christopher Ferrisea8b5de2016-06-17 15:29:58 -0700806 } catch (Throwable ex) {
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000807 Log.e(TAG, "System zygote died with exception", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800808 throw ex;
Narayan Kamathbf99d062017-07-05 14:45:38 +0100809 } finally {
810 zygoteServer.closeServerSocket();
811 }
812
813 // We're in the child process and have exited the select loop. Proceed to execute the
814 // command.
815 if (caller != null) {
816 caller.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800817 }
818 }
819
820 /**
Narayan Kamath64cd9072014-05-13 13:35:14 +0100821 * Return {@code true} if this device configuration has another zygote.
822 *
823 * We determine this by comparing the device ABI list with this zygotes
824 * list. If this zygote supports all ABIs this device supports, there won't
825 * be another zygote.
826 */
827 private static boolean hasSecondZygote(String abiList) {
828 return !SystemProperties.get("ro.product.cpu.abilist").equals(abiList);
829 }
830
831 private static void waitForSecondaryZygote(String socketName) {
832 String otherZygoteName = Process.ZYGOTE_SOCKET.equals(socketName) ?
833 Process.SECONDARY_ZYGOTE_SOCKET : Process.ZYGOTE_SOCKET;
Gustav Senntonf0c52b52017-04-27 17:00:50 +0100834 ZygoteProcess.waitForConnectionToZygote(otherZygoteName);
Narayan Kamath64cd9072014-05-13 13:35:14 +0100835 }
836
Narayan Kamath669afcc2017-02-06 20:24:08 +0000837 static boolean isPreloadComplete() {
838 return sPreloadComplete;
839 }
840
Narayan Kamath64cd9072014-05-13 13:35:14 +0100841 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800842 * Class not instantiable.
843 */
844 private ZygoteInit() {
845 }
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800846
847 /**
848 * The main function called when started through the zygote process. This
849 * could be unified with main(), if the native code in nativeFinishInit()
850 * were rationalized with Zygote startup.<p>
851 *
852 * Current recognized args:
853 * <ul>
854 * <li> <code> [--] &lt;start class name&gt; &lt;args&gt;
855 * </ul>
856 *
857 * @param targetSdkVersion target SDK version
858 * @param argv arg strings
859 */
Narayan Kamathbf99d062017-07-05 14:45:38 +0100860 public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800861 if (RuntimeInit.DEBUG) {
862 Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
863 }
864
865 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
866 RuntimeInit.redirectLogStreams();
867
868 RuntimeInit.commonInit();
869 ZygoteInit.nativeZygoteInit();
Narayan Kamathbf99d062017-07-05 14:45:38 +0100870 return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800871 }
872
873 private static final native void nativeZygoteInit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800874}