blob: a0fe76222f12e2fbc71e0448d71d276196203ede [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;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027import android.net.LocalServerSocket;
Jesse Hallba0370e2017-02-09 14:43:14 -080028import android.opengl.EGL14;
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -070029import android.os.Build;
Jeff Sharkey740f5232016-12-09 14:31:26 -070030import android.os.IInstalld;
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -070031import android.os.Environment;
Jeff Brownebed7d62011-05-16 17:08:42 -070032import android.os.Process;
Jeff Sharkey740f5232016-12-09 14:31:26 -070033import android.os.RemoteException;
Paul Lawrenceef854772017-01-31 09:54:31 -080034import android.os.Seccomp;
Jeff Sharkey740f5232016-12-09 14:31:26 -070035import android.os.ServiceManager;
36import android.os.ServiceSpecificException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037import android.os.SystemClock;
Romain Guyc5e36382013-05-09 11:08:17 -070038import android.os.SystemProperties;
Jamie Gennis6ad04522013-04-15 18:53:24 -070039import android.os.Trace;
Robert Sesek8f8d1872016-03-18 16:52:57 -040040import android.os.ZygoteProcess;
Jeff Sharkeyc98c7bc2016-12-07 14:57:34 -070041import android.os.storage.StorageManager;
Sergio Giro69de3202016-05-17 16:52:33 +010042import android.security.keystore.AndroidKeyStoreProvider;
Bill Yi9a76e9b2014-04-29 18:52:48 -070043import android.system.ErrnoException;
Elliott Hughes860c5912014-04-28 19:19:13 -070044import android.system.Os;
45import android.system.OsConstants;
Luis Hector Chavez72042c92017-07-12 10:03:30 -070046import android.system.StructCapUserData;
47import android.system.StructCapUserHeader;
Raph Levienc3dd1c12015-04-06 10:37:57 -070048import android.text.Hyphenator;
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -080049import android.util.BootTimingsTraceLog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050import android.util.EventLog;
51import android.util.Log;
Andreas Gampe76d4fc82017-02-07 19:44:37 -080052import android.util.Slog;
Torne (Richard Coles)08cfaf62014-05-08 16:07:05 +010053import android.webkit.WebViewFactory;
Andreas Gampeddc13972016-02-26 16:54:59 -080054import android.widget.TextView;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -080056import com.android.internal.logging.MetricsLogger;
Jeff Sharkeyfdeeeea2016-01-11 17:34:24 -070057
Narayan Kamath669afcc2017-02-06 20:24:08 +000058import com.android.internal.util.Preconditions;
Narayan Kamath29564cd2014-08-07 10:57:40 +010059import dalvik.system.DexFile;
60import dalvik.system.PathClassLoader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061import dalvik.system.VMRuntime;
Andreas Gampe1ef8aef2016-04-11 08:39:52 -070062import dalvik.system.ZygoteHooks;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063
Brian Carlstrom46703b02011-04-06 15:41:29 -070064import libcore.io.IoUtils;
65
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066import java.io.BufferedReader;
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -070067import java.io.File;
Ying Wangd0c45352014-11-13 15:22:47 -080068import java.io.FileInputStream;
69import java.io.FileNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070import java.io.IOException;
71import java.io.InputStream;
72import java.io.InputStreamReader;
Sergio Giro6cb7b1c2016-05-13 16:34:46 +010073import java.security.Security;
74import java.security.Provider;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075
76/**
77 * Startup class for the zygote process.
78 *
79 * Pre-initializes some classes, and then waits for commands on a UNIX domain
Elliott Hughese1dfcb72011-07-08 11:08:07 -070080 * socket. Based on these commands, forks off child processes that inherit
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081 * the initial state of the VM.
82 *
83 * Please see {@link ZygoteConnection.Arguments} for documentation on the
84 * client protocol.
85 *
86 * @hide
87 */
88public class ZygoteInit {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089 private static final String TAG = "Zygote";
90
Jesse Hall2852a282017-01-17 10:17:41 -080091 private static final String PROPERTY_DISABLE_OPENGL_PRELOADING = "ro.zygote.disable_gl_preload";
Jesse Hallba0370e2017-02-09 14:43:14 -080092 private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
Romain Guyc5e36382013-05-09 11:08:17 -070093
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094 private static final int LOG_BOOT_PROGRESS_PRELOAD_START = 3020;
95 private static final int LOG_BOOT_PROGRESS_PRELOAD_END = 3030;
96
97 /** when preloading, GC after allocating this many bytes */
98 private static final int PRELOAD_GC_THRESHOLD = 50000;
99
Narayan Kamathc41638c2014-04-07 13:56:15 +0100100 private static final String ABI_LIST_ARG = "--abi-list=";
101
102 private static final String SOCKET_NAME_ARG = "--socket-name=";
Barry Hayes0b3533a2010-01-20 12:46:47 -0800103
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104 /**
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000105 * Used to pre-load resources.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106 */
107 private static Resources mResources;
Bob Leee5408332009-09-04 18:31:17 -0700108
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109 /**
Ying Wangd0c45352014-11-13 15:22:47 -0800110 * The path of a file that contains classes to preload.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111 */
Ying Wangd0c45352014-11-13 15:22:47 -0800112 private static final String PRELOADED_CLASSES = "/system/etc/preloaded-classes";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113
114 /** Controls whether we should preload resources during zygote init. */
Steve Paik3c27a232015-06-10 18:25:44 -0700115 public static final boolean PRELOAD_RESOURCES = true;
Andy McFadden599c9182009-04-08 00:35:56 -0700116
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117 private static final int UNPRIVILEGED_UID = 9999;
118 private static final int UNPRIVILEGED_GID = 9999;
119
120 private static final int ROOT_UID = 0;
121 private static final int ROOT_GID = 0;
122
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000123 private static boolean sPreloadComplete;
124
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800125 static void preload(BootTimingsTraceLog bootTimingsTraceLog) {
Bill Yi9a76e9b2014-04-29 18:52:48 -0700126 Log.d(TAG, "begin preload");
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800127 bootTimingsTraceLog.traceBegin("BeginIcuCachePinning");
Neil Fuller4f41f612016-05-09 16:55:36 +0100128 beginIcuCachePinning();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800129 bootTimingsTraceLog.traceEnd(); // BeginIcuCachePinning
130 bootTimingsTraceLog.traceBegin("PreloadClasses");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900131 preloadClasses();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800132 bootTimingsTraceLog.traceEnd(); // PreloadClasses
133 bootTimingsTraceLog.traceBegin("PreloadResources");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900134 preloadResources();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800135 bootTimingsTraceLog.traceEnd(); // PreloadResources
Jesse Hall42cf26e2017-07-06 15:30:39 -0700136 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs");
137 nativePreloadAppProcessHALs();
138 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Jesse Hallba0370e2017-02-09 14:43:14 -0800139 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadOpenGL");
140 preloadOpenGL();
141 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Brian Carlstrom6c9af962014-09-11 15:36:00 -0700142 preloadSharedLibraries();
Raph Levienc3dd1c12015-04-06 10:37:57 -0700143 preloadTextResources();
Torne (Richard Coles)08cfaf62014-05-08 16:07:05 +0100144 // Ask the WebViewFactory to do any initialization that must run in the zygote process,
145 // for memory sharing purposes.
146 WebViewFactory.prepareWebViewInZygote();
Neil Fuller4f41f612016-05-09 16:55:36 +0100147 endIcuCachePinning();
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100148 warmUpJcaProviders();
Bill Yi9a76e9b2014-04-29 18:52:48 -0700149 Log.d(TAG, "end preload");
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000150
151 sPreloadComplete = true;
152 }
153
Narayan Kamath669afcc2017-02-06 20:24:08 +0000154 public static void lazyPreload() {
155 Preconditions.checkState(!sPreloadComplete);
156 Log.i(TAG, "Lazily preloading resources.");
157
158 preload(new BootTimingsTraceLog("ZygoteInitTiming_lazy", Trace.TRACE_TAG_DALVIK));
Romain Guy74c69122013-05-08 17:54:20 -0700159 }
160
Neil Fuller4f41f612016-05-09 16:55:36 +0100161 private static void beginIcuCachePinning() {
162 // Pin ICU data in memory from this point that would normally be held by soft references.
163 // Without this, any references created immediately below or during class preloading
164 // would be collected when the Zygote GC runs in gcAndFinalize().
165 Log.i(TAG, "Installing ICU cache reference pinning...");
166
167 CacheValue.setStrength(CacheValue.Strength.STRONG);
168
169 Log.i(TAG, "Preloading ICU data...");
170 // Explicitly exercise code to cache data apps are likely to need.
171 ULocale[] localesToPin = { ULocale.ROOT, ULocale.US, ULocale.getDefault() };
172 for (ULocale uLocale : localesToPin) {
173 new DecimalFormatSymbols(uLocale);
174 }
175 }
176
177 private static void endIcuCachePinning() {
178 // All cache references created by ICU from this point will be soft.
179 CacheValue.setStrength(CacheValue.Strength.SOFT);
180
181 Log.i(TAG, "Uninstalled ICU cache reference pinning...");
182 }
183
Brian Carlstrom6c9af962014-09-11 15:36:00 -0700184 private static void preloadSharedLibraries() {
185 Log.i(TAG, "Preloading shared libraries...");
186 System.loadLibrary("android");
187 System.loadLibrary("compiler_rt");
188 System.loadLibrary("jnigraphics");
189 }
190
Jesse Hall42cf26e2017-07-06 15:30:39 -0700191 native private static void nativePreloadAppProcessHALs();
192
Jesse Hallba0370e2017-02-09 14:43:14 -0800193 private static void preloadOpenGL() {
194 String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
Jesse Hall5d911fe2017-04-13 15:44:24 -0700195 if (!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING, false) &&
196 (driverPackageName == null || driverPackageName.isEmpty())) {
Jesse Hallba0370e2017-02-09 14:43:14 -0800197 EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
198 }
199 }
200
Raph Levienc3dd1c12015-04-06 10:37:57 -0700201 private static void preloadTextResources() {
202 Hyphenator.init();
Andreas Gampeddc13972016-02-26 16:54:59 -0800203 TextView.preloadFontCache();
Raph Levienc3dd1c12015-04-06 10:37:57 -0700204 }
205
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206 /**
Sergio Giro69de3202016-05-17 16:52:33 +0100207 * Register AndroidKeyStoreProvider and warm up the providers that are already registered.
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100208 *
209 * By doing it here we avoid that each app does it when requesting a service from the
210 * provider for the first time.
211 */
212 private static void warmUpJcaProviders() {
213 long startTime = SystemClock.uptimeMillis();
214 Trace.traceBegin(
Sergio Giro69de3202016-05-17 16:52:33 +0100215 Trace.TRACE_TAG_DALVIK, "Starting installation of AndroidKeyStoreProvider");
216 // AndroidKeyStoreProvider.install() manipulates the list of JCA providers to insert
217 // preferred providers. Note this is not done via security.properties as the JCA providers
218 // are not on the classpath in the case of, for example, raw dalvikvm runtimes.
219 AndroidKeyStoreProvider.install();
220 Log.i(TAG, "Installed AndroidKeyStoreProvider in "
221 + (SystemClock.uptimeMillis() - startTime) + "ms.");
222 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
223
224 startTime = SystemClock.uptimeMillis();
225 Trace.traceBegin(
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100226 Trace.TRACE_TAG_DALVIK, "Starting warm up of JCA providers");
227 for (Provider p : Security.getProviders()) {
228 p.warmUpServiceProvision();
229 }
230 Log.i(TAG, "Warmed up JCA providers in "
Sergio Giro69de3202016-05-17 16:52:33 +0100231 + (SystemClock.uptimeMillis() - startTime) + "ms.");
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100232 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
233 }
234
235 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800236 * Performs Zygote process initialization. Loads and initializes
237 * commonly used classes.
238 *
239 * Most classes only cause a few hundred bytes to be allocated, but
240 * a few will allocate a dozen Kbytes (in one case, 500+K).
241 */
242 private static void preloadClasses() {
243 final VMRuntime runtime = VMRuntime.getRuntime();
Bob Leee5408332009-09-04 18:31:17 -0700244
Ying Wangd0c45352014-11-13 15:22:47 -0800245 InputStream is;
246 try {
247 is = new FileInputStream(PRELOADED_CLASSES);
248 } catch (FileNotFoundException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800249 Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + ".");
Ying Wangd0c45352014-11-13 15:22:47 -0800250 return;
251 }
Bob Leee5408332009-09-04 18:31:17 -0700252
Ying Wangd0c45352014-11-13 15:22:47 -0800253 Log.i(TAG, "Preloading classes...");
254 long startTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800255
Ying Wangd0c45352014-11-13 15:22:47 -0800256 // Drop root perms while running static initializers.
Narayan Kamath23e68782015-01-16 17:22:41 +0000257 final int reuid = Os.getuid();
258 final int regid = Os.getgid();
259
260 // We need to drop root perms only if we're already root. In the case of "wrapped"
261 // processes (see WrapperInit), this function is called from an unprivileged uid
262 // and gid.
263 boolean droppedPriviliges = false;
264 if (reuid == ROOT_UID && regid == ROOT_GID) {
265 try {
266 Os.setregid(ROOT_GID, UNPRIVILEGED_GID);
267 Os.setreuid(ROOT_UID, UNPRIVILEGED_UID);
268 } catch (ErrnoException ex) {
269 throw new RuntimeException("Failed to drop root", ex);
270 }
271
272 droppedPriviliges = true;
Elliott Hughes26b56e62014-12-17 12:28:29 -0800273 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800274
Ying Wangd0c45352014-11-13 15:22:47 -0800275 // Alter the target heap utilization. With explicit GCs this
276 // is not likely to have any effect.
277 float defaultUtilization = runtime.getTargetHeapUtilization();
278 runtime.setTargetHeapUtilization(0.8f);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279
Ying Wangd0c45352014-11-13 15:22:47 -0800280 try {
281 BufferedReader br
282 = new BufferedReader(new InputStreamReader(is), 256);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800283
Ying Wangd0c45352014-11-13 15:22:47 -0800284 int count = 0;
285 String line;
286 while ((line = br.readLine()) != null) {
287 // Skip comments and blank lines.
288 line = line.trim();
289 if (line.startsWith("#") || line.equals("")) {
290 continue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800291 }
292
Andreas Gampec4253622016-10-28 18:19:30 -0700293 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, line);
Ying Wangd0c45352014-11-13 15:22:47 -0800294 try {
295 if (false) {
296 Log.v(TAG, "Preloading " + line + "...");
297 }
Andreas Gampedd8e5fb2015-04-21 09:01:51 -0700298 // Load and explicitly initialize the given class. Use
299 // Class.forName(String, boolean, ClassLoader) to avoid repeated stack lookups
300 // (to derive the caller's class-loader). Use true to force initialization, and
301 // null for the boot classpath class-loader (could as well cache the
302 // class-loader of this class in a variable).
Andreas Gampec917f742015-04-20 19:16:37 -0700303 Class.forName(line, true, null);
Ying Wangd0c45352014-11-13 15:22:47 -0800304 count++;
305 } catch (ClassNotFoundException e) {
306 Log.w(TAG, "Class not found for preloading: " + line);
307 } catch (UnsatisfiedLinkError e) {
308 Log.w(TAG, "Problem preloading " + line + ": " + e);
309 } catch (Throwable t) {
310 Log.e(TAG, "Error preloading " + line + ".", t);
311 if (t instanceof Error) {
312 throw (Error) t;
313 }
314 if (t instanceof RuntimeException) {
315 throw (RuntimeException) t;
316 }
317 throw new RuntimeException(t);
318 }
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900319 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800320 }
Ying Wangd0c45352014-11-13 15:22:47 -0800321
322 Log.i(TAG, "...preloaded " + count + " classes in "
323 + (SystemClock.uptimeMillis()-startTime) + "ms.");
324 } catch (IOException e) {
325 Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);
326 } finally {
327 IoUtils.closeQuietly(is);
328 // Restore default.
329 runtime.setTargetHeapUtilization(defaultUtilization);
330
331 // Fill in dex caches with classes, fields, and methods brought in by preloading.
Yasuhiro Matsuda1ab43d52015-06-30 17:07:32 +0900332 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadDexCaches");
Ying Wangd0c45352014-11-13 15:22:47 -0800333 runtime.preloadDexCaches();
Yasuhiro Matsuda1ab43d52015-06-30 17:07:32 +0900334 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Ying Wangd0c45352014-11-13 15:22:47 -0800335
Narayan Kamath23e68782015-01-16 17:22:41 +0000336 // Bring back root. We'll need it later if we're in the zygote.
337 if (droppedPriviliges) {
338 try {
339 Os.setreuid(ROOT_UID, ROOT_UID);
340 Os.setregid(ROOT_GID, ROOT_GID);
341 } catch (ErrnoException ex) {
342 throw new RuntimeException("Failed to restore root", ex);
343 }
Elliott Hughes26b56e62014-12-17 12:28:29 -0800344 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800345 }
346 }
347
348 /**
349 * Load in commonly used resources, so they can be shared across
350 * processes.
351 *
352 * These tend to be a few Kbytes, but are frequently in the 20-40K
353 * range, and occasionally even larger.
354 */
355 private static void preloadResources() {
356 final VMRuntime runtime = VMRuntime.getRuntime();
Bob Leee5408332009-09-04 18:31:17 -0700357
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800358 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800359 mResources = Resources.getSystem();
360 mResources.startPreloading();
361 if (PRELOAD_RESOURCES) {
362 Log.i(TAG, "Preloading resources...");
363
364 long startTime = SystemClock.uptimeMillis();
365 TypedArray ar = mResources.obtainTypedArray(
366 com.android.internal.R.array.preloaded_drawables);
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800367 int N = preloadDrawables(ar);
Jeff Brown14577c42012-03-08 16:40:14 -0800368 ar.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800369 Log.i(TAG, "...preloaded " + N + " resources in "
370 + (SystemClock.uptimeMillis()-startTime) + "ms.");
371
372 startTime = SystemClock.uptimeMillis();
373 ar = mResources.obtainTypedArray(
374 com.android.internal.R.array.preloaded_color_state_lists);
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800375 N = preloadColorStateLists(ar);
Jeff Brown14577c42012-03-08 16:40:14 -0800376 ar.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800377 Log.i(TAG, "...preloaded " + N + " resources in "
378 + (SystemClock.uptimeMillis()-startTime) + "ms.");
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800379
380 if (mResources.getBoolean(
381 com.android.internal.R.bool.config_freeformWindowManagement)) {
382 startTime = SystemClock.uptimeMillis();
383 ar = mResources.obtainTypedArray(
384 com.android.internal.R.array.preloaded_freeform_multi_window_drawables);
385 N = preloadDrawables(ar);
386 ar.recycle();
387 Log.i(TAG, "...preloaded " + N + " resource in "
388 + (SystemClock.uptimeMillis() - startTime) + "ms.");
389 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800390 }
391 mResources.finishPreloading();
392 } catch (RuntimeException e) {
393 Log.w(TAG, "Failure preloading resources", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800394 }
395 }
396
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800397 private static int preloadColorStateLists(TypedArray ar) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398 int N = ar.length();
399 for (int i=0; i<N; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800400 int id = ar.getResourceId(i, 0);
Joe Onorato43a17652011-04-06 19:22:23 -0700401 if (false) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402 Log.v(TAG, "Preloading resource #" + Integer.toHexString(id));
403 }
404 if (id != 0) {
Alan Viverette77bb6f12015-02-11 17:24:33 -0800405 if (mResources.getColorStateList(id, null) == null) {
Dianne Hackborndde331c2012-08-03 14:01:57 -0700406 throw new IllegalArgumentException(
407 "Unable to find preloaded color resource #0x"
408 + Integer.toHexString(id)
409 + " (" + ar.getString(i) + ")");
410 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800411 }
412 }
413 return N;
414 }
415
416
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800417 private static int preloadDrawables(TypedArray ar) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800418 int N = ar.length();
419 for (int i=0; i<N; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800420 int id = ar.getResourceId(i, 0);
Joe Onorato43a17652011-04-06 19:22:23 -0700421 if (false) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800422 Log.v(TAG, "Preloading resource #" + Integer.toHexString(id));
423 }
424 if (id != 0) {
Alan Viverette84e001a2014-09-22 00:04:22 -0700425 if (mResources.getDrawable(id, null) == null) {
Dianne Hackborndde331c2012-08-03 14:01:57 -0700426 throw new IllegalArgumentException(
427 "Unable to find preloaded drawable resource #0x"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800428 + Integer.toHexString(id)
Dianne Hackborndde331c2012-08-03 14:01:57 -0700429 + " (" + ar.getString(i) + ")");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800430 }
431 }
432 }
433 return N;
434 }
435
436 /**
437 * Runs several special GCs to try to clean up a few generations of
438 * softly- and final-reachable objects, along with any other garbage.
439 * This is only useful just before a fork().
440 */
Mathieu Chartier9a88f102014-08-20 10:24:11 -0700441 /*package*/ static void gcAndFinalize() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800442 final VMRuntime runtime = VMRuntime.getRuntime();
443
444 /* runFinalizationSync() lets finalizers be called in Zygote,
445 * which doesn't have a HeapWorker thread.
446 */
Brian Carlstrom08065b92011-04-01 15:49:41 -0700447 System.gc();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800448 runtime.runFinalizationSync();
Brian Carlstrom08065b92011-04-01 15:49:41 -0700449 System.gc();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800450 }
451
452 /**
453 * Finish remaining work for the newly forked system server process.
454 */
455 private static void handleSystemServerProcess(
456 ZygoteConnection.Arguments parsedArgs)
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000457 throws Zygote.MethodAndArgsCaller {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800458
Mike Lockwood90960e82010-08-06 09:15:25 -0400459 // set umask to 0077 so new files and directories will default to owner-only permissions.
Elliott Hughes860c5912014-04-28 19:19:13 -0700460 Os.umask(S_IRWXG | S_IRWXO);
Mike Lockwood90960e82010-08-06 09:15:25 -0400461
Jeff Brownebed7d62011-05-16 17:08:42 -0700462 if (parsedArgs.niceName != null) {
463 Process.setArgV0(parsedArgs.niceName);
464 }
465
Narayan Kamath29564cd2014-08-07 10:57:40 +0100466 final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
467 if (systemServerClasspath != null) {
468 performSystemServerDexOpt(systemServerClasspath);
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -0700469 // Capturing profiles is only supported for debug or eng builds since selinux normally
470 // prevents it.
471 boolean profileSystemServer = SystemProperties.getBoolean(
472 "dalvik.vm.profilesystemserver", false);
473 if (profileSystemServer && (Build.IS_USERDEBUG || Build.IS_ENG)) {
474 try {
475 File profileDir = Environment.getDataProfilesDePackageDirectory(
476 Process.SYSTEM_UID, "system_server");
477 File profile = new File(profileDir, "primary.prof");
478 profile.getParentFile().mkdirs();
479 profile.createNewFile();
480 String[] codePaths = systemServerClasspath.split(":");
481 VMRuntime.registerAppInfo(profile.getPath(), codePaths);
482 } catch (Exception e) {
483 Log.wtf(TAG, "Failed to set up system server profile", e);
484 }
485 }
Narayan Kamath29564cd2014-08-07 10:57:40 +0100486 }
487
Jeff Brownebed7d62011-05-16 17:08:42 -0700488 if (parsedArgs.invokeWith != null) {
Narayan Kamath29564cd2014-08-07 10:57:40 +0100489 String[] args = parsedArgs.remainingArgs;
490 // If we have a non-null system server class path, we'll have to duplicate the
491 // existing arguments and append the classpath to it. ART will handle the classpath
492 // correctly when we exec a new process.
493 if (systemServerClasspath != null) {
494 String[] amendedArgs = new String[args.length + 2];
495 amendedArgs[0] = "-cp";
496 amendedArgs[1] = systemServerClasspath;
tony.ys_liu34738172016-12-14 18:50:29 +0800497 System.arraycopy(args, 0, amendedArgs, 2, args.length);
498 args = amendedArgs;
Narayan Kamath29564cd2014-08-07 10:57:40 +0100499 }
500
Jeff Brownebed7d62011-05-16 17:08:42 -0700501 WrapperInit.execApplication(parsedArgs.invokeWith,
Elliott Hughese1dfcb72011-07-08 11:08:07 -0700502 parsedArgs.niceName, parsedArgs.targetSdkVersion,
Narayan Kamath37ad4b02015-01-19 16:05:24 +0000503 VMRuntime.getCurrentInstructionSet(), null, args);
Jeff Brownebed7d62011-05-16 17:08:42 -0700504 } else {
Narayan Kamath29564cd2014-08-07 10:57:40 +0100505 ClassLoader cl = null;
506 if (systemServerClasspath != null) {
tony.ys_liu34738172016-12-14 18:50:29 +0800507 cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700508
Narayan Kamath29564cd2014-08-07 10:57:40 +0100509 Thread.currentThread().setContextClassLoader(cl);
510 }
511
Jeff Brownebed7d62011-05-16 17:08:42 -0700512 /*
513 * Pass the remaining arguments to SystemServer.
514 */
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800515 ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
Jeff Brownebed7d62011-05-16 17:08:42 -0700516 }
517
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800518 /* should never reach here */
519 }
520
521 /**
tony.ys_liu34738172016-12-14 18:50:29 +0800522 * Creates a PathClassLoader for the given class path that is associated with a shared
523 * namespace, i.e., this classloader can access platform-private native libraries. The
524 * classloader will use java.library.path as the native library path.
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700525 */
tony.ys_liu34738172016-12-14 18:50:29 +0800526 static PathClassLoader createPathClassLoader(String classPath, int targetSdkVersion) {
Dimitry Ivanov9e9061f2016-09-20 10:50:40 -0700527 String libraryPath = System.getProperty("java.library.path");
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700528
tony.ys_liu34738172016-12-14 18:50:29 +0800529 return PathClassLoaderFactory.createClassLoader(classPath,
Dimitry Ivanov9e9061f2016-09-20 10:50:40 -0700530 libraryPath,
531 libraryPath,
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700532 ClassLoader.getSystemClassLoader(),
533 targetSdkVersion,
534 true /* isNamespaceShared */);
535 }
536
537 /**
Narayan Kamath29564cd2014-08-07 10:57:40 +0100538 * Performs dex-opt on the elements of {@code classPath}, if needed. We
539 * choose the instruction set of the current runtime.
540 */
541 private static void performSystemServerDexOpt(String classPath) {
542 final String[] classPathElements = classPath.split(":");
Jeff Sharkey740f5232016-12-09 14:31:26 -0700543 final IInstalld installd = IInstalld.Stub
544 .asInterface(ServiceManager.getService("installd"));
Narayan Kamath29564cd2014-08-07 10:57:40 +0100545 final String instructionSet = VMRuntime.getRuntime().vmInstructionSet();
546
Jeff Sharkey740f5232016-12-09 14:31:26 -0700547 String sharedLibraries = "";
548 for (String classPathElement : classPathElements) {
549 // System server is fully AOTed and never profiled
550 // for profile guided compilation.
551 // TODO: Make this configurable between INTERPRET_ONLY, SPEED, SPACE and EVERYTHING?
Andreas Gampee7bc1522016-08-09 20:44:04 -0700552
Jeff Sharkey740f5232016-12-09 14:31:26 -0700553 int dexoptNeeded;
554 try {
555 dexoptNeeded = DexFile.getDexOptNeeded(
556 classPathElement, instructionSet, "speed",
Shubham Ajmera52c86202017-07-24 15:21:04 -0700557 false /* newProfile */, false /* downgrade */);
Jeff Sharkey740f5232016-12-09 14:31:26 -0700558 } catch (FileNotFoundException ignored) {
559 // Do not add to the classpath.
560 Log.w(TAG, "Missing classpath element for system server: " + classPathElement);
561 continue;
562 } catch (IOException e) {
563 // Not fully clear what to do here as we don't know the cause of the
564 // IO exception. Add to the classpath to be conservative, but don't
565 // attempt to compile it.
566 Log.w(TAG, "Error checking classpath element for system server: "
567 + classPathElement, e);
568 dexoptNeeded = DexFile.NO_DEXOPT_NEEDED;
Narayan Kamath29564cd2014-08-07 10:57:40 +0100569 }
Jeff Sharkey740f5232016-12-09 14:31:26 -0700570
571 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
572 final String packageName = "*";
573 final String outputPath = null;
574 final int dexFlags = 0;
575 final String compilerFilter = "speed";
576 final String uuid = StorageManager.UUID_PRIVATE_INTERNAL;
Calin Juravle811a75a2017-04-05 22:49:38 -0700577 final String seInfo = null;
Jeff Sharkey740f5232016-12-09 14:31:26 -0700578 try {
579 installd.dexopt(classPathElement, Process.SYSTEM_UID, packageName,
580 instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter,
Calin Juravle811a75a2017-04-05 22:49:38 -0700581 uuid, sharedLibraries, seInfo);
Jeff Sharkey740f5232016-12-09 14:31:26 -0700582 } catch (RemoteException | ServiceSpecificException e) {
583 // Ignore (but log), we need this on the classpath for fallback mode.
584 Log.w(TAG, "Failed compiling classpath element for system server: "
585 + classPathElement, e);
586 }
587 }
588
589 if (!sharedLibraries.isEmpty()) {
590 sharedLibraries += ":";
591 }
592 sharedLibraries += classPathElement;
Narayan Kamath29564cd2014-08-07 10:57:40 +0100593 }
594 }
595
596 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800597 * Prepare the arguments and fork for the system server process.
598 */
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000599 private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
600 throws Zygote.MethodAndArgsCaller, RuntimeException {
Alex Klyubin48a06e72013-04-19 10:01:42 -0700601 long capabilities = posixCapabilitiesAsBits(
Philip Cuadra7bd0fdd2016-04-28 15:26:49 -0700602 OsConstants.CAP_IPC_LOCK,
Alex Klyubin48a06e72013-04-19 10:01:42 -0700603 OsConstants.CAP_KILL,
604 OsConstants.CAP_NET_ADMIN,
605 OsConstants.CAP_NET_BIND_SERVICE,
606 OsConstants.CAP_NET_BROADCAST,
607 OsConstants.CAP_NET_RAW,
Alex Klyubin48a06e72013-04-19 10:01:42 -0700608 OsConstants.CAP_SYS_MODULE,
609 OsConstants.CAP_SYS_NICE,
Nick Kralevich3082eb72017-02-15 15:12:31 -0800610 OsConstants.CAP_SYS_PTRACE,
Alex Klyubin48a06e72013-04-19 10:01:42 -0700611 OsConstants.CAP_SYS_TIME,
John Stultz5733f382016-07-28 12:35:31 -0700612 OsConstants.CAP_SYS_TTY_CONFIG,
Luis Hector Chavez72042c92017-07-12 10:03:30 -0700613 OsConstants.CAP_WAKE_ALARM,
614 OsConstants.CAP_BLOCK_SUSPEND
Alex Klyubin48a06e72013-04-19 10:01:42 -0700615 );
Luis Hector Chavez72042c92017-07-12 10:03:30 -0700616 /* Containers run without some capabilities, so drop any caps that are not available. */
617 StructCapUserHeader header = new StructCapUserHeader(
618 OsConstants._LINUX_CAPABILITY_VERSION_3, 0);
619 StructCapUserData[] data;
620 try {
621 data = Os.capget(header);
622 } catch (ErrnoException ex) {
623 throw new RuntimeException("Failed to capget()", ex);
Luis Hector Chavez5dd239a2015-10-06 14:01:45 -0700624 }
Luis Hector Chavez72042c92017-07-12 10:03:30 -0700625 capabilities &= ((long) data[0].effective) | (((long) data[1].effective) << 32);
626
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800627 /* Hardcoded command line to start the system server */
628 String args[] = {
629 "--setuid=1000",
630 "--setgid=1000",
Jeff Sharkey053a9092016-12-02 13:17:49 -0700631 "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
Alex Klyubin48a06e72013-04-19 10:01:42 -0700632 "--capabilities=" + capabilities + "," + capabilities,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800633 "--nice-name=system_server",
Narayan Kamathb6b044a2015-02-13 17:31:25 +0000634 "--runtime-args",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800635 "com.android.server.SystemServer",
636 };
637 ZygoteConnection.Arguments parsedArgs = null;
638
639 int pid;
640
641 try {
642 parsedArgs = new ZygoteConnection.Arguments(args);
Jeff Brownebed7d62011-05-16 17:08:42 -0700643 ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
644 ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800645
646 /* Request to fork the system server process */
647 pid = Zygote.forkSystemServer(
648 parsedArgs.uid, parsedArgs.gid,
Elliott Hughese1dfcb72011-07-08 11:08:07 -0700649 parsedArgs.gids,
650 parsedArgs.debugFlags,
651 null,
Andy McFadden1b4c7962010-10-27 11:26:05 -0700652 parsedArgs.permittedCapabilities,
653 parsedArgs.effectiveCapabilities);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800654 } catch (IllegalArgumentException ex) {
655 throw new RuntimeException(ex);
Bob Leee5408332009-09-04 18:31:17 -0700656 }
657
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800658 /* For child process */
659 if (pid == 0) {
Narayan Kamath64cd9072014-05-13 13:35:14 +0100660 if (hasSecondZygote(abiList)) {
661 waitForSecondaryZygote(socketName);
662 }
663
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000664 zygoteServer.closeServerSocket();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800665 handleSystemServerProcess(parsedArgs);
666 }
667
668 return true;
669 }
670
Alex Klyubin48a06e72013-04-19 10:01:42 -0700671 /**
672 * Gets the bit array representation of the provided list of POSIX capabilities.
673 */
674 private static long posixCapabilitiesAsBits(int... capabilities) {
675 long result = 0;
676 for (int capability : capabilities) {
677 if ((capability < 0) || (capability > OsConstants.CAP_LAST_CAP)) {
678 throw new IllegalArgumentException(String.valueOf(capability));
679 }
680 result |= (1L << capability);
681 }
682 return result;
683 }
684
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800685 public static void main(String argv[]) {
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000686 ZygoteServer zygoteServer = new ZygoteServer();
687
Andreas Gampe1ef8aef2016-04-11 08:39:52 -0700688 // Mark zygote start. This ensures that thread creation will throw
689 // an error.
690 ZygoteHooks.startZygoteNoThreadCreation();
691
Robert Seseke4f8d692016-09-13 19:13:01 -0400692 // Zygote goes into its own process group.
693 try {
694 Os.setpgid(0, 0);
695 } catch (ErrnoException ex) {
696 throw new RuntimeException("Failed to setpgid(0,0)", ex);
697 }
698
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800699 try {
Fyodor Kupolov6733e6c2017-01-06 18:27:05 -0800700 // Report Zygote start time to tron unless it is a runtime restart
701 if (!"1".equals(SystemProperties.get("sys.boot_completed"))) {
702 MetricsLogger.histogram(null, "boot_zygote_init",
703 (int) SystemClock.elapsedRealtime());
704 }
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800705
706 String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
707 BootTimingsTraceLog bootTimingsTraceLog = new BootTimingsTraceLog(bootTimeTag,
708 Trace.TRACE_TAG_DALVIK);
709 bootTimingsTraceLog.traceBegin("ZygoteInit");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900710 RuntimeInit.enableDdms();
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900711
Narayan Kamathc41638c2014-04-07 13:56:15 +0100712 boolean startSystemServer = false;
713 String socketName = "zygote";
714 String abiList = null;
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000715 boolean enableLazyPreload = false;
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900716 for (int i = 1; i < argv.length; i++) {
717 if ("start-system-server".equals(argv[i])) {
718 startSystemServer = true;
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000719 } else if ("--enable-lazy-preload".equals(argv[i])) {
720 enableLazyPreload = true;
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900721 } else if (argv[i].startsWith(ABI_LIST_ARG)) {
722 abiList = argv[i].substring(ABI_LIST_ARG.length());
723 } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
724 socketName = argv[i].substring(SOCKET_NAME_ARG.length());
725 } else {
726 throw new RuntimeException("Unknown command line argument: " + argv[i]);
Narayan Kamathc41638c2014-04-07 13:56:15 +0100727 }
728 }
729
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900730 if (abiList == null) {
731 throw new RuntimeException("No ABI list supplied.");
732 }
733
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000734 zygoteServer.registerServerSocket(socketName);
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000735 // In some configurations, we avoid preloading resources and classes eagerly.
736 // In such cases, we will preload things prior to our first fork.
737 if (!enableLazyPreload) {
738 bootTimingsTraceLog.traceBegin("ZygotePreload");
739 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
740 SystemClock.uptimeMillis());
741 preload(bootTimingsTraceLog);
742 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
743 SystemClock.uptimeMillis());
744 bootTimingsTraceLog.traceEnd(); // ZygotePreload
Narayan Kamathb49996d2017-02-06 20:24:08 +0000745 } else {
Hiroshi Yamauchi1e3db872017-03-02 13:39:07 -0800746 Zygote.resetNicePriority();
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000747 }
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900748
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900749 // Do an initial gc to clean up after startup
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800750 bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900751 gcAndFinalize();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800752 bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900753
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800754 bootTimingsTraceLog.traceEnd(); // ZygoteInit
Jamie Gennis6ad04522013-04-15 18:53:24 -0700755 // Disable tracing so that forked processes do not inherit stale tracing tags from
756 // Zygote.
John Reck62cc1192017-05-12 15:39:51 -0700757 Trace.setTracingEnabled(false, 0);
Jamie Gennis6ad04522013-04-15 18:53:24 -0700758
doheon1.lee885b7422016-01-20 13:07:27 +0900759 // Zygote process unmounts root storage spaces.
760 Zygote.nativeUnmountStorageOnInit();
761
Paul Lawrenceef854772017-01-31 09:54:31 -0800762 // Set seccomp policy
763 Seccomp.setPolicy();
764
Andreas Gampe1ef8aef2016-04-11 08:39:52 -0700765 ZygoteHooks.stopZygoteNoThreadCreation();
766
Narayan Kamathc41638c2014-04-07 13:56:15 +0100767 if (startSystemServer) {
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000768 startSystemServer(abiList, socketName, zygoteServer);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800769 }
770
771 Log.i(TAG, "Accepting command socket connections");
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000772 zygoteServer.runSelectLoop(abiList);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800773
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000774 zygoteServer.closeServerSocket();
775 } catch (Zygote.MethodAndArgsCaller caller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800776 caller.run();
Christopher Ferrisea8b5de2016-06-17 15:29:58 -0700777 } catch (Throwable ex) {
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000778 Log.e(TAG, "System zygote died with exception", ex);
779 zygoteServer.closeServerSocket();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800780 throw ex;
781 }
782 }
783
784 /**
Narayan Kamath64cd9072014-05-13 13:35:14 +0100785 * Return {@code true} if this device configuration has another zygote.
786 *
787 * We determine this by comparing the device ABI list with this zygotes
788 * list. If this zygote supports all ABIs this device supports, there won't
789 * be another zygote.
790 */
791 private static boolean hasSecondZygote(String abiList) {
792 return !SystemProperties.get("ro.product.cpu.abilist").equals(abiList);
793 }
794
795 private static void waitForSecondaryZygote(String socketName) {
796 String otherZygoteName = Process.ZYGOTE_SOCKET.equals(socketName) ?
797 Process.SECONDARY_ZYGOTE_SOCKET : Process.ZYGOTE_SOCKET;
Gustav Senntonf0c52b52017-04-27 17:00:50 +0100798 ZygoteProcess.waitForConnectionToZygote(otherZygoteName);
Narayan Kamath64cd9072014-05-13 13:35:14 +0100799 }
800
Narayan Kamath669afcc2017-02-06 20:24:08 +0000801 static boolean isPreloadComplete() {
802 return sPreloadComplete;
803 }
804
Narayan Kamath64cd9072014-05-13 13:35:14 +0100805 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800806 * Class not instantiable.
807 */
808 private ZygoteInit() {
809 }
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800810
811 /**
812 * The main function called when started through the zygote process. This
813 * could be unified with main(), if the native code in nativeFinishInit()
814 * were rationalized with Zygote startup.<p>
815 *
816 * Current recognized args:
817 * <ul>
818 * <li> <code> [--] &lt;start class name&gt; &lt;args&gt;
819 * </ul>
820 *
821 * @param targetSdkVersion target SDK version
822 * @param argv arg strings
823 */
824 public static final void zygoteInit(int targetSdkVersion, String[] argv,
825 ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
826 if (RuntimeInit.DEBUG) {
827 Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
828 }
829
830 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
831 RuntimeInit.redirectLogStreams();
832
833 RuntimeInit.commonInit();
834 ZygoteInit.nativeZygoteInit();
835 RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
836 }
837
838 private static final native void nativeZygoteInit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800839}