blob: e132abd7e4cb7043f94d6a97e24ec6030076cb26 [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;
Mathieu Chartierf5cd8c12019-02-04 13:28:36 -080044import android.text.TextUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045import android.util.EventLog;
46import android.util.Log;
Andreas Gampe76d4fc82017-02-07 19:44:37 -080047import android.util.Slog;
Mathew Inwood04194fe2018-04-04 14:48:03 +010048import android.util.TimingsTraceLog;
Torne (Richard Coles)08cfaf62014-05-08 16:07:05 +010049import android.webkit.WebViewFactory;
Andreas Gampeddc13972016-02-26 16:54:59 -080050import android.widget.TextView;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -080052import com.android.internal.logging.MetricsLogger;
Narayan Kamath669afcc2017-02-06 20:24:08 +000053import com.android.internal.util.Preconditions;
Mathew Inwood04194fe2018-04-04 14:48:03 +010054
Narayan Kamath29564cd2014-08-07 10:57:40 +010055import dalvik.system.DexFile;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056import dalvik.system.VMRuntime;
Andreas Gampe1ef8aef2016-04-11 08:39:52 -070057import dalvik.system.ZygoteHooks;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058
Brian Carlstrom46703b02011-04-06 15:41:29 -070059import libcore.io.IoUtils;
60
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061import java.io.BufferedReader;
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -070062import java.io.File;
Ying Wangd0c45352014-11-13 15:22:47 -080063import java.io.FileInputStream;
64import java.io.FileNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065import java.io.IOException;
66import java.io.InputStream;
67import java.io.InputStreamReader;
Sergio Giro6cb7b1c2016-05-13 16:34:46 +010068import java.security.Provider;
Mathew Inwood04194fe2018-04-04 14:48:03 +010069import java.security.Security;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070
71/**
72 * Startup class for the zygote process.
73 *
Chris Wailescd92db22019-01-11 14:30:43 -080074 * Pre-initializes some classes, and then waits for commands on a UNIX domain socket. Based on these
75 * commands, forks off child processes that inherit the initial state of the VM.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076 *
Chris Wailes682b4792019-01-11 16:14:43 -080077 * Please see {@link ZygoteArguments} for documentation on the client protocol.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078 *
79 * @hide
80 */
81public class ZygoteInit {
Chris Wailescd92db22019-01-11 14:30:43 -080082
83 // TODO (chriswailes): Change this so it is set with Zygote or ZygoteSecondary as appropriate
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084 private static final String TAG = "Zygote";
85
Jesse Hall2852a282017-01-17 10:17:41 -080086 private static final String PROPERTY_DISABLE_OPENGL_PRELOADING = "ro.zygote.disable_gl_preload";
Jesse Hallba0370e2017-02-09 14:43:14 -080087 private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
Mathieu Chartierf5cd8c12019-02-04 13:28:36 -080088 private static final String PROPERTY_USE_APP_IMAGE_STARTUP_CACHE =
89 "persist.device_config.runtime_native.use_app_image_startup_cache";
Romain Guyc5e36382013-05-09 11:08:17 -070090
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091 private static final int LOG_BOOT_PROGRESS_PRELOAD_START = 3020;
92 private static final int LOG_BOOT_PROGRESS_PRELOAD_END = 3030;
93
Chris Wailescd92db22019-01-11 14:30:43 -080094 /**
95 * when preloading, GC after allocating this many bytes
96 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097 private static final int PRELOAD_GC_THRESHOLD = 50000;
98
Narayan Kamathc41638c2014-04-07 13:56:15 +010099 private static final String ABI_LIST_ARG = "--abi-list=";
100
Chris Wailescd92db22019-01-11 14:30:43 -0800101 // TODO (chriswailes): Re-name this --zygote-socket-name= and then add a
102 // --blastula-socket-name parameter.
Narayan Kamathc41638c2014-04-07 13:56:15 +0100103 private static final String SOCKET_NAME_ARG = "--socket-name=";
Barry Hayes0b3533a2010-01-20 12:46:47 -0800104
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105 /**
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000106 * Used to pre-load resources.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107 */
108 private static Resources mResources;
Bob Leee5408332009-09-04 18:31:17 -0700109
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110 /**
Ying Wangd0c45352014-11-13 15:22:47 -0800111 * The path of a file that contains classes to preload.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112 */
Ying Wangd0c45352014-11-13 15:22:47 -0800113 private static final String PRELOADED_CLASSES = "/system/etc/preloaded-classes";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114
Chris Wailescd92db22019-01-11 14:30:43 -0800115 /**
116 * Controls whether we should preload resources during zygote init.
117 */
Steve Paik3c27a232015-06-10 18:25:44 -0700118 public static final boolean PRELOAD_RESOURCES = true;
Andy McFadden599c9182009-04-08 00:35:56 -0700119
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800120 private static final int UNPRIVILEGED_UID = 9999;
121 private static final int UNPRIVILEGED_GID = 9999;
122
123 private static final int ROOT_UID = 0;
124 private static final int ROOT_GID = 0;
125
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000126 private static boolean sPreloadComplete;
127
Fyodor Kupolov6e3461b2017-08-10 17:00:43 -0700128 static void preload(TimingsTraceLog bootTimingsTraceLog) {
Bill Yi9a76e9b2014-04-29 18:52:48 -0700129 Log.d(TAG, "begin preload");
Neil Fullera84056a2018-07-11 13:59:45 +0100130 bootTimingsTraceLog.traceBegin("BeginPreload");
131 beginPreload();
132 bootTimingsTraceLog.traceEnd(); // BeginPreload
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800133 bootTimingsTraceLog.traceBegin("PreloadClasses");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900134 preloadClasses();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800135 bootTimingsTraceLog.traceEnd(); // PreloadClasses
136 bootTimingsTraceLog.traceBegin("PreloadResources");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900137 preloadResources();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800138 bootTimingsTraceLog.traceEnd(); // PreloadResources
Jesse Hall1fe1dc02017-07-06 15:30:39 -0700139 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs");
140 nativePreloadAppProcessHALs();
141 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Jesse Hallba0370e2017-02-09 14:43:14 -0800142 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadOpenGL");
143 preloadOpenGL();
144 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Brian Carlstrom6c9af962014-09-11 15:36:00 -0700145 preloadSharedLibraries();
Raph Levienc3dd1c12015-04-06 10:37:57 -0700146 preloadTextResources();
Torne (Richard Coles)08cfaf62014-05-08 16:07:05 +0100147 // Ask the WebViewFactory to do any initialization that must run in the zygote process,
148 // for memory sharing purposes.
149 WebViewFactory.prepareWebViewInZygote();
Neil Fullera84056a2018-07-11 13:59:45 +0100150 endPreload();
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100151 warmUpJcaProviders();
Bill Yi9a76e9b2014-04-29 18:52:48 -0700152 Log.d(TAG, "end preload");
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000153
154 sPreloadComplete = true;
155 }
156
Narayan Kamath669afcc2017-02-06 20:24:08 +0000157 public static void lazyPreload() {
158 Preconditions.checkState(!sPreloadComplete);
159 Log.i(TAG, "Lazily preloading resources.");
160
Fyodor Kupolov6e3461b2017-08-10 17:00:43 -0700161 preload(new TimingsTraceLog("ZygoteInitTiming_lazy", Trace.TRACE_TAG_DALVIK));
Romain Guy74c69122013-05-08 17:54:20 -0700162 }
163
Neil Fullera84056a2018-07-11 13:59:45 +0100164 private static void beginPreload() {
165 Log.i(TAG, "Calling ZygoteHooks.beginPreload()");
Neil Fuller4f41f612016-05-09 16:55:36 +0100166
Neil Fullera84056a2018-07-11 13:59:45 +0100167 ZygoteHooks.onBeginPreload();
Neil Fuller4f41f612016-05-09 16:55:36 +0100168 }
169
Neil Fullera84056a2018-07-11 13:59:45 +0100170 private static void endPreload() {
171 ZygoteHooks.onEndPreload();
Neil Fuller4f41f612016-05-09 16:55:36 +0100172
Neil Fullera84056a2018-07-11 13:59:45 +0100173 Log.i(TAG, "Called ZygoteHooks.endPreload()");
Neil Fuller4f41f612016-05-09 16:55:36 +0100174 }
175
Brian Carlstrom6c9af962014-09-11 15:36:00 -0700176 private static void preloadSharedLibraries() {
177 Log.i(TAG, "Preloading shared libraries...");
178 System.loadLibrary("android");
179 System.loadLibrary("compiler_rt");
180 System.loadLibrary("jnigraphics");
181 }
182
Jesse Hall1fe1dc02017-07-06 15:30:39 -0700183 native private static void nativePreloadAppProcessHALs();
Chris Wailescd92db22019-01-11 14:30:43 -0800184
Peter Collingbourne6f4986b2018-10-26 14:52:14 -0700185 native private static void nativePreloadOpenGL();
Jesse Hall1fe1dc02017-07-06 15:30:39 -0700186
Jesse Hallba0370e2017-02-09 14:43:14 -0800187 private static void preloadOpenGL() {
188 String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
Jesse Hall5d911fe2017-04-13 15:44:24 -0700189 if (!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING, false) &&
190 (driverPackageName == null || driverPackageName.isEmpty())) {
Peter Collingbourne6f4986b2018-10-26 14:52:14 -0700191 nativePreloadOpenGL();
Jesse Hallba0370e2017-02-09 14:43:14 -0800192 }
193 }
194
Raph Levienc3dd1c12015-04-06 10:37:57 -0700195 private static void preloadTextResources() {
196 Hyphenator.init();
Andreas Gampeddc13972016-02-26 16:54:59 -0800197 TextView.preloadFontCache();
Raph Levienc3dd1c12015-04-06 10:37:57 -0700198 }
199
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800200 /**
Sergio Giro69de3202016-05-17 16:52:33 +0100201 * Register AndroidKeyStoreProvider and warm up the providers that are already registered.
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100202 *
Chris Wailescd92db22019-01-11 14:30:43 -0800203 * By doing it here we avoid that each app does it when requesting a service from the provider
204 * for the first time.
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100205 */
206 private static void warmUpJcaProviders() {
207 long startTime = SystemClock.uptimeMillis();
208 Trace.traceBegin(
Sergio Giro69de3202016-05-17 16:52:33 +0100209 Trace.TRACE_TAG_DALVIK, "Starting installation of AndroidKeyStoreProvider");
210 // AndroidKeyStoreProvider.install() manipulates the list of JCA providers to insert
211 // preferred providers. Note this is not done via security.properties as the JCA providers
212 // are not on the classpath in the case of, for example, raw dalvikvm runtimes.
213 AndroidKeyStoreProvider.install();
214 Log.i(TAG, "Installed AndroidKeyStoreProvider in "
215 + (SystemClock.uptimeMillis() - startTime) + "ms.");
216 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
217
218 startTime = SystemClock.uptimeMillis();
219 Trace.traceBegin(
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100220 Trace.TRACE_TAG_DALVIK, "Starting warm up of JCA providers");
221 for (Provider p : Security.getProviders()) {
222 p.warmUpServiceProvision();
223 }
224 Log.i(TAG, "Warmed up JCA providers in "
Sergio Giro69de3202016-05-17 16:52:33 +0100225 + (SystemClock.uptimeMillis() - startTime) + "ms.");
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100226 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
227 }
228
229 /**
Chris Wailescd92db22019-01-11 14:30:43 -0800230 * Performs Zygote process initialization. Loads and initializes commonly used classes.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800231 *
Chris Wailescd92db22019-01-11 14:30:43 -0800232 * Most classes only cause a few hundred bytes to be allocated, but a few will allocate a dozen
233 * Kbytes (in one case, 500+K).
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800234 */
235 private static void preloadClasses() {
236 final VMRuntime runtime = VMRuntime.getRuntime();
Bob Leee5408332009-09-04 18:31:17 -0700237
Ying Wangd0c45352014-11-13 15:22:47 -0800238 InputStream is;
239 try {
240 is = new FileInputStream(PRELOADED_CLASSES);
241 } catch (FileNotFoundException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800242 Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + ".");
Ying Wangd0c45352014-11-13 15:22:47 -0800243 return;
244 }
Bob Leee5408332009-09-04 18:31:17 -0700245
Ying Wangd0c45352014-11-13 15:22:47 -0800246 Log.i(TAG, "Preloading classes...");
247 long startTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800248
Ying Wangd0c45352014-11-13 15:22:47 -0800249 // Drop root perms while running static initializers.
Narayan Kamath23e68782015-01-16 17:22:41 +0000250 final int reuid = Os.getuid();
251 final int regid = Os.getgid();
252
253 // We need to drop root perms only if we're already root. In the case of "wrapped"
254 // processes (see WrapperInit), this function is called from an unprivileged uid
255 // and gid.
256 boolean droppedPriviliges = false;
257 if (reuid == ROOT_UID && regid == ROOT_GID) {
258 try {
259 Os.setregid(ROOT_GID, UNPRIVILEGED_GID);
260 Os.setreuid(ROOT_UID, UNPRIVILEGED_UID);
261 } catch (ErrnoException ex) {
262 throw new RuntimeException("Failed to drop root", ex);
263 }
264
265 droppedPriviliges = true;
Elliott Hughes26b56e62014-12-17 12:28:29 -0800266 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800267
Ying Wangd0c45352014-11-13 15:22:47 -0800268 // Alter the target heap utilization. With explicit GCs this
269 // is not likely to have any effect.
270 float defaultUtilization = runtime.getTargetHeapUtilization();
271 runtime.setTargetHeapUtilization(0.8f);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800272
Ying Wangd0c45352014-11-13 15:22:47 -0800273 try {
Chris Wailescd92db22019-01-11 14:30:43 -0800274 BufferedReader br =
Chris Wailescffbf1c2019-01-11 17:13:00 -0800275 new BufferedReader(new InputStreamReader(is), Zygote.SOCKET_BUFFER_SIZE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800276
Ying Wangd0c45352014-11-13 15:22:47 -0800277 int count = 0;
278 String line;
279 while ((line = br.readLine()) != null) {
280 // Skip comments and blank lines.
281 line = line.trim();
282 if (line.startsWith("#") || line.equals("")) {
283 continue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800284 }
285
Andreas Gampec4253622016-10-28 18:19:30 -0700286 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, line);
Ying Wangd0c45352014-11-13 15:22:47 -0800287 try {
288 if (false) {
289 Log.v(TAG, "Preloading " + line + "...");
290 }
Andreas Gampedd8e5fb2015-04-21 09:01:51 -0700291 // Load and explicitly initialize the given class. Use
292 // Class.forName(String, boolean, ClassLoader) to avoid repeated stack lookups
293 // (to derive the caller's class-loader). Use true to force initialization, and
294 // null for the boot classpath class-loader (could as well cache the
295 // class-loader of this class in a variable).
Andreas Gampec917f742015-04-20 19:16:37 -0700296 Class.forName(line, true, null);
Ying Wangd0c45352014-11-13 15:22:47 -0800297 count++;
298 } catch (ClassNotFoundException e) {
299 Log.w(TAG, "Class not found for preloading: " + line);
300 } catch (UnsatisfiedLinkError e) {
301 Log.w(TAG, "Problem preloading " + line + ": " + e);
302 } catch (Throwable t) {
303 Log.e(TAG, "Error preloading " + line + ".", t);
304 if (t instanceof Error) {
305 throw (Error) t;
306 }
307 if (t instanceof RuntimeException) {
308 throw (RuntimeException) t;
309 }
310 throw new RuntimeException(t);
311 }
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900312 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313 }
Ying Wangd0c45352014-11-13 15:22:47 -0800314
315 Log.i(TAG, "...preloaded " + count + " classes in "
Chris Wailescd92db22019-01-11 14:30:43 -0800316 + (SystemClock.uptimeMillis() - startTime) + "ms.");
Ying Wangd0c45352014-11-13 15:22:47 -0800317 } catch (IOException e) {
318 Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);
319 } finally {
320 IoUtils.closeQuietly(is);
321 // Restore default.
322 runtime.setTargetHeapUtilization(defaultUtilization);
323
324 // Fill in dex caches with classes, fields, and methods brought in by preloading.
Yasuhiro Matsuda1ab43d52015-06-30 17:07:32 +0900325 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadDexCaches");
Ying Wangd0c45352014-11-13 15:22:47 -0800326 runtime.preloadDexCaches();
Yasuhiro Matsuda1ab43d52015-06-30 17:07:32 +0900327 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Ying Wangd0c45352014-11-13 15:22:47 -0800328
Narayan Kamath23e68782015-01-16 17:22:41 +0000329 // Bring back root. We'll need it later if we're in the zygote.
330 if (droppedPriviliges) {
331 try {
332 Os.setreuid(ROOT_UID, ROOT_UID);
333 Os.setregid(ROOT_GID, ROOT_GID);
334 } catch (ErrnoException ex) {
335 throw new RuntimeException("Failed to restore root", ex);
336 }
Elliott Hughes26b56e62014-12-17 12:28:29 -0800337 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800338 }
339 }
340
341 /**
Chris Wailescd92db22019-01-11 14:30:43 -0800342 * Load in commonly used resources, so they can be shared across processes.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800343 *
Chris Wailescd92db22019-01-11 14:30:43 -0800344 * These tend to be a few Kbytes, but are frequently in the 20-40K range, and occasionally even
345 * larger.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800346 */
347 private static void preloadResources() {
348 final VMRuntime runtime = VMRuntime.getRuntime();
Bob Leee5408332009-09-04 18:31:17 -0700349
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800350 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800351 mResources = Resources.getSystem();
352 mResources.startPreloading();
353 if (PRELOAD_RESOURCES) {
354 Log.i(TAG, "Preloading resources...");
355
356 long startTime = SystemClock.uptimeMillis();
357 TypedArray ar = mResources.obtainTypedArray(
358 com.android.internal.R.array.preloaded_drawables);
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800359 int N = preloadDrawables(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 "
Chris Wailescd92db22019-01-11 14:30:43 -0800362 + (SystemClock.uptimeMillis() - startTime) + "ms.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800363
364 startTime = SystemClock.uptimeMillis();
365 ar = mResources.obtainTypedArray(
366 com.android.internal.R.array.preloaded_color_state_lists);
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800367 N = preloadColorStateLists(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 "
Chris Wailescd92db22019-01-11 14:30:43 -0800370 + (SystemClock.uptimeMillis() - startTime) + "ms.");
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800371
372 if (mResources.getBoolean(
373 com.android.internal.R.bool.config_freeformWindowManagement)) {
374 startTime = SystemClock.uptimeMillis();
375 ar = mResources.obtainTypedArray(
376 com.android.internal.R.array.preloaded_freeform_multi_window_drawables);
377 N = preloadDrawables(ar);
378 ar.recycle();
379 Log.i(TAG, "...preloaded " + N + " resource in "
380 + (SystemClock.uptimeMillis() - startTime) + "ms.");
381 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382 }
383 mResources.finishPreloading();
384 } catch (RuntimeException e) {
385 Log.w(TAG, "Failure preloading resources", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800386 }
387 }
388
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800389 private static int preloadColorStateLists(TypedArray ar) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800390 int N = ar.length();
Chris Wailescd92db22019-01-11 14:30:43 -0800391 for (int i = 0; i < N; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800392 int id = ar.getResourceId(i, 0);
Joe Onorato43a17652011-04-06 19:22:23 -0700393 if (false) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800394 Log.v(TAG, "Preloading resource #" + Integer.toHexString(id));
395 }
396 if (id != 0) {
Alan Viverette77bb6f12015-02-11 17:24:33 -0800397 if (mResources.getColorStateList(id, null) == null) {
Dianne Hackborndde331c2012-08-03 14:01:57 -0700398 throw new IllegalArgumentException(
399 "Unable to find preloaded color resource #0x"
Chris Wailescd92db22019-01-11 14:30:43 -0800400 + Integer.toHexString(id)
401 + " (" + ar.getString(i) + ")");
Dianne Hackborndde331c2012-08-03 14:01:57 -0700402 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800403 }
404 }
405 return N;
406 }
407
408
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800409 private static int preloadDrawables(TypedArray ar) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800410 int N = ar.length();
Chris Wailescd92db22019-01-11 14:30:43 -0800411 for (int i = 0; i < N; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800412 int id = ar.getResourceId(i, 0);
Joe Onorato43a17652011-04-06 19:22:23 -0700413 if (false) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800414 Log.v(TAG, "Preloading resource #" + Integer.toHexString(id));
415 }
416 if (id != 0) {
Alan Viverette84e001a2014-09-22 00:04:22 -0700417 if (mResources.getDrawable(id, null) == null) {
Dianne Hackborndde331c2012-08-03 14:01:57 -0700418 throw new IllegalArgumentException(
419 "Unable to find preloaded drawable resource #0x"
Chris Wailescd92db22019-01-11 14:30:43 -0800420 + Integer.toHexString(id)
421 + " (" + ar.getString(i) + ")");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800422 }
423 }
424 }
425 return N;
426 }
427
428 /**
Chris Wailescd92db22019-01-11 14:30:43 -0800429 * Runs several special GCs to try to clean up a few generations of softly- and final-reachable
430 * objects, along with any other garbage. This is only useful just before a fork().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800431 */
Neil Fullera84056a2018-07-11 13:59:45 +0100432 private static void gcAndFinalize() {
433 ZygoteHooks.gcAndFinalize();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800434 }
435
436 /**
437 * Finish remaining work for the newly forked system server process.
438 */
Chris Wailes682b4792019-01-11 16:14:43 -0800439 private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
Mike Lockwood90960e82010-08-06 09:15:25 -0400440 // set umask to 0077 so new files and directories will default to owner-only permissions.
Elliott Hughes860c5912014-04-28 19:19:13 -0700441 Os.umask(S_IRWXG | S_IRWXO);
Mike Lockwood90960e82010-08-06 09:15:25 -0400442
Chris Wailes682b4792019-01-11 16:14:43 -0800443 if (parsedArgs.mNiceName != null) {
444 Process.setArgV0(parsedArgs.mNiceName);
Jeff Brownebed7d62011-05-16 17:08:42 -0700445 }
446
Narayan Kamath29564cd2014-08-07 10:57:40 +0100447 final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
448 if (systemServerClasspath != null) {
449 performSystemServerDexOpt(systemServerClasspath);
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -0700450 // Capturing profiles is only supported for debug or eng builds since selinux normally
451 // prevents it.
452 boolean profileSystemServer = SystemProperties.getBoolean(
453 "dalvik.vm.profilesystemserver", false);
454 if (profileSystemServer && (Build.IS_USERDEBUG || Build.IS_ENG)) {
455 try {
Calin Juravle3f3a08a2018-05-02 23:39:19 -0700456 prepareSystemServerProfile(systemServerClasspath);
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -0700457 } catch (Exception e) {
458 Log.wtf(TAG, "Failed to set up system server profile", e);
459 }
460 }
Narayan Kamath29564cd2014-08-07 10:57:40 +0100461 }
462
Chris Wailes682b4792019-01-11 16:14:43 -0800463 if (parsedArgs.mInvokeWith != null) {
464 String[] args = parsedArgs.mRemainingArgs;
Narayan Kamath29564cd2014-08-07 10:57:40 +0100465 // If we have a non-null system server class path, we'll have to duplicate the
466 // existing arguments and append the classpath to it. ART will handle the classpath
467 // correctly when we exec a new process.
468 if (systemServerClasspath != null) {
469 String[] amendedArgs = new String[args.length + 2];
470 amendedArgs[0] = "-cp";
471 amendedArgs[1] = systemServerClasspath;
tony.ys_liu34738172016-12-14 18:50:29 +0800472 System.arraycopy(args, 0, amendedArgs, 2, args.length);
473 args = amendedArgs;
Narayan Kamath29564cd2014-08-07 10:57:40 +0100474 }
475
Chris Wailes682b4792019-01-11 16:14:43 -0800476 WrapperInit.execApplication(parsedArgs.mInvokeWith,
477 parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
Narayan Kamath37ad4b02015-01-19 16:05:24 +0000478 VMRuntime.getCurrentInstructionSet(), null, args);
Narayan Kamathbf99d062017-07-05 14:45:38 +0100479
480 throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
Jeff Brownebed7d62011-05-16 17:08:42 -0700481 } else {
Narayan Kamath29564cd2014-08-07 10:57:40 +0100482 ClassLoader cl = null;
483 if (systemServerClasspath != null) {
Chris Wailes682b4792019-01-11 16:14:43 -0800484 cl = createPathClassLoader(systemServerClasspath, parsedArgs.mTargetSdkVersion);
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700485
Narayan Kamath29564cd2014-08-07 10:57:40 +0100486 Thread.currentThread().setContextClassLoader(cl);
487 }
488
Jeff Brownebed7d62011-05-16 17:08:42 -0700489 /*
490 * Pass the remaining arguments to SystemServer.
491 */
Chris Wailes682b4792019-01-11 16:14:43 -0800492 return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
493 parsedArgs.mRemainingArgs, cl);
Jeff Brownebed7d62011-05-16 17:08:42 -0700494 }
495
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800496 /* should never reach here */
497 }
498
Calin Juravle3f3a08a2018-05-02 23:39:19 -0700499 /**
Chris Wailescd92db22019-01-11 14:30:43 -0800500 * Note that preparing the profiles for system server does not require special selinux
501 * permissions. From the installer perspective the system server is a regular package which can
502 * capture profile information.
Calin Juravle3f3a08a2018-05-02 23:39:19 -0700503 */
504 private static void prepareSystemServerProfile(String systemServerClasspath)
505 throws RemoteException {
506 if (systemServerClasspath.isEmpty()) {
507 return;
508 }
509 String[] codePaths = systemServerClasspath.split(":");
510
511 final IInstalld installd = IInstalld.Stub
512 .asInterface(ServiceManager.getService("installd"));
513
514 String systemServerPackageName = "android";
515 String systemServerProfileName = "primary.prof";
516 installd.prepareAppProfile(
517 systemServerPackageName,
518 UserHandle.USER_SYSTEM,
519 UserHandle.getAppId(Process.SYSTEM_UID),
520 systemServerProfileName,
521 codePaths[0],
522 /*dexMetadata*/ null);
523
524 File profileDir = Environment.getDataProfilesDePackageDirectory(
525 UserHandle.USER_SYSTEM, systemServerPackageName);
526 String profilePath = new File(profileDir, systemServerProfileName).getAbsolutePath();
527 VMRuntime.registerAppInfo(profilePath, codePaths);
528 }
529
Mathew Inwood8faeab82018-03-16 14:26:08 +0000530 public static void setApiBlacklistExemptions(String[] exemptions) {
531 VMRuntime.getRuntime().setHiddenApiExemptions(exemptions);
532 }
533
Mathew Inwood04194fe2018-04-04 14:48:03 +0100534 public static void setHiddenApiAccessLogSampleRate(int percent) {
535 VMRuntime.getRuntime().setHiddenApiAccessLogSamplingRate(percent);
536 }
537
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800538 /**
Andrei Onea89acbab2019-01-25 16:29:44 +0000539 * Sets the implementation to be used for logging hidden API accesses
540 * @param logger the implementation of the VMRuntime.HiddenApiUsageLogger interface
541 */
542 public static void setHiddenApiUsageLogger(VMRuntime.HiddenApiUsageLogger logger) {
543 VMRuntime.getRuntime().setHiddenApiUsageLogger(logger);
544 }
545
546 /**
tony.ys_liu34738172016-12-14 18:50:29 +0800547 * Creates a PathClassLoader for the given class path that is associated with a shared
548 * namespace, i.e., this classloader can access platform-private native libraries. The
549 * classloader will use java.library.path as the native library path.
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700550 */
Narayan Kamathf9419f02017-06-15 11:35:38 +0100551 static ClassLoader createPathClassLoader(String classPath, int targetSdkVersion) {
552 String libraryPath = System.getProperty("java.library.path");
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700553
Nicolas Geoffray5d1814e2018-12-13 09:27:04 +0000554 // We use the boot class loader, that's what the runtime expects at AOT.
555 ClassLoader parent = ClassLoader.getSystemClassLoader().getParent();
556
Narayan Kamathf9419f02017-06-15 11:35:38 +0100557 return ClassLoaderFactory.createClassLoader(classPath, libraryPath, libraryPath,
Nicolas Geoffray5d1814e2018-12-13 09:27:04 +0000558 parent, targetSdkVersion, true /* isNamespaceShared */, null /* classLoaderName */);
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700559 }
560
561 /**
Chris Wailescd92db22019-01-11 14:30:43 -0800562 * Performs dex-opt on the elements of {@code classPath}, if needed. We choose the instruction
563 * set of the current runtime.
Narayan Kamath29564cd2014-08-07 10:57:40 +0100564 */
565 private static void performSystemServerDexOpt(String classPath) {
566 final String[] classPathElements = classPath.split(":");
Jeff Sharkey740f5232016-12-09 14:31:26 -0700567 final IInstalld installd = IInstalld.Stub
568 .asInterface(ServiceManager.getService("installd"));
Narayan Kamath29564cd2014-08-07 10:57:40 +0100569 final String instructionSet = VMRuntime.getRuntime().vmInstructionSet();
570
Calin Juravle2f09ff32017-07-24 15:29:56 -0700571 String classPathForElement = "";
Jeff Sharkey740f5232016-12-09 14:31:26 -0700572 for (String classPathElement : classPathElements) {
573 // System server is fully AOTed and never profiled
574 // for profile guided compilation.
Mathieu Chartier5e07a0d2017-06-15 19:09:38 -0700575 String systemServerFilter = SystemProperties.get(
576 "dalvik.vm.systemservercompilerfilter", "speed");
Andreas Gampee7bc1522016-08-09 20:44:04 -0700577
Jeff Sharkey740f5232016-12-09 14:31:26 -0700578 int dexoptNeeded;
579 try {
580 dexoptNeeded = DexFile.getDexOptNeeded(
Chris Wailescd92db22019-01-11 14:30:43 -0800581 classPathElement, instructionSet, systemServerFilter,
582 null /* classLoaderContext */, false /* newProfile */,
583 false /* downgrade */);
Jeff Sharkey740f5232016-12-09 14:31:26 -0700584 } catch (FileNotFoundException ignored) {
585 // Do not add to the classpath.
586 Log.w(TAG, "Missing classpath element for system server: " + classPathElement);
587 continue;
588 } catch (IOException e) {
589 // Not fully clear what to do here as we don't know the cause of the
590 // IO exception. Add to the classpath to be conservative, but don't
591 // attempt to compile it.
592 Log.w(TAG, "Error checking classpath element for system server: "
593 + classPathElement, e);
594 dexoptNeeded = DexFile.NO_DEXOPT_NEEDED;
Narayan Kamath29564cd2014-08-07 10:57:40 +0100595 }
Jeff Sharkey740f5232016-12-09 14:31:26 -0700596
597 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
598 final String packageName = "*";
599 final String outputPath = null;
David Brazdilf7e31c02018-02-13 17:04:26 +0000600 final int dexFlags = 0;
Mathieu Chartier5e07a0d2017-06-15 19:09:38 -0700601 final String compilerFilter = systemServerFilter;
Jeff Sharkey740f5232016-12-09 14:31:26 -0700602 final String uuid = StorageManager.UUID_PRIVATE_INTERNAL;
Calin Juravle811a75a2017-04-05 22:49:38 -0700603 final String seInfo = null;
Calin Juravle2f09ff32017-07-24 15:29:56 -0700604 final String classLoaderContext =
605 getSystemServerClassLoaderContext(classPathForElement);
David Brazdil3d44ed02018-01-16 20:01:47 +0000606 final int targetSdkVersion = 0; // SystemServer targets the system's SDK version
Jeff Sharkey740f5232016-12-09 14:31:26 -0700607 try {
608 installd.dexopt(classPathElement, Process.SYSTEM_UID, packageName,
609 instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter,
David Brazdil3d44ed02018-01-16 20:01:47 +0000610 uuid, classLoaderContext, seInfo, false /* downgrade */,
Calin Juravle4bc8f4d2018-02-12 12:00:44 -0800611 targetSdkVersion, /*profileName*/ null, /*dexMetadataPath*/ null,
612 "server-dexopt");
Jeff Sharkey740f5232016-12-09 14:31:26 -0700613 } catch (RemoteException | ServiceSpecificException e) {
614 // Ignore (but log), we need this on the classpath for fallback mode.
615 Log.w(TAG, "Failed compiling classpath element for system server: "
616 + classPathElement, e);
617 }
618 }
619
Calin Juravle2f09ff32017-07-24 15:29:56 -0700620 classPathForElement = encodeSystemServerClassPath(
621 classPathForElement, classPathElement);
Narayan Kamath29564cd2014-08-07 10:57:40 +0100622 }
623 }
624
625 /**
Chris Wailescd92db22019-01-11 14:30:43 -0800626 * Encodes the system server class loader context in a format that is accepted by dexopt. This
627 * assumes the system server is always loaded with a {@link dalvik.system.PathClassLoader}.
Calin Juravle2f09ff32017-07-24 15:29:56 -0700628 *
629 * Note that ideally we would use the {@code DexoptUtils} to compute this. However we have no
630 * dependency here on the server so we hard code the logic again.
631 */
632 private static String getSystemServerClassLoaderContext(String classPath) {
633 return classPath == null ? "PCL[]" : "PCL[" + classPath + "]";
634 }
635
636 /**
637 * Encodes the class path in a format accepted by dexopt.
Chris Wailescd92db22019-01-11 14:30:43 -0800638 *
639 * @param classPath The old class path (may be empty).
640 * @param newElement The new class path elements
641 * @return The class path encoding resulted from appending {@code newElement} to {@code
642 * classPath}.
Calin Juravle2f09ff32017-07-24 15:29:56 -0700643 */
644 private static String encodeSystemServerClassPath(String classPath, String newElement) {
645 return (classPath == null || classPath.isEmpty())
646 ? newElement
647 : classPath + ":" + newElement;
648 }
649
650 /**
Narayan Kamathbf99d062017-07-05 14:45:38 +0100651 * Prepare the arguments and forks for the system server process.
652 *
Chris Wailescd92db22019-01-11 14:30:43 -0800653 * @return A {@code Runnable} that provides an entrypoint into system_server code in the child
654 * process; {@code null} in the parent.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800655 */
Narayan Kamathbf99d062017-07-05 14:45:38 +0100656 private static Runnable forkSystemServer(String abiList, String socketName,
657 ZygoteServer zygoteServer) {
Alex Klyubin48a06e72013-04-19 10:01:42 -0700658 long capabilities = posixCapabilitiesAsBits(
Chris Wailescd92db22019-01-11 14:30:43 -0800659 OsConstants.CAP_IPC_LOCK,
660 OsConstants.CAP_KILL,
661 OsConstants.CAP_NET_ADMIN,
662 OsConstants.CAP_NET_BIND_SERVICE,
663 OsConstants.CAP_NET_BROADCAST,
664 OsConstants.CAP_NET_RAW,
665 OsConstants.CAP_SYS_MODULE,
666 OsConstants.CAP_SYS_NICE,
667 OsConstants.CAP_SYS_PTRACE,
668 OsConstants.CAP_SYS_TIME,
669 OsConstants.CAP_SYS_TTY_CONFIG,
670 OsConstants.CAP_WAKE_ALARM,
671 OsConstants.CAP_BLOCK_SUSPEND
Alex Klyubin48a06e72013-04-19 10:01:42 -0700672 );
Luis Hector Chavez72042c92017-07-12 10:03:30 -0700673 /* Containers run without some capabilities, so drop any caps that are not available. */
674 StructCapUserHeader header = new StructCapUserHeader(
675 OsConstants._LINUX_CAPABILITY_VERSION_3, 0);
676 StructCapUserData[] data;
677 try {
678 data = Os.capget(header);
679 } catch (ErrnoException ex) {
680 throw new RuntimeException("Failed to capget()", ex);
Luis Hector Chavez5dd239a2015-10-06 14:01:45 -0700681 }
Luis Hector Chavez72042c92017-07-12 10:03:30 -0700682 capabilities &= ((long) data[0].effective) | (((long) data[1].effective) << 32);
683
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800684 /* Hardcoded command line to start the system server */
685 String args[] = {
Chris Wailescd92db22019-01-11 14:30:43 -0800686 "--setuid=1000",
687 "--setgid=1000",
688 "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,"
689 + "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010",
690 "--capabilities=" + capabilities + "," + capabilities,
691 "--nice-name=system_server",
692 "--runtime-args",
693 "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
694 "com.android.server.SystemServer",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800695 };
Chris Wailes682b4792019-01-11 16:14:43 -0800696 ZygoteArguments parsedArgs = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800697
698 int pid;
699
700 try {
Chris Wailes682b4792019-01-11 16:14:43 -0800701 parsedArgs = new ZygoteArguments(args);
702 Zygote.applyDebuggerSystemProperty(parsedArgs);
703 Zygote.applyInvokeWithSystemProperty(parsedArgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800704
Calin Juravle8eb891b2018-05-03 19:51:18 -0700705 boolean profileSystemServer = SystemProperties.getBoolean(
706 "dalvik.vm.profilesystemserver", false);
707 if (profileSystemServer) {
Chris Wailes682b4792019-01-11 16:14:43 -0800708 parsedArgs.mRuntimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
Calin Juravle8eb891b2018-05-03 19:51:18 -0700709 }
710
Mathieu Chartierf5cd8c12019-02-04 13:28:36 -0800711 String use_app_image_cache = SystemProperties.get(
712 PROPERTY_USE_APP_IMAGE_STARTUP_CACHE, "");
713 // Property defaults to true currently.
714 if (!TextUtils.isEmpty(use_app_image_cache) && !use_app_image_cache.equals("false")) {
715 parsedArgs.mRuntimeFlags |= Zygote.USE_APP_IMAGE_STARTUP_CACHE;
716 }
717
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800718 /* Request to fork the system server process */
719 pid = Zygote.forkSystemServer(
Chris Wailes682b4792019-01-11 16:14:43 -0800720 parsedArgs.mUid, parsedArgs.mGid,
721 parsedArgs.mGids,
722 parsedArgs.mRuntimeFlags,
Elliott Hughese1dfcb72011-07-08 11:08:07 -0700723 null,
Chris Wailes682b4792019-01-11 16:14:43 -0800724 parsedArgs.mPermittedCapabilities,
725 parsedArgs.mEffectiveCapabilities);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800726 } catch (IllegalArgumentException ex) {
727 throw new RuntimeException(ex);
Bob Leee5408332009-09-04 18:31:17 -0700728 }
729
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800730 /* For child process */
731 if (pid == 0) {
Narayan Kamath64cd9072014-05-13 13:35:14 +0100732 if (hasSecondZygote(abiList)) {
733 waitForSecondaryZygote(socketName);
734 }
735
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000736 zygoteServer.closeServerSocket();
Narayan Kamathbf99d062017-07-05 14:45:38 +0100737 return handleSystemServerProcess(parsedArgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800738 }
739
Narayan Kamathbf99d062017-07-05 14:45:38 +0100740 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800741 }
742
Alex Klyubin48a06e72013-04-19 10:01:42 -0700743 /**
744 * Gets the bit array representation of the provided list of POSIX capabilities.
745 */
746 private static long posixCapabilitiesAsBits(int... capabilities) {
747 long result = 0;
748 for (int capability : capabilities) {
749 if ((capability < 0) || (capability > OsConstants.CAP_LAST_CAP)) {
750 throw new IllegalArgumentException(String.valueOf(capability));
751 }
752 result |= (1L << capability);
753 }
754 return result;
755 }
756
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800757 public static void main(String argv[]) {
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000758 ZygoteServer zygoteServer = new ZygoteServer();
759
Andreas Gampe1ef8aef2016-04-11 08:39:52 -0700760 // Mark zygote start. This ensures that thread creation will throw
761 // an error.
762 ZygoteHooks.startZygoteNoThreadCreation();
763
Robert Seseke4f8d692016-09-13 19:13:01 -0400764 // Zygote goes into its own process group.
765 try {
766 Os.setpgid(0, 0);
767 } catch (ErrnoException ex) {
768 throw new RuntimeException("Failed to setpgid(0,0)", ex);
769 }
770
Chris Wailescffbf1c2019-01-11 17:13:00 -0800771 Runnable caller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800772 try {
Fyodor Kupolov6733e6c2017-01-06 18:27:05 -0800773 // Report Zygote start time to tron unless it is a runtime restart
774 if (!"1".equals(SystemProperties.get("sys.boot_completed"))) {
775 MetricsLogger.histogram(null, "boot_zygote_init",
776 (int) SystemClock.elapsedRealtime());
777 }
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800778
779 String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
Fyodor Kupolov6e3461b2017-08-10 17:00:43 -0700780 TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag,
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800781 Trace.TRACE_TAG_DALVIK);
782 bootTimingsTraceLog.traceBegin("ZygoteInit");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900783 RuntimeInit.enableDdms();
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900784
Narayan Kamathc41638c2014-04-07 13:56:15 +0100785 boolean startSystemServer = false;
786 String socketName = "zygote";
787 String abiList = null;
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000788 boolean enableLazyPreload = false;
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900789 for (int i = 1; i < argv.length; i++) {
790 if ("start-system-server".equals(argv[i])) {
791 startSystemServer = true;
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000792 } else if ("--enable-lazy-preload".equals(argv[i])) {
793 enableLazyPreload = true;
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900794 } else if (argv[i].startsWith(ABI_LIST_ARG)) {
795 abiList = argv[i].substring(ABI_LIST_ARG.length());
796 } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
797 socketName = argv[i].substring(SOCKET_NAME_ARG.length());
798 } else {
799 throw new RuntimeException("Unknown command line argument: " + argv[i]);
Narayan Kamathc41638c2014-04-07 13:56:15 +0100800 }
801 }
802
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900803 if (abiList == null) {
804 throw new RuntimeException("No ABI list supplied.");
805 }
806
Chris Wailescffbf1c2019-01-11 17:13:00 -0800807 // TODO (chriswailes): Wrap these three calls in a helper function?
808 final String blastulaSocketName =
809 socketName.equals(ZygoteProcess.ZYGOTE_SOCKET_NAME)
810 ? ZygoteProcess.BLASTULA_POOL_SOCKET_NAME
811 : ZygoteProcess.BLASTULA_POOL_SECONDARY_SOCKET_NAME;
812
813 zygoteServer.createZygoteSocket(socketName);
814 Zygote.createBlastulaSocket(blastulaSocketName);
815
816 Zygote.getSocketFDs(socketName.equals(ZygoteProcess.ZYGOTE_SOCKET_NAME));
817
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000818 // In some configurations, we avoid preloading resources and classes eagerly.
819 // In such cases, we will preload things prior to our first fork.
820 if (!enableLazyPreload) {
821 bootTimingsTraceLog.traceBegin("ZygotePreload");
822 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
Chris Wailescd92db22019-01-11 14:30:43 -0800823 SystemClock.uptimeMillis());
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000824 preload(bootTimingsTraceLog);
825 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
Chris Wailescd92db22019-01-11 14:30:43 -0800826 SystemClock.uptimeMillis());
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000827 bootTimingsTraceLog.traceEnd(); // ZygotePreload
Narayan Kamathb49996d2017-02-06 20:24:08 +0000828 } else {
Hiroshi Yamauchi1e3db872017-03-02 13:39:07 -0800829 Zygote.resetNicePriority();
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000830 }
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900831
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900832 // Do an initial gc to clean up after startup
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800833 bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900834 gcAndFinalize();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800835 bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900836
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800837 bootTimingsTraceLog.traceEnd(); // ZygoteInit
Jamie Gennis6ad04522013-04-15 18:53:24 -0700838 // Disable tracing so that forked processes do not inherit stale tracing tags from
839 // Zygote.
John Reck62cc1192017-05-12 15:39:51 -0700840 Trace.setTracingEnabled(false, 0);
Jamie Gennis6ad04522013-04-15 18:53:24 -0700841
Victor Hsiehc8176ef2018-01-08 12:43:00 -0800842 Zygote.nativeSecurityInit();
843
doheon1.lee885b7422016-01-20 13:07:27 +0900844 // Zygote process unmounts root storage spaces.
845 Zygote.nativeUnmountStorageOnInit();
846
Andreas Gampe1ef8aef2016-04-11 08:39:52 -0700847 ZygoteHooks.stopZygoteNoThreadCreation();
848
Narayan Kamathc41638c2014-04-07 13:56:15 +0100849 if (startSystemServer) {
Narayan Kamathbf99d062017-07-05 14:45:38 +0100850 Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
851
852 // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
853 // child (system_server) process.
854 if (r != null) {
855 r.run();
856 return;
857 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800858 }
859
Chris Wailescffbf1c2019-01-11 17:13:00 -0800860 // If the return value is null then this is the zygote process
861 // returning to the normal control flow. If it returns a Runnable
862 // object then this is a blastula that has finished specializing.
863 caller = Zygote.initBlastulaPool();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800864
Chris Wailescffbf1c2019-01-11 17:13:00 -0800865 if (caller == null) {
866 Log.i(TAG, "Accepting command socket connections");
867
868 // The select loop returns early in the child process after a fork and
869 // loops forever in the zygote.
870 caller = zygoteServer.runSelectLoop(abiList);
871 }
Christopher Ferrisea8b5de2016-06-17 15:29:58 -0700872 } catch (Throwable ex) {
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000873 Log.e(TAG, "System zygote died with exception", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800874 throw ex;
Narayan Kamathbf99d062017-07-05 14:45:38 +0100875 } finally {
876 zygoteServer.closeServerSocket();
877 }
878
879 // We're in the child process and have exited the select loop. Proceed to execute the
880 // command.
881 if (caller != null) {
882 caller.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800883 }
884 }
885
886 /**
Narayan Kamath64cd9072014-05-13 13:35:14 +0100887 * Return {@code true} if this device configuration has another zygote.
888 *
Chris Wailescd92db22019-01-11 14:30:43 -0800889 * We determine this by comparing the device ABI list with this zygotes list. If this zygote
890 * supports all ABIs this device supports, there won't be another zygote.
Narayan Kamath64cd9072014-05-13 13:35:14 +0100891 */
892 private static boolean hasSecondZygote(String abiList) {
893 return !SystemProperties.get("ro.product.cpu.abilist").equals(abiList);
894 }
895
896 private static void waitForSecondaryZygote(String socketName) {
Chris Wailes6e3c7ce2019-01-11 13:19:20 -0800897 String otherZygoteName = ZygoteProcess.ZYGOTE_SOCKET_NAME.equals(socketName)
898 ? ZygoteProcess.ZYGOTE_SECONDARY_SOCKET_NAME : ZygoteProcess.ZYGOTE_SOCKET_NAME;
Gustav Senntonf0c52b52017-04-27 17:00:50 +0100899 ZygoteProcess.waitForConnectionToZygote(otherZygoteName);
Narayan Kamath64cd9072014-05-13 13:35:14 +0100900 }
901
Narayan Kamath669afcc2017-02-06 20:24:08 +0000902 static boolean isPreloadComplete() {
903 return sPreloadComplete;
904 }
905
Narayan Kamath64cd9072014-05-13 13:35:14 +0100906 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800907 * Class not instantiable.
908 */
909 private ZygoteInit() {
910 }
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800911
912 /**
Chris Wailescd92db22019-01-11 14:30:43 -0800913 * The main function called when started through the zygote process. This could be unified with
914 * main(), if the native code in nativeFinishInit() were rationalized with Zygote startup.<p>
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800915 *
916 * Current recognized args:
917 * <ul>
918 * <li> <code> [--] &lt;start class name&gt; &lt;args&gt;
919 * </ul>
920 *
921 * @param targetSdkVersion target SDK version
922 * @param argv arg strings
923 */
Chris Wailescd92db22019-01-11 14:30:43 -0800924 public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
925 ClassLoader classLoader) {
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800926 if (RuntimeInit.DEBUG) {
927 Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
928 }
929
930 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
931 RuntimeInit.redirectLogStreams();
932
933 RuntimeInit.commonInit();
934 ZygoteInit.nativeZygoteInit();
Narayan Kamathbf99d062017-07-05 14:45:38 +0100935 return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800936 }
937
Robert Sesekd0a190df2018-02-12 18:46:01 -0500938 /**
Chris Wailescd92db22019-01-11 14:30:43 -0800939 * The main function called when starting a child zygote process. This is used as an alternative
940 * to zygoteInit(), which skips calling into initialization routines that start the Binder
941 * threadpool.
Robert Sesekd0a190df2018-02-12 18:46:01 -0500942 */
943 static final Runnable childZygoteInit(
944 int targetSdkVersion, String[] argv, ClassLoader classLoader) {
945 RuntimeInit.Arguments args = new RuntimeInit.Arguments(argv);
946 return RuntimeInit.findStaticMain(args.startClass, args.startArgs, classLoader);
947 }
948
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800949 private static final native void nativeZygoteInit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800950}