blob: 04034fb68fbf7c9d8bfb45300d1ed38ca940847f [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;
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -070024import android.os.Build;
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -070025import android.os.Environment;
Mathew Inwood04194fe2018-04-04 14:48:03 +010026import android.os.IInstalld;
Jeff Brownebed7d62011-05-16 17:08:42 -070027import android.os.Process;
Jeff Sharkey740f5232016-12-09 14:31:26 -070028import android.os.RemoteException;
29import android.os.ServiceManager;
30import android.os.ServiceSpecificException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import android.os.SystemClock;
Romain Guyc5e36382013-05-09 11:08:17 -070032import android.os.SystemProperties;
Jamie Gennis6ad04522013-04-15 18:53:24 -070033import android.os.Trace;
Calin Juravle3f3a08a2018-05-02 23:39:19 -070034import android.os.UserHandle;
Robert Sesek8f8d1872016-03-18 16:52:57 -040035import android.os.ZygoteProcess;
Jeff Sharkeyc98c7bc2016-12-07 14:57:34 -070036import android.os.storage.StorageManager;
Sergio Giro69de3202016-05-17 16:52:33 +010037import android.security.keystore.AndroidKeyStoreProvider;
Bill Yi9a76e9b2014-04-29 18:52:48 -070038import android.system.ErrnoException;
Elliott Hughes860c5912014-04-28 19:19:13 -070039import android.system.Os;
40import android.system.OsConstants;
Luis Hector Chavez72042c92017-07-12 10:03:30 -070041import android.system.StructCapUserData;
42import android.system.StructCapUserHeader;
Raph Levienc3dd1c12015-04-06 10:37:57 -070043import android.text.Hyphenator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import android.util.EventLog;
45import android.util.Log;
Andreas Gampe76d4fc82017-02-07 19:44:37 -080046import android.util.Slog;
Mathew Inwood04194fe2018-04-04 14:48:03 +010047import android.util.TimingsTraceLog;
Torne (Richard Coles)08cfaf62014-05-08 16:07:05 +010048import android.webkit.WebViewFactory;
Andreas Gampeddc13972016-02-26 16:54:59 -080049import android.widget.TextView;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -080051import com.android.internal.logging.MetricsLogger;
Narayan Kamath669afcc2017-02-06 20:24:08 +000052import com.android.internal.util.Preconditions;
Mathew Inwood04194fe2018-04-04 14:48:03 +010053
Narayan Kamath29564cd2014-08-07 10:57:40 +010054import dalvik.system.DexFile;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055import dalvik.system.VMRuntime;
Andreas Gampe1ef8aef2016-04-11 08:39:52 -070056import dalvik.system.ZygoteHooks;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057
Brian Carlstrom46703b02011-04-06 15:41:29 -070058import libcore.io.IoUtils;
59
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060import java.io.BufferedReader;
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -070061import java.io.File;
Ying Wangd0c45352014-11-13 15:22:47 -080062import java.io.FileInputStream;
63import java.io.FileNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064import java.io.IOException;
65import java.io.InputStream;
66import java.io.InputStreamReader;
Sergio Giro6cb7b1c2016-05-13 16:34:46 +010067import java.security.Provider;
Mathew Inwood04194fe2018-04-04 14:48:03 +010068import java.security.Security;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069
70/**
71 * Startup class for the zygote process.
72 *
73 * Pre-initializes some classes, and then waits for commands on a UNIX domain
Elliott Hughese1dfcb72011-07-08 11:08:07 -070074 * socket. Based on these commands, forks off child processes that inherit
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075 * the initial state of the VM.
76 *
77 * Please see {@link ZygoteConnection.Arguments} for documentation on the
78 * client protocol.
79 *
80 * @hide
81 */
82public class ZygoteInit {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083 private static final String TAG = "Zygote";
84
Jesse Hall2852a282017-01-17 10:17:41 -080085 private static final String PROPERTY_DISABLE_OPENGL_PRELOADING = "ro.zygote.disable_gl_preload";
Jesse Hallba0370e2017-02-09 14:43:14 -080086 private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
Romain Guyc5e36382013-05-09 11:08:17 -070087
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088 private static final int LOG_BOOT_PROGRESS_PRELOAD_START = 3020;
89 private static final int LOG_BOOT_PROGRESS_PRELOAD_END = 3030;
90
91 /** when preloading, GC after allocating this many bytes */
92 private static final int PRELOAD_GC_THRESHOLD = 50000;
93
Narayan Kamathc41638c2014-04-07 13:56:15 +010094 private static final String ABI_LIST_ARG = "--abi-list=";
95
96 private static final String SOCKET_NAME_ARG = "--socket-name=";
Barry Hayes0b3533a2010-01-20 12:46:47 -080097
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098 /**
Tobias Sargeantdd4bb312016-01-19 16:34:54 +000099 * Used to pre-load resources.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100 */
101 private static Resources mResources;
Bob Leee5408332009-09-04 18:31:17 -0700102
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103 /**
Ying Wangd0c45352014-11-13 15:22:47 -0800104 * The path of a file that contains classes to preload.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105 */
Ying Wangd0c45352014-11-13 15:22:47 -0800106 private static final String PRELOADED_CLASSES = "/system/etc/preloaded-classes";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107
108 /** Controls whether we should preload resources during zygote init. */
Steve Paik3c27a232015-06-10 18:25:44 -0700109 public static final boolean PRELOAD_RESOURCES = true;
Andy McFadden599c9182009-04-08 00:35:56 -0700110
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111 private static final int UNPRIVILEGED_UID = 9999;
112 private static final int UNPRIVILEGED_GID = 9999;
113
114 private static final int ROOT_UID = 0;
115 private static final int ROOT_GID = 0;
116
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000117 private static boolean sPreloadComplete;
118
Fyodor Kupolov6e3461b2017-08-10 17:00:43 -0700119 static void preload(TimingsTraceLog bootTimingsTraceLog) {
Bill Yi9a76e9b2014-04-29 18:52:48 -0700120 Log.d(TAG, "begin preload");
Neil Fullera84056a2018-07-11 13:59:45 +0100121 bootTimingsTraceLog.traceBegin("BeginPreload");
122 beginPreload();
123 bootTimingsTraceLog.traceEnd(); // BeginPreload
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800124 bootTimingsTraceLog.traceBegin("PreloadClasses");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900125 preloadClasses();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800126 bootTimingsTraceLog.traceEnd(); // PreloadClasses
127 bootTimingsTraceLog.traceBegin("PreloadResources");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900128 preloadResources();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800129 bootTimingsTraceLog.traceEnd(); // PreloadResources
Jesse Hall1fe1dc02017-07-06 15:30:39 -0700130 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs");
131 nativePreloadAppProcessHALs();
132 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Jesse Hallba0370e2017-02-09 14:43:14 -0800133 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadOpenGL");
134 preloadOpenGL();
135 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Brian Carlstrom6c9af962014-09-11 15:36:00 -0700136 preloadSharedLibraries();
Raph Levienc3dd1c12015-04-06 10:37:57 -0700137 preloadTextResources();
Torne (Richard Coles)08cfaf62014-05-08 16:07:05 +0100138 // Ask the WebViewFactory to do any initialization that must run in the zygote process,
139 // for memory sharing purposes.
140 WebViewFactory.prepareWebViewInZygote();
Neil Fullera84056a2018-07-11 13:59:45 +0100141 endPreload();
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100142 warmUpJcaProviders();
Bill Yi9a76e9b2014-04-29 18:52:48 -0700143 Log.d(TAG, "end preload");
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000144
145 sPreloadComplete = true;
146 }
147
Narayan Kamath669afcc2017-02-06 20:24:08 +0000148 public static void lazyPreload() {
149 Preconditions.checkState(!sPreloadComplete);
150 Log.i(TAG, "Lazily preloading resources.");
151
Fyodor Kupolov6e3461b2017-08-10 17:00:43 -0700152 preload(new TimingsTraceLog("ZygoteInitTiming_lazy", Trace.TRACE_TAG_DALVIK));
Romain Guy74c69122013-05-08 17:54:20 -0700153 }
154
Neil Fullera84056a2018-07-11 13:59:45 +0100155 private static void beginPreload() {
156 Log.i(TAG, "Calling ZygoteHooks.beginPreload()");
Neil Fuller4f41f612016-05-09 16:55:36 +0100157
Neil Fullera84056a2018-07-11 13:59:45 +0100158 ZygoteHooks.onBeginPreload();
Neil Fuller4f41f612016-05-09 16:55:36 +0100159 }
160
Neil Fullera84056a2018-07-11 13:59:45 +0100161 private static void endPreload() {
162 ZygoteHooks.onEndPreload();
Neil Fuller4f41f612016-05-09 16:55:36 +0100163
Neil Fullera84056a2018-07-11 13:59:45 +0100164 Log.i(TAG, "Called ZygoteHooks.endPreload()");
Neil Fuller4f41f612016-05-09 16:55:36 +0100165 }
166
Brian Carlstrom6c9af962014-09-11 15:36:00 -0700167 private static void preloadSharedLibraries() {
168 Log.i(TAG, "Preloading shared libraries...");
169 System.loadLibrary("android");
170 System.loadLibrary("compiler_rt");
171 System.loadLibrary("jnigraphics");
172 }
173
Jesse Hall1fe1dc02017-07-06 15:30:39 -0700174 native private static void nativePreloadAppProcessHALs();
Peter Collingbourne6f4986b2018-10-26 14:52:14 -0700175 native private static void nativePreloadOpenGL();
Jesse Hall1fe1dc02017-07-06 15:30:39 -0700176
Jesse Hallba0370e2017-02-09 14:43:14 -0800177 private static void preloadOpenGL() {
178 String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
Jesse Hall5d911fe2017-04-13 15:44:24 -0700179 if (!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING, false) &&
180 (driverPackageName == null || driverPackageName.isEmpty())) {
Peter Collingbourne6f4986b2018-10-26 14:52:14 -0700181 nativePreloadOpenGL();
Jesse Hallba0370e2017-02-09 14:43:14 -0800182 }
183 }
184
Raph Levienc3dd1c12015-04-06 10:37:57 -0700185 private static void preloadTextResources() {
186 Hyphenator.init();
Andreas Gampeddc13972016-02-26 16:54:59 -0800187 TextView.preloadFontCache();
Raph Levienc3dd1c12015-04-06 10:37:57 -0700188 }
189
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800190 /**
Sergio Giro69de3202016-05-17 16:52:33 +0100191 * Register AndroidKeyStoreProvider and warm up the providers that are already registered.
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100192 *
193 * By doing it here we avoid that each app does it when requesting a service from the
194 * provider for the first time.
195 */
196 private static void warmUpJcaProviders() {
197 long startTime = SystemClock.uptimeMillis();
198 Trace.traceBegin(
Sergio Giro69de3202016-05-17 16:52:33 +0100199 Trace.TRACE_TAG_DALVIK, "Starting installation of AndroidKeyStoreProvider");
200 // AndroidKeyStoreProvider.install() manipulates the list of JCA providers to insert
201 // preferred providers. Note this is not done via security.properties as the JCA providers
202 // are not on the classpath in the case of, for example, raw dalvikvm runtimes.
203 AndroidKeyStoreProvider.install();
204 Log.i(TAG, "Installed AndroidKeyStoreProvider in "
205 + (SystemClock.uptimeMillis() - startTime) + "ms.");
206 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
207
208 startTime = SystemClock.uptimeMillis();
209 Trace.traceBegin(
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100210 Trace.TRACE_TAG_DALVIK, "Starting warm up of JCA providers");
211 for (Provider p : Security.getProviders()) {
212 p.warmUpServiceProvision();
213 }
214 Log.i(TAG, "Warmed up JCA providers in "
Sergio Giro69de3202016-05-17 16:52:33 +0100215 + (SystemClock.uptimeMillis() - startTime) + "ms.");
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100216 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
217 }
218
219 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800220 * Performs Zygote process initialization. Loads and initializes
221 * commonly used classes.
222 *
223 * Most classes only cause a few hundred bytes to be allocated, but
224 * a few will allocate a dozen Kbytes (in one case, 500+K).
225 */
226 private static void preloadClasses() {
227 final VMRuntime runtime = VMRuntime.getRuntime();
Bob Leee5408332009-09-04 18:31:17 -0700228
Ying Wangd0c45352014-11-13 15:22:47 -0800229 InputStream is;
230 try {
231 is = new FileInputStream(PRELOADED_CLASSES);
232 } catch (FileNotFoundException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800233 Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + ".");
Ying Wangd0c45352014-11-13 15:22:47 -0800234 return;
235 }
Bob Leee5408332009-09-04 18:31:17 -0700236
Ying Wangd0c45352014-11-13 15:22:47 -0800237 Log.i(TAG, "Preloading classes...");
238 long startTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800239
Ying Wangd0c45352014-11-13 15:22:47 -0800240 // Drop root perms while running static initializers.
Narayan Kamath23e68782015-01-16 17:22:41 +0000241 final int reuid = Os.getuid();
242 final int regid = Os.getgid();
243
244 // We need to drop root perms only if we're already root. In the case of "wrapped"
245 // processes (see WrapperInit), this function is called from an unprivileged uid
246 // and gid.
247 boolean droppedPriviliges = false;
248 if (reuid == ROOT_UID && regid == ROOT_GID) {
249 try {
250 Os.setregid(ROOT_GID, UNPRIVILEGED_GID);
251 Os.setreuid(ROOT_UID, UNPRIVILEGED_UID);
252 } catch (ErrnoException ex) {
253 throw new RuntimeException("Failed to drop root", ex);
254 }
255
256 droppedPriviliges = true;
Elliott Hughes26b56e62014-12-17 12:28:29 -0800257 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800258
Ying Wangd0c45352014-11-13 15:22:47 -0800259 // Alter the target heap utilization. With explicit GCs this
260 // is not likely to have any effect.
261 float defaultUtilization = runtime.getTargetHeapUtilization();
262 runtime.setTargetHeapUtilization(0.8f);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800263
Ying Wangd0c45352014-11-13 15:22:47 -0800264 try {
265 BufferedReader br
266 = new BufferedReader(new InputStreamReader(is), 256);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800267
Ying Wangd0c45352014-11-13 15:22:47 -0800268 int count = 0;
269 String line;
270 while ((line = br.readLine()) != null) {
271 // Skip comments and blank lines.
272 line = line.trim();
273 if (line.startsWith("#") || line.equals("")) {
274 continue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800275 }
276
Andreas Gampec4253622016-10-28 18:19:30 -0700277 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, line);
Ying Wangd0c45352014-11-13 15:22:47 -0800278 try {
279 if (false) {
280 Log.v(TAG, "Preloading " + line + "...");
281 }
Andreas Gampedd8e5fb2015-04-21 09:01:51 -0700282 // Load and explicitly initialize the given class. Use
283 // Class.forName(String, boolean, ClassLoader) to avoid repeated stack lookups
284 // (to derive the caller's class-loader). Use true to force initialization, and
285 // null for the boot classpath class-loader (could as well cache the
286 // class-loader of this class in a variable).
Andreas Gampec917f742015-04-20 19:16:37 -0700287 Class.forName(line, true, null);
Ying Wangd0c45352014-11-13 15:22:47 -0800288 count++;
289 } catch (ClassNotFoundException e) {
290 Log.w(TAG, "Class not found for preloading: " + line);
291 } catch (UnsatisfiedLinkError e) {
292 Log.w(TAG, "Problem preloading " + line + ": " + e);
293 } catch (Throwable t) {
294 Log.e(TAG, "Error preloading " + line + ".", t);
295 if (t instanceof Error) {
296 throw (Error) t;
297 }
298 if (t instanceof RuntimeException) {
299 throw (RuntimeException) t;
300 }
301 throw new RuntimeException(t);
302 }
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900303 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800304 }
Ying Wangd0c45352014-11-13 15:22:47 -0800305
306 Log.i(TAG, "...preloaded " + count + " classes in "
307 + (SystemClock.uptimeMillis()-startTime) + "ms.");
308 } catch (IOException e) {
309 Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);
310 } finally {
311 IoUtils.closeQuietly(is);
312 // Restore default.
313 runtime.setTargetHeapUtilization(defaultUtilization);
314
315 // Fill in dex caches with classes, fields, and methods brought in by preloading.
Yasuhiro Matsuda1ab43d52015-06-30 17:07:32 +0900316 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadDexCaches");
Ying Wangd0c45352014-11-13 15:22:47 -0800317 runtime.preloadDexCaches();
Yasuhiro Matsuda1ab43d52015-06-30 17:07:32 +0900318 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Ying Wangd0c45352014-11-13 15:22:47 -0800319
Narayan Kamath23e68782015-01-16 17:22:41 +0000320 // Bring back root. We'll need it later if we're in the zygote.
321 if (droppedPriviliges) {
322 try {
323 Os.setreuid(ROOT_UID, ROOT_UID);
324 Os.setregid(ROOT_GID, ROOT_GID);
325 } catch (ErrnoException ex) {
326 throw new RuntimeException("Failed to restore root", ex);
327 }
Elliott Hughes26b56e62014-12-17 12:28:29 -0800328 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800329 }
330 }
331
332 /**
333 * Load in commonly used resources, so they can be shared across
334 * processes.
335 *
336 * These tend to be a few Kbytes, but are frequently in the 20-40K
337 * range, and occasionally even larger.
338 */
339 private static void preloadResources() {
340 final VMRuntime runtime = VMRuntime.getRuntime();
Bob Leee5408332009-09-04 18:31:17 -0700341
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800342 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800343 mResources = Resources.getSystem();
344 mResources.startPreloading();
345 if (PRELOAD_RESOURCES) {
346 Log.i(TAG, "Preloading resources...");
347
348 long startTime = SystemClock.uptimeMillis();
349 TypedArray ar = mResources.obtainTypedArray(
350 com.android.internal.R.array.preloaded_drawables);
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800351 int N = preloadDrawables(ar);
Jeff Brown14577c42012-03-08 16:40:14 -0800352 ar.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800353 Log.i(TAG, "...preloaded " + N + " resources in "
354 + (SystemClock.uptimeMillis()-startTime) + "ms.");
355
356 startTime = SystemClock.uptimeMillis();
357 ar = mResources.obtainTypedArray(
358 com.android.internal.R.array.preloaded_color_state_lists);
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800359 N = preloadColorStateLists(ar);
Jeff Brown14577c42012-03-08 16:40:14 -0800360 ar.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800361 Log.i(TAG, "...preloaded " + N + " resources in "
362 + (SystemClock.uptimeMillis()-startTime) + "ms.");
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800363
364 if (mResources.getBoolean(
365 com.android.internal.R.bool.config_freeformWindowManagement)) {
366 startTime = SystemClock.uptimeMillis();
367 ar = mResources.obtainTypedArray(
368 com.android.internal.R.array.preloaded_freeform_multi_window_drawables);
369 N = preloadDrawables(ar);
370 ar.recycle();
371 Log.i(TAG, "...preloaded " + N + " resource in "
372 + (SystemClock.uptimeMillis() - startTime) + "ms.");
373 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800374 }
375 mResources.finishPreloading();
376 } catch (RuntimeException e) {
377 Log.w(TAG, "Failure preloading resources", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800378 }
379 }
380
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800381 private static int preloadColorStateLists(TypedArray ar) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382 int N = ar.length();
383 for (int i=0; i<N; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800384 int id = ar.getResourceId(i, 0);
Joe Onorato43a17652011-04-06 19:22:23 -0700385 if (false) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800386 Log.v(TAG, "Preloading resource #" + Integer.toHexString(id));
387 }
388 if (id != 0) {
Alan Viverette77bb6f12015-02-11 17:24:33 -0800389 if (mResources.getColorStateList(id, null) == null) {
Dianne Hackborndde331c2012-08-03 14:01:57 -0700390 throw new IllegalArgumentException(
391 "Unable to find preloaded color resource #0x"
392 + Integer.toHexString(id)
393 + " (" + ar.getString(i) + ")");
394 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395 }
396 }
397 return N;
398 }
399
400
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800401 private static int preloadDrawables(TypedArray ar) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402 int N = ar.length();
403 for (int i=0; i<N; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800404 int id = ar.getResourceId(i, 0);
Joe Onorato43a17652011-04-06 19:22:23 -0700405 if (false) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800406 Log.v(TAG, "Preloading resource #" + Integer.toHexString(id));
407 }
408 if (id != 0) {
Alan Viverette84e001a2014-09-22 00:04:22 -0700409 if (mResources.getDrawable(id, null) == null) {
Dianne Hackborndde331c2012-08-03 14:01:57 -0700410 throw new IllegalArgumentException(
411 "Unable to find preloaded drawable resource #0x"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800412 + Integer.toHexString(id)
Dianne Hackborndde331c2012-08-03 14:01:57 -0700413 + " (" + ar.getString(i) + ")");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800414 }
415 }
416 }
417 return N;
418 }
419
420 /**
421 * Runs several special GCs to try to clean up a few generations of
422 * softly- and final-reachable objects, along with any other garbage.
423 * This is only useful just before a fork().
424 */
Neil Fullera84056a2018-07-11 13:59:45 +0100425 private static void gcAndFinalize() {
426 ZygoteHooks.gcAndFinalize();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800427 }
428
429 /**
430 * Finish remaining work for the newly forked system server process.
431 */
Narayan Kamathbf99d062017-07-05 14:45:38 +0100432 private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
Mike Lockwood90960e82010-08-06 09:15:25 -0400433 // set umask to 0077 so new files and directories will default to owner-only permissions.
Elliott Hughes860c5912014-04-28 19:19:13 -0700434 Os.umask(S_IRWXG | S_IRWXO);
Mike Lockwood90960e82010-08-06 09:15:25 -0400435
Jeff Brownebed7d62011-05-16 17:08:42 -0700436 if (parsedArgs.niceName != null) {
437 Process.setArgV0(parsedArgs.niceName);
438 }
439
Narayan Kamath29564cd2014-08-07 10:57:40 +0100440 final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
441 if (systemServerClasspath != null) {
442 performSystemServerDexOpt(systemServerClasspath);
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -0700443 // Capturing profiles is only supported for debug or eng builds since selinux normally
444 // prevents it.
445 boolean profileSystemServer = SystemProperties.getBoolean(
446 "dalvik.vm.profilesystemserver", false);
447 if (profileSystemServer && (Build.IS_USERDEBUG || Build.IS_ENG)) {
448 try {
Calin Juravle3f3a08a2018-05-02 23:39:19 -0700449 prepareSystemServerProfile(systemServerClasspath);
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -0700450 } catch (Exception e) {
451 Log.wtf(TAG, "Failed to set up system server profile", e);
452 }
453 }
Narayan Kamath29564cd2014-08-07 10:57:40 +0100454 }
455
Jeff Brownebed7d62011-05-16 17:08:42 -0700456 if (parsedArgs.invokeWith != null) {
Narayan Kamath29564cd2014-08-07 10:57:40 +0100457 String[] args = parsedArgs.remainingArgs;
458 // If we have a non-null system server class path, we'll have to duplicate the
459 // existing arguments and append the classpath to it. ART will handle the classpath
460 // correctly when we exec a new process.
461 if (systemServerClasspath != null) {
462 String[] amendedArgs = new String[args.length + 2];
463 amendedArgs[0] = "-cp";
464 amendedArgs[1] = systemServerClasspath;
tony.ys_liu34738172016-12-14 18:50:29 +0800465 System.arraycopy(args, 0, amendedArgs, 2, args.length);
466 args = amendedArgs;
Narayan Kamath29564cd2014-08-07 10:57:40 +0100467 }
468
Jeff Brownebed7d62011-05-16 17:08:42 -0700469 WrapperInit.execApplication(parsedArgs.invokeWith,
Elliott Hughese1dfcb72011-07-08 11:08:07 -0700470 parsedArgs.niceName, parsedArgs.targetSdkVersion,
Narayan Kamath37ad4b02015-01-19 16:05:24 +0000471 VMRuntime.getCurrentInstructionSet(), null, args);
Narayan Kamathbf99d062017-07-05 14:45:38 +0100472
473 throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
Jeff Brownebed7d62011-05-16 17:08:42 -0700474 } else {
Narayan Kamath29564cd2014-08-07 10:57:40 +0100475 ClassLoader cl = null;
476 if (systemServerClasspath != null) {
tony.ys_liu34738172016-12-14 18:50:29 +0800477 cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700478
Narayan Kamath29564cd2014-08-07 10:57:40 +0100479 Thread.currentThread().setContextClassLoader(cl);
480 }
481
Jeff Brownebed7d62011-05-16 17:08:42 -0700482 /*
483 * Pass the remaining arguments to SystemServer.
484 */
Narayan Kamathbf99d062017-07-05 14:45:38 +0100485 return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
Jeff Brownebed7d62011-05-16 17:08:42 -0700486 }
487
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800488 /* should never reach here */
489 }
490
Calin Juravle3f3a08a2018-05-02 23:39:19 -0700491 /**
492 * Note that preparing the profiles for system server does not require special
493 * selinux permissions. From the installer perspective the system server is a regular package
494 * which can capture profile information.
495 */
496 private static void prepareSystemServerProfile(String systemServerClasspath)
497 throws RemoteException {
498 if (systemServerClasspath.isEmpty()) {
499 return;
500 }
501 String[] codePaths = systemServerClasspath.split(":");
502
503 final IInstalld installd = IInstalld.Stub
504 .asInterface(ServiceManager.getService("installd"));
505
506 String systemServerPackageName = "android";
507 String systemServerProfileName = "primary.prof";
508 installd.prepareAppProfile(
509 systemServerPackageName,
510 UserHandle.USER_SYSTEM,
511 UserHandle.getAppId(Process.SYSTEM_UID),
512 systemServerProfileName,
513 codePaths[0],
514 /*dexMetadata*/ null);
515
516 File profileDir = Environment.getDataProfilesDePackageDirectory(
517 UserHandle.USER_SYSTEM, systemServerPackageName);
518 String profilePath = new File(profileDir, systemServerProfileName).getAbsolutePath();
519 VMRuntime.registerAppInfo(profilePath, codePaths);
520 }
521
Mathew Inwood8faeab82018-03-16 14:26:08 +0000522 public static void setApiBlacklistExemptions(String[] exemptions) {
523 VMRuntime.getRuntime().setHiddenApiExemptions(exemptions);
524 }
525
Mathew Inwood04194fe2018-04-04 14:48:03 +0100526 public static void setHiddenApiAccessLogSampleRate(int percent) {
527 VMRuntime.getRuntime().setHiddenApiAccessLogSamplingRate(percent);
528 }
529
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800530 /**
tony.ys_liu34738172016-12-14 18:50:29 +0800531 * Creates a PathClassLoader for the given class path that is associated with a shared
532 * namespace, i.e., this classloader can access platform-private native libraries. The
533 * classloader will use java.library.path as the native library path.
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700534 */
Narayan Kamathf9419f02017-06-15 11:35:38 +0100535 static ClassLoader createPathClassLoader(String classPath, int targetSdkVersion) {
536 String libraryPath = System.getProperty("java.library.path");
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700537
Nicolas Geoffray5d1814e2018-12-13 09:27:04 +0000538 // We use the boot class loader, that's what the runtime expects at AOT.
539 ClassLoader parent = ClassLoader.getSystemClassLoader().getParent();
540
Narayan Kamathf9419f02017-06-15 11:35:38 +0100541 return ClassLoaderFactory.createClassLoader(classPath, libraryPath, libraryPath,
Nicolas Geoffray5d1814e2018-12-13 09:27:04 +0000542 parent, targetSdkVersion, true /* isNamespaceShared */, null /* classLoaderName */);
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700543 }
544
545 /**
Narayan Kamath29564cd2014-08-07 10:57:40 +0100546 * Performs dex-opt on the elements of {@code classPath}, if needed. We
547 * choose the instruction set of the current runtime.
548 */
549 private static void performSystemServerDexOpt(String classPath) {
550 final String[] classPathElements = classPath.split(":");
Jeff Sharkey740f5232016-12-09 14:31:26 -0700551 final IInstalld installd = IInstalld.Stub
552 .asInterface(ServiceManager.getService("installd"));
Narayan Kamath29564cd2014-08-07 10:57:40 +0100553 final String instructionSet = VMRuntime.getRuntime().vmInstructionSet();
554
Calin Juravle2f09ff32017-07-24 15:29:56 -0700555 String classPathForElement = "";
Jeff Sharkey740f5232016-12-09 14:31:26 -0700556 for (String classPathElement : classPathElements) {
557 // System server is fully AOTed and never profiled
558 // for profile guided compilation.
Mathieu Chartier5e07a0d2017-06-15 19:09:38 -0700559 String systemServerFilter = SystemProperties.get(
560 "dalvik.vm.systemservercompilerfilter", "speed");
Andreas Gampee7bc1522016-08-09 20:44:04 -0700561
Jeff Sharkey740f5232016-12-09 14:31:26 -0700562 int dexoptNeeded;
563 try {
564 dexoptNeeded = DexFile.getDexOptNeeded(
Shubham Ajmera246dccf2017-05-24 17:46:36 -0700565 classPathElement, instructionSet, systemServerFilter,
Calin Juravle576e6c02017-09-12 00:58:33 -0700566 null /* classLoaderContext */, false /* newProfile */, false /* downgrade */);
Jeff Sharkey740f5232016-12-09 14:31:26 -0700567 } catch (FileNotFoundException ignored) {
568 // Do not add to the classpath.
569 Log.w(TAG, "Missing classpath element for system server: " + classPathElement);
570 continue;
571 } catch (IOException e) {
572 // Not fully clear what to do here as we don't know the cause of the
573 // IO exception. Add to the classpath to be conservative, but don't
574 // attempt to compile it.
575 Log.w(TAG, "Error checking classpath element for system server: "
576 + classPathElement, e);
577 dexoptNeeded = DexFile.NO_DEXOPT_NEEDED;
Narayan Kamath29564cd2014-08-07 10:57:40 +0100578 }
Jeff Sharkey740f5232016-12-09 14:31:26 -0700579
580 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
581 final String packageName = "*";
582 final String outputPath = null;
David Brazdilf7e31c02018-02-13 17:04:26 +0000583 final int dexFlags = 0;
Mathieu Chartier5e07a0d2017-06-15 19:09:38 -0700584 final String compilerFilter = systemServerFilter;
Jeff Sharkey740f5232016-12-09 14:31:26 -0700585 final String uuid = StorageManager.UUID_PRIVATE_INTERNAL;
Calin Juravle811a75a2017-04-05 22:49:38 -0700586 final String seInfo = null;
Calin Juravle2f09ff32017-07-24 15:29:56 -0700587 final String classLoaderContext =
588 getSystemServerClassLoaderContext(classPathForElement);
David Brazdil3d44ed02018-01-16 20:01:47 +0000589 final int targetSdkVersion = 0; // SystemServer targets the system's SDK version
Jeff Sharkey740f5232016-12-09 14:31:26 -0700590 try {
591 installd.dexopt(classPathElement, Process.SYSTEM_UID, packageName,
592 instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter,
David Brazdil3d44ed02018-01-16 20:01:47 +0000593 uuid, classLoaderContext, seInfo, false /* downgrade */,
Calin Juravle4bc8f4d2018-02-12 12:00:44 -0800594 targetSdkVersion, /*profileName*/ null, /*dexMetadataPath*/ null,
595 "server-dexopt");
Jeff Sharkey740f5232016-12-09 14:31:26 -0700596 } catch (RemoteException | ServiceSpecificException e) {
597 // Ignore (but log), we need this on the classpath for fallback mode.
598 Log.w(TAG, "Failed compiling classpath element for system server: "
599 + classPathElement, e);
600 }
601 }
602
Calin Juravle2f09ff32017-07-24 15:29:56 -0700603 classPathForElement = encodeSystemServerClassPath(
604 classPathForElement, classPathElement);
Narayan Kamath29564cd2014-08-07 10:57:40 +0100605 }
606 }
607
608 /**
Calin Juravle2f09ff32017-07-24 15:29:56 -0700609 * Encodes the system server class loader context in a format that is accepted by dexopt.
610 * This assumes the system server is always loaded with a {@link dalvik.system.PathClassLoader}.
611 *
612 * Note that ideally we would use the {@code DexoptUtils} to compute this. However we have no
613 * dependency here on the server so we hard code the logic again.
614 */
615 private static String getSystemServerClassLoaderContext(String classPath) {
616 return classPath == null ? "PCL[]" : "PCL[" + classPath + "]";
617 }
618
619 /**
620 * Encodes the class path in a format accepted by dexopt.
621 * @param classPath the old class path (may be empty).
622 * @param newElement the new class path elements
623 * @return the class path encoding resulted from appending {@code newElement} to
624 * {@code classPath}.
625 */
626 private static String encodeSystemServerClassPath(String classPath, String newElement) {
627 return (classPath == null || classPath.isEmpty())
628 ? newElement
629 : classPath + ":" + newElement;
630 }
631
632 /**
Narayan Kamathbf99d062017-07-05 14:45:38 +0100633 * Prepare the arguments and forks for the system server process.
634 *
635 * Returns an {@code Runnable} that provides an entrypoint into system_server code in the
636 * child process, and {@code null} in the parent.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800637 */
Narayan Kamathbf99d062017-07-05 14:45:38 +0100638 private static Runnable forkSystemServer(String abiList, String socketName,
639 ZygoteServer zygoteServer) {
Alex Klyubin48a06e72013-04-19 10:01:42 -0700640 long capabilities = posixCapabilitiesAsBits(
Philip Cuadra7bd0fdd2016-04-28 15:26:49 -0700641 OsConstants.CAP_IPC_LOCK,
Alex Klyubin48a06e72013-04-19 10:01:42 -0700642 OsConstants.CAP_KILL,
643 OsConstants.CAP_NET_ADMIN,
644 OsConstants.CAP_NET_BIND_SERVICE,
645 OsConstants.CAP_NET_BROADCAST,
646 OsConstants.CAP_NET_RAW,
Alex Klyubin48a06e72013-04-19 10:01:42 -0700647 OsConstants.CAP_SYS_MODULE,
648 OsConstants.CAP_SYS_NICE,
Nick Kralevich3082eb72017-02-15 15:12:31 -0800649 OsConstants.CAP_SYS_PTRACE,
Alex Klyubin48a06e72013-04-19 10:01:42 -0700650 OsConstants.CAP_SYS_TIME,
John Stultz5733f382016-07-28 12:35:31 -0700651 OsConstants.CAP_SYS_TTY_CONFIG,
Luis Hector Chavez72042c92017-07-12 10:03:30 -0700652 OsConstants.CAP_WAKE_ALARM,
653 OsConstants.CAP_BLOCK_SUSPEND
Alex Klyubin48a06e72013-04-19 10:01:42 -0700654 );
Luis Hector Chavez72042c92017-07-12 10:03:30 -0700655 /* Containers run without some capabilities, so drop any caps that are not available. */
656 StructCapUserHeader header = new StructCapUserHeader(
657 OsConstants._LINUX_CAPABILITY_VERSION_3, 0);
658 StructCapUserData[] data;
659 try {
660 data = Os.capget(header);
661 } catch (ErrnoException ex) {
662 throw new RuntimeException("Failed to capget()", ex);
Luis Hector Chavez5dd239a2015-10-06 14:01:45 -0700663 }
Luis Hector Chavez72042c92017-07-12 10:03:30 -0700664 capabilities &= ((long) data[0].effective) | (((long) data[1].effective) << 32);
665
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800666 /* Hardcoded command line to start the system server */
667 String args[] = {
668 "--setuid=1000",
669 "--setgid=1000",
Jerry Zhang6d319b82017-12-06 16:03:57 -0800670 "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1024,1032,1065,3001,3002,3003,3006,3007,3009,3010",
Alex Klyubin48a06e72013-04-19 10:01:42 -0700671 "--capabilities=" + capabilities + "," + capabilities,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800672 "--nice-name=system_server",
Narayan Kamathb6b044a2015-02-13 17:31:25 +0000673 "--runtime-args",
Jeff Sharkey27e4b742018-02-16 17:25:14 -0700674 "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800675 "com.android.server.SystemServer",
676 };
677 ZygoteConnection.Arguments parsedArgs = null;
678
679 int pid;
680
681 try {
682 parsedArgs = new ZygoteConnection.Arguments(args);
Jeff Brownebed7d62011-05-16 17:08:42 -0700683 ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
684 ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800685
Calin Juravle8eb891b2018-05-03 19:51:18 -0700686 boolean profileSystemServer = SystemProperties.getBoolean(
687 "dalvik.vm.profilesystemserver", false);
688 if (profileSystemServer) {
689 parsedArgs.runtimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
690 }
691
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800692 /* Request to fork the system server process */
693 pid = Zygote.forkSystemServer(
694 parsedArgs.uid, parsedArgs.gid,
Elliott Hughese1dfcb72011-07-08 11:08:07 -0700695 parsedArgs.gids,
Nicolas Geoffray81edac42017-09-07 14:13:29 +0100696 parsedArgs.runtimeFlags,
Elliott Hughese1dfcb72011-07-08 11:08:07 -0700697 null,
Andy McFadden1b4c7962010-10-27 11:26:05 -0700698 parsedArgs.permittedCapabilities,
699 parsedArgs.effectiveCapabilities);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800700 } catch (IllegalArgumentException ex) {
701 throw new RuntimeException(ex);
Bob Leee5408332009-09-04 18:31:17 -0700702 }
703
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800704 /* For child process */
705 if (pid == 0) {
Narayan Kamath64cd9072014-05-13 13:35:14 +0100706 if (hasSecondZygote(abiList)) {
707 waitForSecondaryZygote(socketName);
708 }
709
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000710 zygoteServer.closeServerSocket();
Narayan Kamathbf99d062017-07-05 14:45:38 +0100711 return handleSystemServerProcess(parsedArgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800712 }
713
Narayan Kamathbf99d062017-07-05 14:45:38 +0100714 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800715 }
716
Alex Klyubin48a06e72013-04-19 10:01:42 -0700717 /**
718 * Gets the bit array representation of the provided list of POSIX capabilities.
719 */
720 private static long posixCapabilitiesAsBits(int... capabilities) {
721 long result = 0;
722 for (int capability : capabilities) {
723 if ((capability < 0) || (capability > OsConstants.CAP_LAST_CAP)) {
724 throw new IllegalArgumentException(String.valueOf(capability));
725 }
726 result |= (1L << capability);
727 }
728 return result;
729 }
730
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800731 public static void main(String argv[]) {
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000732 ZygoteServer zygoteServer = new ZygoteServer();
733
Andreas Gampe1ef8aef2016-04-11 08:39:52 -0700734 // Mark zygote start. This ensures that thread creation will throw
735 // an error.
736 ZygoteHooks.startZygoteNoThreadCreation();
737
Robert Seseke4f8d692016-09-13 19:13:01 -0400738 // Zygote goes into its own process group.
739 try {
740 Os.setpgid(0, 0);
741 } catch (ErrnoException ex) {
742 throw new RuntimeException("Failed to setpgid(0,0)", ex);
743 }
744
Narayan Kamathbf99d062017-07-05 14:45:38 +0100745 final Runnable caller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800746 try {
Fyodor Kupolov6733e6c2017-01-06 18:27:05 -0800747 // Report Zygote start time to tron unless it is a runtime restart
748 if (!"1".equals(SystemProperties.get("sys.boot_completed"))) {
749 MetricsLogger.histogram(null, "boot_zygote_init",
750 (int) SystemClock.elapsedRealtime());
751 }
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800752
753 String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
Fyodor Kupolov6e3461b2017-08-10 17:00:43 -0700754 TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag,
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800755 Trace.TRACE_TAG_DALVIK);
756 bootTimingsTraceLog.traceBegin("ZygoteInit");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900757 RuntimeInit.enableDdms();
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900758
Narayan Kamathc41638c2014-04-07 13:56:15 +0100759 boolean startSystemServer = false;
760 String socketName = "zygote";
761 String abiList = null;
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000762 boolean enableLazyPreload = false;
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900763 for (int i = 1; i < argv.length; i++) {
764 if ("start-system-server".equals(argv[i])) {
765 startSystemServer = true;
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000766 } else if ("--enable-lazy-preload".equals(argv[i])) {
767 enableLazyPreload = true;
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900768 } else if (argv[i].startsWith(ABI_LIST_ARG)) {
769 abiList = argv[i].substring(ABI_LIST_ARG.length());
770 } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
771 socketName = argv[i].substring(SOCKET_NAME_ARG.length());
772 } else {
773 throw new RuntimeException("Unknown command line argument: " + argv[i]);
Narayan Kamathc41638c2014-04-07 13:56:15 +0100774 }
775 }
776
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900777 if (abiList == null) {
778 throw new RuntimeException("No ABI list supplied.");
779 }
780
Robert Sesekd0a190df2018-02-12 18:46:01 -0500781 zygoteServer.registerServerSocketFromEnv(socketName);
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000782 // In some configurations, we avoid preloading resources and classes eagerly.
783 // In such cases, we will preload things prior to our first fork.
784 if (!enableLazyPreload) {
785 bootTimingsTraceLog.traceBegin("ZygotePreload");
786 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
787 SystemClock.uptimeMillis());
788 preload(bootTimingsTraceLog);
789 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
790 SystemClock.uptimeMillis());
791 bootTimingsTraceLog.traceEnd(); // ZygotePreload
Narayan Kamathb49996d2017-02-06 20:24:08 +0000792 } else {
Hiroshi Yamauchi1e3db872017-03-02 13:39:07 -0800793 Zygote.resetNicePriority();
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000794 }
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900795
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900796 // Do an initial gc to clean up after startup
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800797 bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900798 gcAndFinalize();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800799 bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900800
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800801 bootTimingsTraceLog.traceEnd(); // ZygoteInit
Jamie Gennis6ad04522013-04-15 18:53:24 -0700802 // Disable tracing so that forked processes do not inherit stale tracing tags from
803 // Zygote.
John Reck62cc1192017-05-12 15:39:51 -0700804 Trace.setTracingEnabled(false, 0);
Jamie Gennis6ad04522013-04-15 18:53:24 -0700805
Victor Hsiehc8176ef2018-01-08 12:43:00 -0800806 Zygote.nativeSecurityInit();
807
doheon1.lee885b7422016-01-20 13:07:27 +0900808 // Zygote process unmounts root storage spaces.
809 Zygote.nativeUnmountStorageOnInit();
810
Andreas Gampe1ef8aef2016-04-11 08:39:52 -0700811 ZygoteHooks.stopZygoteNoThreadCreation();
812
Narayan Kamathc41638c2014-04-07 13:56:15 +0100813 if (startSystemServer) {
Narayan Kamathbf99d062017-07-05 14:45:38 +0100814 Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
815
816 // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
817 // child (system_server) process.
818 if (r != null) {
819 r.run();
820 return;
821 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800822 }
823
824 Log.i(TAG, "Accepting command socket connections");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800825
Narayan Kamathbf99d062017-07-05 14:45:38 +0100826 // The select loop returns early in the child process after a fork and
827 // loops forever in the zygote.
828 caller = zygoteServer.runSelectLoop(abiList);
Christopher Ferrisea8b5de2016-06-17 15:29:58 -0700829 } catch (Throwable ex) {
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000830 Log.e(TAG, "System zygote died with exception", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800831 throw ex;
Narayan Kamathbf99d062017-07-05 14:45:38 +0100832 } finally {
833 zygoteServer.closeServerSocket();
834 }
835
836 // We're in the child process and have exited the select loop. Proceed to execute the
837 // command.
838 if (caller != null) {
839 caller.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800840 }
841 }
842
843 /**
Narayan Kamath64cd9072014-05-13 13:35:14 +0100844 * Return {@code true} if this device configuration has another zygote.
845 *
846 * We determine this by comparing the device ABI list with this zygotes
847 * list. If this zygote supports all ABIs this device supports, there won't
848 * be another zygote.
849 */
850 private static boolean hasSecondZygote(String abiList) {
851 return !SystemProperties.get("ro.product.cpu.abilist").equals(abiList);
852 }
853
854 private static void waitForSecondaryZygote(String socketName) {
Chris Wailesefce9292019-01-11 13:19:20 -0800855 String otherZygoteName = ZygoteProcess.ZYGOTE_SOCKET_NAME.equals(socketName)
856 ? ZygoteProcess.ZYGOTE_SECONDARY_SOCKET_NAME : ZygoteProcess.ZYGOTE_SOCKET_NAME;
Gustav Senntonf0c52b52017-04-27 17:00:50 +0100857 ZygoteProcess.waitForConnectionToZygote(otherZygoteName);
Narayan Kamath64cd9072014-05-13 13:35:14 +0100858 }
859
Narayan Kamath669afcc2017-02-06 20:24:08 +0000860 static boolean isPreloadComplete() {
861 return sPreloadComplete;
862 }
863
Narayan Kamath64cd9072014-05-13 13:35:14 +0100864 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800865 * Class not instantiable.
866 */
867 private ZygoteInit() {
868 }
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800869
870 /**
871 * The main function called when started through the zygote process. This
872 * could be unified with main(), if the native code in nativeFinishInit()
873 * were rationalized with Zygote startup.<p>
874 *
875 * Current recognized args:
876 * <ul>
877 * <li> <code> [--] &lt;start class name&gt; &lt;args&gt;
878 * </ul>
879 *
880 * @param targetSdkVersion target SDK version
881 * @param argv arg strings
882 */
Narayan Kamathbf99d062017-07-05 14:45:38 +0100883 public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800884 if (RuntimeInit.DEBUG) {
885 Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
886 }
887
888 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
889 RuntimeInit.redirectLogStreams();
890
891 RuntimeInit.commonInit();
892 ZygoteInit.nativeZygoteInit();
Narayan Kamathbf99d062017-07-05 14:45:38 +0100893 return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800894 }
895
Robert Sesekd0a190df2018-02-12 18:46:01 -0500896 /**
897 * The main function called when starting a child zygote process. This is used as an
898 * alternative to zygoteInit(), which skips calling into initialization routines that
899 * start the Binder threadpool.
900 */
901 static final Runnable childZygoteInit(
902 int targetSdkVersion, String[] argv, ClassLoader classLoader) {
903 RuntimeInit.Arguments args = new RuntimeInit.Arguments(argv);
904 return RuntimeInit.findStaticMain(args.startClass, args.startArgs, classLoader);
905 }
906
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800907 private static final native void nativeZygoteInit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800908}