blob: 5f2371961857d776eb81ebde0fdd1e9d5a5b13df [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.internal.os;
18
Elliott Hughesa9569ff2014-04-28 20:53:52 -070019import static android.system.OsConstants.S_IRWXG;
20import static android.system.OsConstants.S_IRWXO;
Kenny Root4c74f8c2012-08-17 08:45:55 -070021
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022import android.content.res.Resources;
23import android.content.res.TypedArray;
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -070024import android.os.Build;
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -070025import android.os.Environment;
Mathew Inwood04194fe2018-04-04 14:48:03 +010026import android.os.IInstalld;
Jeff Brownebed7d62011-05-16 17:08:42 -070027import android.os.Process;
Jeff Sharkey740f5232016-12-09 14:31:26 -070028import android.os.RemoteException;
29import android.os.ServiceManager;
30import android.os.ServiceSpecificException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import android.os.SystemClock;
Romain Guyc5e36382013-05-09 11:08:17 -070032import android.os.SystemProperties;
Jamie Gennis6ad04522013-04-15 18:53:24 -070033import android.os.Trace;
Calin Juravle3f3a08a2018-05-02 23:39:19 -070034import android.os.UserHandle;
Robert Sesek8f8d1872016-03-18 16:52:57 -040035import android.os.ZygoteProcess;
Jeff Sharkeyc98c7bc2016-12-07 14:57:34 -070036import android.os.storage.StorageManager;
Sergio Giro69de3202016-05-17 16:52:33 +010037import android.security.keystore.AndroidKeyStoreProvider;
Bill Yi9a76e9b2014-04-29 18:52:48 -070038import android.system.ErrnoException;
Elliott Hughes860c5912014-04-28 19:19:13 -070039import android.system.Os;
40import android.system.OsConstants;
Luis Hector Chavez72042c92017-07-12 10:03:30 -070041import android.system.StructCapUserData;
42import android.system.StructCapUserHeader;
Raph Levienc3dd1c12015-04-06 10:37:57 -070043import android.text.Hyphenator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import android.util.EventLog;
45import android.util.Log;
Andreas Gampe76d4fc82017-02-07 19:44:37 -080046import android.util.Slog;
Mathew Inwood04194fe2018-04-04 14:48:03 +010047import android.util.TimingsTraceLog;
Torne (Richard Coles)08cfaf62014-05-08 16:07:05 +010048import android.webkit.WebViewFactory;
Andreas Gampeddc13972016-02-26 16:54:59 -080049import android.widget.TextView;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -080051import com.android.internal.logging.MetricsLogger;
Narayan Kamath669afcc2017-02-06 20:24:08 +000052import com.android.internal.util.Preconditions;
Mathew Inwood04194fe2018-04-04 14:48:03 +010053
Narayan Kamath29564cd2014-08-07 10:57:40 +010054import dalvik.system.DexFile;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055import dalvik.system.VMRuntime;
Andreas Gampe1ef8aef2016-04-11 08:39:52 -070056import dalvik.system.ZygoteHooks;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057
Brian Carlstrom46703b02011-04-06 15:41:29 -070058import libcore.io.IoUtils;
59
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060import java.io.BufferedReader;
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -070061import java.io.File;
Ying Wangd0c45352014-11-13 15:22:47 -080062import java.io.FileInputStream;
63import java.io.FileNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064import java.io.IOException;
65import java.io.InputStream;
66import java.io.InputStreamReader;
Sergio Giro6cb7b1c2016-05-13 16:34:46 +010067import java.security.Provider;
Mathew Inwood04194fe2018-04-04 14:48:03 +010068import java.security.Security;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069
70/**
71 * Startup class for the zygote process.
72 *
Chris Wailes143f7cc2019-01-11 14:30:43 -080073 * Pre-initializes some classes, and then waits for commands on a UNIX domain socket. Based on these
74 * commands, forks off child processes that inherit the initial state of the VM.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075 *
Chris Wailes2be26262019-01-11 16:14:43 -080076 * Please see {@link ZygoteArguments} for documentation on the client protocol.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077 *
78 * @hide
79 */
80public class ZygoteInit {
Chris Wailes143f7cc2019-01-11 14:30:43 -080081
82 // TODO (chriswailes): Change this so it is set with Zygote or ZygoteSecondary as appropriate
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083 private static final String TAG = "Zygote";
84
Jesse Hall2852a282017-01-17 10:17:41 -080085 private static final String PROPERTY_DISABLE_OPENGL_PRELOADING = "ro.zygote.disable_gl_preload";
Jesse Hallba0370e2017-02-09 14:43:14 -080086 private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
Romain Guyc5e36382013-05-09 11:08:17 -070087
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088 private static final int LOG_BOOT_PROGRESS_PRELOAD_START = 3020;
89 private static final int LOG_BOOT_PROGRESS_PRELOAD_END = 3030;
90
Chris Wailes143f7cc2019-01-11 14:30:43 -080091 /**
92 * when preloading, GC after allocating this many bytes
93 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094 private static final int PRELOAD_GC_THRESHOLD = 50000;
95
Narayan Kamathc41638c2014-04-07 13:56:15 +010096 private static final String ABI_LIST_ARG = "--abi-list=";
97
Chris Wailes143f7cc2019-01-11 14:30:43 -080098 // TODO (chriswailes): Re-name this --zygote-socket-name= and then add a
Chris Wailes7e797b62019-02-22 18:29:22 -080099 // --usap-socket-name parameter.
Narayan Kamathc41638c2014-04-07 13:56:15 +0100100 private static final String SOCKET_NAME_ARG = "--socket-name=";
Barry Hayes0b3533a2010-01-20 12:46:47 -0800101
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102 /**
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000103 * Used to pre-load resources.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104 */
105 private static Resources mResources;
Bob Leee5408332009-09-04 18:31:17 -0700106
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107 /**
Ying Wangd0c45352014-11-13 15:22:47 -0800108 * The path of a file that contains classes to preload.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109 */
Ying Wangd0c45352014-11-13 15:22:47 -0800110 private static final String PRELOADED_CLASSES = "/system/etc/preloaded-classes";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111
Chris Wailes143f7cc2019-01-11 14:30:43 -0800112 /**
113 * Controls whether we should preload resources during zygote init.
114 */
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 Kupolov6e3461b2017-08-10 17:00:43 -0700125 static void preload(TimingsTraceLog bootTimingsTraceLog) {
Bill Yi9a76e9b2014-04-29 18:52:48 -0700126 Log.d(TAG, "begin preload");
Neil Fullera84056a2018-07-11 13:59:45 +0100127 bootTimingsTraceLog.traceBegin("BeginPreload");
128 beginPreload();
129 bootTimingsTraceLog.traceEnd(); // BeginPreload
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800130 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 Hall1fe1dc02017-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 Fullera84056a2018-07-11 13:59:45 +0100147 endPreload();
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
Fyodor Kupolov6e3461b2017-08-10 17:00:43 -0700158 preload(new TimingsTraceLog("ZygoteInitTiming_lazy", Trace.TRACE_TAG_DALVIK));
Romain Guy74c69122013-05-08 17:54:20 -0700159 }
160
Neil Fullera84056a2018-07-11 13:59:45 +0100161 private static void beginPreload() {
162 Log.i(TAG, "Calling ZygoteHooks.beginPreload()");
Neil Fuller4f41f612016-05-09 16:55:36 +0100163
Neil Fullera84056a2018-07-11 13:59:45 +0100164 ZygoteHooks.onBeginPreload();
Neil Fuller4f41f612016-05-09 16:55:36 +0100165 }
166
Neil Fullera84056a2018-07-11 13:59:45 +0100167 private static void endPreload() {
168 ZygoteHooks.onEndPreload();
Neil Fuller4f41f612016-05-09 16:55:36 +0100169
Neil Fullera84056a2018-07-11 13:59:45 +0100170 Log.i(TAG, "Called ZygoteHooks.endPreload()");
Neil Fuller4f41f612016-05-09 16:55:36 +0100171 }
172
Brian Carlstrom6c9af962014-09-11 15:36:00 -0700173 private static void preloadSharedLibraries() {
174 Log.i(TAG, "Preloading shared libraries...");
175 System.loadLibrary("android");
176 System.loadLibrary("compiler_rt");
177 System.loadLibrary("jnigraphics");
178 }
179
Jesse Hall1fe1dc02017-07-06 15:30:39 -0700180 native private static void nativePreloadAppProcessHALs();
Chris Wailes143f7cc2019-01-11 14:30:43 -0800181
Peter Collingbourne6f4986b2018-10-26 14:52:14 -0700182 native private static void nativePreloadOpenGL();
Jesse Hall1fe1dc02017-07-06 15:30:39 -0700183
Jesse Hallba0370e2017-02-09 14:43:14 -0800184 private static void preloadOpenGL() {
185 String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
Jesse Hall5d911fe2017-04-13 15:44:24 -0700186 if (!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING, false) &&
187 (driverPackageName == null || driverPackageName.isEmpty())) {
Peter Collingbourne6f4986b2018-10-26 14:52:14 -0700188 nativePreloadOpenGL();
Jesse Hallba0370e2017-02-09 14:43:14 -0800189 }
190 }
191
Raph Levienc3dd1c12015-04-06 10:37:57 -0700192 private static void preloadTextResources() {
193 Hyphenator.init();
Andreas Gampeddc13972016-02-26 16:54:59 -0800194 TextView.preloadFontCache();
Raph Levienc3dd1c12015-04-06 10:37:57 -0700195 }
196
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800197 /**
Sergio Giro69de3202016-05-17 16:52:33 +0100198 * Register AndroidKeyStoreProvider and warm up the providers that are already registered.
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100199 *
Chris Wailes143f7cc2019-01-11 14:30:43 -0800200 * By doing it here we avoid that each app does it when requesting a service from the provider
201 * for the first time.
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100202 */
203 private static void warmUpJcaProviders() {
204 long startTime = SystemClock.uptimeMillis();
205 Trace.traceBegin(
Sergio Giro69de3202016-05-17 16:52:33 +0100206 Trace.TRACE_TAG_DALVIK, "Starting installation of AndroidKeyStoreProvider");
207 // AndroidKeyStoreProvider.install() manipulates the list of JCA providers to insert
208 // preferred providers. Note this is not done via security.properties as the JCA providers
209 // are not on the classpath in the case of, for example, raw dalvikvm runtimes.
210 AndroidKeyStoreProvider.install();
211 Log.i(TAG, "Installed AndroidKeyStoreProvider in "
212 + (SystemClock.uptimeMillis() - startTime) + "ms.");
213 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
214
215 startTime = SystemClock.uptimeMillis();
216 Trace.traceBegin(
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100217 Trace.TRACE_TAG_DALVIK, "Starting warm up of JCA providers");
218 for (Provider p : Security.getProviders()) {
219 p.warmUpServiceProvision();
220 }
221 Log.i(TAG, "Warmed up JCA providers in "
Sergio Giro69de3202016-05-17 16:52:33 +0100222 + (SystemClock.uptimeMillis() - startTime) + "ms.");
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100223 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
224 }
225
226 /**
Chris Wailes143f7cc2019-01-11 14:30:43 -0800227 * Performs Zygote process initialization. Loads and initializes commonly used classes.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800228 *
Chris Wailes143f7cc2019-01-11 14:30:43 -0800229 * Most classes only cause a few hundred bytes to be allocated, but a few will allocate a dozen
230 * Kbytes (in one case, 500+K).
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800231 */
232 private static void preloadClasses() {
233 final VMRuntime runtime = VMRuntime.getRuntime();
Bob Leee5408332009-09-04 18:31:17 -0700234
Ying Wangd0c45352014-11-13 15:22:47 -0800235 InputStream is;
236 try {
237 is = new FileInputStream(PRELOADED_CLASSES);
238 } catch (FileNotFoundException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800239 Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + ".");
Ying Wangd0c45352014-11-13 15:22:47 -0800240 return;
241 }
Bob Leee5408332009-09-04 18:31:17 -0700242
Ying Wangd0c45352014-11-13 15:22:47 -0800243 Log.i(TAG, "Preloading classes...");
244 long startTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800245
Ying Wangd0c45352014-11-13 15:22:47 -0800246 // Drop root perms while running static initializers.
Narayan Kamath23e68782015-01-16 17:22:41 +0000247 final int reuid = Os.getuid();
248 final int regid = Os.getgid();
249
250 // We need to drop root perms only if we're already root. In the case of "wrapped"
251 // processes (see WrapperInit), this function is called from an unprivileged uid
252 // and gid.
253 boolean droppedPriviliges = false;
254 if (reuid == ROOT_UID && regid == ROOT_GID) {
255 try {
256 Os.setregid(ROOT_GID, UNPRIVILEGED_GID);
257 Os.setreuid(ROOT_UID, UNPRIVILEGED_UID);
258 } catch (ErrnoException ex) {
259 throw new RuntimeException("Failed to drop root", ex);
260 }
261
262 droppedPriviliges = true;
Elliott Hughes26b56e62014-12-17 12:28:29 -0800263 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800264
Ying Wangd0c45352014-11-13 15:22:47 -0800265 // Alter the target heap utilization. With explicit GCs this
266 // is not likely to have any effect.
267 float defaultUtilization = runtime.getTargetHeapUtilization();
268 runtime.setTargetHeapUtilization(0.8f);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800269
Ying Wangd0c45352014-11-13 15:22:47 -0800270 try {
Chris Wailes143f7cc2019-01-11 14:30:43 -0800271 BufferedReader br =
Chris Wailesba4c2eb2019-01-11 17:13:00 -0800272 new BufferedReader(new InputStreamReader(is), Zygote.SOCKET_BUFFER_SIZE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800273
Ying Wangd0c45352014-11-13 15:22:47 -0800274 int count = 0;
275 String line;
276 while ((line = br.readLine()) != null) {
277 // Skip comments and blank lines.
278 line = line.trim();
279 if (line.startsWith("#") || line.equals("")) {
280 continue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800281 }
282
Andreas Gampec4253622016-10-28 18:19:30 -0700283 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, line);
Ying Wangd0c45352014-11-13 15:22:47 -0800284 try {
285 if (false) {
286 Log.v(TAG, "Preloading " + line + "...");
287 }
Andreas Gampedd8e5fb2015-04-21 09:01:51 -0700288 // Load and explicitly initialize the given class. Use
289 // Class.forName(String, boolean, ClassLoader) to avoid repeated stack lookups
290 // (to derive the caller's class-loader). Use true to force initialization, and
291 // null for the boot classpath class-loader (could as well cache the
292 // class-loader of this class in a variable).
Andreas Gampec917f742015-04-20 19:16:37 -0700293 Class.forName(line, true, null);
Ying Wangd0c45352014-11-13 15:22:47 -0800294 count++;
295 } catch (ClassNotFoundException e) {
296 Log.w(TAG, "Class not found for preloading: " + line);
297 } catch (UnsatisfiedLinkError e) {
298 Log.w(TAG, "Problem preloading " + line + ": " + e);
299 } catch (Throwable t) {
300 Log.e(TAG, "Error preloading " + line + ".", t);
301 if (t instanceof Error) {
302 throw (Error) t;
303 }
304 if (t instanceof RuntimeException) {
305 throw (RuntimeException) t;
306 }
307 throw new RuntimeException(t);
308 }
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900309 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310 }
Ying Wangd0c45352014-11-13 15:22:47 -0800311
312 Log.i(TAG, "...preloaded " + count + " classes in "
Chris Wailes143f7cc2019-01-11 14:30:43 -0800313 + (SystemClock.uptimeMillis() - startTime) + "ms.");
Ying Wangd0c45352014-11-13 15:22:47 -0800314 } catch (IOException e) {
315 Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);
316 } finally {
317 IoUtils.closeQuietly(is);
318 // Restore default.
319 runtime.setTargetHeapUtilization(defaultUtilization);
320
321 // Fill in dex caches with classes, fields, and methods brought in by preloading.
Yasuhiro Matsuda1ab43d52015-06-30 17:07:32 +0900322 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadDexCaches");
Ying Wangd0c45352014-11-13 15:22:47 -0800323 runtime.preloadDexCaches();
Yasuhiro Matsuda1ab43d52015-06-30 17:07:32 +0900324 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Ying Wangd0c45352014-11-13 15:22:47 -0800325
Narayan Kamath23e68782015-01-16 17:22:41 +0000326 // Bring back root. We'll need it later if we're in the zygote.
327 if (droppedPriviliges) {
328 try {
329 Os.setreuid(ROOT_UID, ROOT_UID);
330 Os.setregid(ROOT_GID, ROOT_GID);
331 } catch (ErrnoException ex) {
332 throw new RuntimeException("Failed to restore root", ex);
333 }
Elliott Hughes26b56e62014-12-17 12:28:29 -0800334 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800335 }
336 }
337
338 /**
Chris Wailes143f7cc2019-01-11 14:30:43 -0800339 * Load in commonly used resources, so they can be shared across processes.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800340 *
Chris Wailes143f7cc2019-01-11 14:30:43 -0800341 * These tend to be a few Kbytes, but are frequently in the 20-40K range, and occasionally even
342 * larger.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800343 */
344 private static void preloadResources() {
345 final VMRuntime runtime = VMRuntime.getRuntime();
Bob Leee5408332009-09-04 18:31:17 -0700346
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800347 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800348 mResources = Resources.getSystem();
349 mResources.startPreloading();
350 if (PRELOAD_RESOURCES) {
351 Log.i(TAG, "Preloading resources...");
352
353 long startTime = SystemClock.uptimeMillis();
354 TypedArray ar = mResources.obtainTypedArray(
355 com.android.internal.R.array.preloaded_drawables);
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800356 int N = preloadDrawables(ar);
Jeff Brown14577c42012-03-08 16:40:14 -0800357 ar.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800358 Log.i(TAG, "...preloaded " + N + " resources in "
Chris Wailes143f7cc2019-01-11 14:30:43 -0800359 + (SystemClock.uptimeMillis() - startTime) + "ms.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800360
361 startTime = SystemClock.uptimeMillis();
362 ar = mResources.obtainTypedArray(
363 com.android.internal.R.array.preloaded_color_state_lists);
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800364 N = preloadColorStateLists(ar);
Jeff Brown14577c42012-03-08 16:40:14 -0800365 ar.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800366 Log.i(TAG, "...preloaded " + N + " resources in "
Chris Wailes143f7cc2019-01-11 14:30:43 -0800367 + (SystemClock.uptimeMillis() - startTime) + "ms.");
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800368
369 if (mResources.getBoolean(
370 com.android.internal.R.bool.config_freeformWindowManagement)) {
371 startTime = SystemClock.uptimeMillis();
372 ar = mResources.obtainTypedArray(
373 com.android.internal.R.array.preloaded_freeform_multi_window_drawables);
374 N = preloadDrawables(ar);
375 ar.recycle();
376 Log.i(TAG, "...preloaded " + N + " resource in "
377 + (SystemClock.uptimeMillis() - startTime) + "ms.");
378 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800379 }
380 mResources.finishPreloading();
381 } catch (RuntimeException e) {
382 Log.w(TAG, "Failure preloading resources", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800383 }
384 }
385
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800386 private static int preloadColorStateLists(TypedArray ar) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800387 int N = ar.length();
Chris Wailes143f7cc2019-01-11 14:30:43 -0800388 for (int i = 0; i < N; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389 int id = ar.getResourceId(i, 0);
Joe Onorato43a17652011-04-06 19:22:23 -0700390 if (false) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800391 Log.v(TAG, "Preloading resource #" + Integer.toHexString(id));
392 }
393 if (id != 0) {
Alan Viverette77bb6f12015-02-11 17:24:33 -0800394 if (mResources.getColorStateList(id, null) == null) {
Dianne Hackborndde331c2012-08-03 14:01:57 -0700395 throw new IllegalArgumentException(
396 "Unable to find preloaded color resource #0x"
Chris Wailes143f7cc2019-01-11 14:30:43 -0800397 + Integer.toHexString(id)
398 + " (" + ar.getString(i) + ")");
Dianne Hackborndde331c2012-08-03 14:01:57 -0700399 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800400 }
401 }
402 return N;
403 }
404
405
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800406 private static int preloadDrawables(TypedArray ar) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800407 int N = ar.length();
Chris Wailes143f7cc2019-01-11 14:30:43 -0800408 for (int i = 0; i < N; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800409 int id = ar.getResourceId(i, 0);
Joe Onorato43a17652011-04-06 19:22:23 -0700410 if (false) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800411 Log.v(TAG, "Preloading resource #" + Integer.toHexString(id));
412 }
413 if (id != 0) {
Alan Viverette84e001a2014-09-22 00:04:22 -0700414 if (mResources.getDrawable(id, null) == null) {
Dianne Hackborndde331c2012-08-03 14:01:57 -0700415 throw new IllegalArgumentException(
416 "Unable to find preloaded drawable resource #0x"
Chris Wailes143f7cc2019-01-11 14:30:43 -0800417 + Integer.toHexString(id)
418 + " (" + ar.getString(i) + ")");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800419 }
420 }
421 }
422 return N;
423 }
424
425 /**
Chris Wailes143f7cc2019-01-11 14:30:43 -0800426 * Runs several special GCs to try to clean up a few generations of softly- and final-reachable
427 * objects, along with any other garbage. This is only useful just before a fork().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800428 */
Neil Fullera84056a2018-07-11 13:59:45 +0100429 private static void gcAndFinalize() {
430 ZygoteHooks.gcAndFinalize();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800431 }
432
433 /**
434 * Finish remaining work for the newly forked system server process.
435 */
Chris Wailes2be26262019-01-11 16:14:43 -0800436 private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
Mike Lockwood90960e82010-08-06 09:15:25 -0400437 // set umask to 0077 so new files and directories will default to owner-only permissions.
Elliott Hughes860c5912014-04-28 19:19:13 -0700438 Os.umask(S_IRWXG | S_IRWXO);
Mike Lockwood90960e82010-08-06 09:15:25 -0400439
Chris Wailes2be26262019-01-11 16:14:43 -0800440 if (parsedArgs.mNiceName != null) {
441 Process.setArgV0(parsedArgs.mNiceName);
Jeff Brownebed7d62011-05-16 17:08:42 -0700442 }
443
Narayan Kamath29564cd2014-08-07 10:57:40 +0100444 final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
445 if (systemServerClasspath != null) {
446 performSystemServerDexOpt(systemServerClasspath);
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -0700447 // Capturing profiles is only supported for debug or eng builds since selinux normally
448 // prevents it.
449 boolean profileSystemServer = SystemProperties.getBoolean(
450 "dalvik.vm.profilesystemserver", false);
451 if (profileSystemServer && (Build.IS_USERDEBUG || Build.IS_ENG)) {
452 try {
Calin Juravle3f3a08a2018-05-02 23:39:19 -0700453 prepareSystemServerProfile(systemServerClasspath);
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -0700454 } catch (Exception e) {
455 Log.wtf(TAG, "Failed to set up system server profile", e);
456 }
457 }
Narayan Kamath29564cd2014-08-07 10:57:40 +0100458 }
459
Chris Wailes2be26262019-01-11 16:14:43 -0800460 if (parsedArgs.mInvokeWith != null) {
461 String[] args = parsedArgs.mRemainingArgs;
Narayan Kamath29564cd2014-08-07 10:57:40 +0100462 // If we have a non-null system server class path, we'll have to duplicate the
463 // existing arguments and append the classpath to it. ART will handle the classpath
464 // correctly when we exec a new process.
465 if (systemServerClasspath != null) {
466 String[] amendedArgs = new String[args.length + 2];
467 amendedArgs[0] = "-cp";
468 amendedArgs[1] = systemServerClasspath;
tony.ys_liu34738172016-12-14 18:50:29 +0800469 System.arraycopy(args, 0, amendedArgs, 2, args.length);
470 args = amendedArgs;
Narayan Kamath29564cd2014-08-07 10:57:40 +0100471 }
472
Chris Wailes2be26262019-01-11 16:14:43 -0800473 WrapperInit.execApplication(parsedArgs.mInvokeWith,
474 parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
Narayan Kamath37ad4b02015-01-19 16:05:24 +0000475 VMRuntime.getCurrentInstructionSet(), null, args);
Narayan Kamathbf99d062017-07-05 14:45:38 +0100476
477 throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
Jeff Brownebed7d62011-05-16 17:08:42 -0700478 } else {
Narayan Kamath29564cd2014-08-07 10:57:40 +0100479 ClassLoader cl = null;
480 if (systemServerClasspath != null) {
Chris Wailes2be26262019-01-11 16:14:43 -0800481 cl = createPathClassLoader(systemServerClasspath, parsedArgs.mTargetSdkVersion);
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700482
Narayan Kamath29564cd2014-08-07 10:57:40 +0100483 Thread.currentThread().setContextClassLoader(cl);
484 }
485
Jeff Brownebed7d62011-05-16 17:08:42 -0700486 /*
487 * Pass the remaining arguments to SystemServer.
488 */
Chris Wailes2be26262019-01-11 16:14:43 -0800489 return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
490 parsedArgs.mRemainingArgs, cl);
Jeff Brownebed7d62011-05-16 17:08:42 -0700491 }
492
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800493 /* should never reach here */
494 }
495
Calin Juravle3f3a08a2018-05-02 23:39:19 -0700496 /**
Chris Wailes143f7cc2019-01-11 14:30:43 -0800497 * Note that preparing the profiles for system server does not require special selinux
498 * permissions. From the installer perspective the system server is a regular package which can
499 * capture profile information.
Calin Juravle3f3a08a2018-05-02 23:39:19 -0700500 */
501 private static void prepareSystemServerProfile(String systemServerClasspath)
502 throws RemoteException {
503 if (systemServerClasspath.isEmpty()) {
504 return;
505 }
506 String[] codePaths = systemServerClasspath.split(":");
507
508 final IInstalld installd = IInstalld.Stub
509 .asInterface(ServiceManager.getService("installd"));
510
511 String systemServerPackageName = "android";
512 String systemServerProfileName = "primary.prof";
513 installd.prepareAppProfile(
514 systemServerPackageName,
515 UserHandle.USER_SYSTEM,
516 UserHandle.getAppId(Process.SYSTEM_UID),
517 systemServerProfileName,
518 codePaths[0],
519 /*dexMetadata*/ null);
520
521 File profileDir = Environment.getDataProfilesDePackageDirectory(
522 UserHandle.USER_SYSTEM, systemServerPackageName);
523 String profilePath = new File(profileDir, systemServerProfileName).getAbsolutePath();
524 VMRuntime.registerAppInfo(profilePath, codePaths);
525 }
526
Mathew Inwood8faeab82018-03-16 14:26:08 +0000527 public static void setApiBlacklistExemptions(String[] exemptions) {
528 VMRuntime.getRuntime().setHiddenApiExemptions(exemptions);
529 }
530
Mathew Inwood04194fe2018-04-04 14:48:03 +0100531 public static void setHiddenApiAccessLogSampleRate(int percent) {
532 VMRuntime.getRuntime().setHiddenApiAccessLogSamplingRate(percent);
533 }
534
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800535 /**
Andrei Onea6cd1b702019-01-25 16:29:44 +0000536 * Sets the implementation to be used for logging hidden API accesses
537 * @param logger the implementation of the VMRuntime.HiddenApiUsageLogger interface
538 */
539 public static void setHiddenApiUsageLogger(VMRuntime.HiddenApiUsageLogger logger) {
540 VMRuntime.getRuntime().setHiddenApiUsageLogger(logger);
541 }
542
543 /**
tony.ys_liu34738172016-12-14 18:50:29 +0800544 * Creates a PathClassLoader for the given class path that is associated with a shared
545 * namespace, i.e., this classloader can access platform-private native libraries. The
546 * classloader will use java.library.path as the native library path.
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700547 */
Narayan Kamathf9419f02017-06-15 11:35:38 +0100548 static ClassLoader createPathClassLoader(String classPath, int targetSdkVersion) {
549 String libraryPath = System.getProperty("java.library.path");
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700550
Nicolas Geoffray5d1814e2018-12-13 09:27:04 +0000551 // We use the boot class loader, that's what the runtime expects at AOT.
552 ClassLoader parent = ClassLoader.getSystemClassLoader().getParent();
553
Narayan Kamathf9419f02017-06-15 11:35:38 +0100554 return ClassLoaderFactory.createClassLoader(classPath, libraryPath, libraryPath,
Nicolas Geoffray5d1814e2018-12-13 09:27:04 +0000555 parent, targetSdkVersion, true /* isNamespaceShared */, null /* classLoaderName */);
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700556 }
557
558 /**
Chris Wailes143f7cc2019-01-11 14:30:43 -0800559 * Performs dex-opt on the elements of {@code classPath}, if needed. We choose the instruction
560 * set of the current runtime.
Narayan Kamath29564cd2014-08-07 10:57:40 +0100561 */
562 private static void performSystemServerDexOpt(String classPath) {
563 final String[] classPathElements = classPath.split(":");
Jeff Sharkey740f5232016-12-09 14:31:26 -0700564 final IInstalld installd = IInstalld.Stub
565 .asInterface(ServiceManager.getService("installd"));
Narayan Kamath29564cd2014-08-07 10:57:40 +0100566 final String instructionSet = VMRuntime.getRuntime().vmInstructionSet();
567
Calin Juravle2f09ff32017-07-24 15:29:56 -0700568 String classPathForElement = "";
Jeff Sharkey740f5232016-12-09 14:31:26 -0700569 for (String classPathElement : classPathElements) {
570 // System server is fully AOTed and never profiled
571 // for profile guided compilation.
Mathieu Chartier5e07a0d2017-06-15 19:09:38 -0700572 String systemServerFilter = SystemProperties.get(
573 "dalvik.vm.systemservercompilerfilter", "speed");
Andreas Gampee7bc1522016-08-09 20:44:04 -0700574
Jeff Sharkey740f5232016-12-09 14:31:26 -0700575 int dexoptNeeded;
576 try {
577 dexoptNeeded = DexFile.getDexOptNeeded(
Chris Wailes143f7cc2019-01-11 14:30:43 -0800578 classPathElement, instructionSet, systemServerFilter,
579 null /* classLoaderContext */, false /* newProfile */,
580 false /* downgrade */);
Jeff Sharkey740f5232016-12-09 14:31:26 -0700581 } catch (FileNotFoundException ignored) {
582 // Do not add to the classpath.
583 Log.w(TAG, "Missing classpath element for system server: " + classPathElement);
584 continue;
585 } catch (IOException e) {
586 // Not fully clear what to do here as we don't know the cause of the
587 // IO exception. Add to the classpath to be conservative, but don't
588 // attempt to compile it.
589 Log.w(TAG, "Error checking classpath element for system server: "
590 + classPathElement, e);
591 dexoptNeeded = DexFile.NO_DEXOPT_NEEDED;
Narayan Kamath29564cd2014-08-07 10:57:40 +0100592 }
Jeff Sharkey740f5232016-12-09 14:31:26 -0700593
594 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
595 final String packageName = "*";
596 final String outputPath = null;
David Brazdilf7e31c02018-02-13 17:04:26 +0000597 final int dexFlags = 0;
Mathieu Chartier5e07a0d2017-06-15 19:09:38 -0700598 final String compilerFilter = systemServerFilter;
Jeff Sharkey740f5232016-12-09 14:31:26 -0700599 final String uuid = StorageManager.UUID_PRIVATE_INTERNAL;
Calin Juravle811a75a2017-04-05 22:49:38 -0700600 final String seInfo = null;
Calin Juravle2f09ff32017-07-24 15:29:56 -0700601 final String classLoaderContext =
602 getSystemServerClassLoaderContext(classPathForElement);
David Brazdil3d44ed02018-01-16 20:01:47 +0000603 final int targetSdkVersion = 0; // SystemServer targets the system's SDK version
Jeff Sharkey740f5232016-12-09 14:31:26 -0700604 try {
605 installd.dexopt(classPathElement, Process.SYSTEM_UID, packageName,
606 instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter,
David Brazdil3d44ed02018-01-16 20:01:47 +0000607 uuid, classLoaderContext, seInfo, false /* downgrade */,
Calin Juravle4bc8f4d2018-02-12 12:00:44 -0800608 targetSdkVersion, /*profileName*/ null, /*dexMetadataPath*/ null,
609 "server-dexopt");
Jeff Sharkey740f5232016-12-09 14:31:26 -0700610 } catch (RemoteException | ServiceSpecificException e) {
611 // Ignore (but log), we need this on the classpath for fallback mode.
612 Log.w(TAG, "Failed compiling classpath element for system server: "
613 + classPathElement, e);
614 }
615 }
616
Calin Juravle2f09ff32017-07-24 15:29:56 -0700617 classPathForElement = encodeSystemServerClassPath(
618 classPathForElement, classPathElement);
Narayan Kamath29564cd2014-08-07 10:57:40 +0100619 }
620 }
621
622 /**
Chris Wailes143f7cc2019-01-11 14:30:43 -0800623 * Encodes the system server class loader context in a format that is accepted by dexopt. This
624 * assumes the system server is always loaded with a {@link dalvik.system.PathClassLoader}.
Calin Juravle2f09ff32017-07-24 15:29:56 -0700625 *
626 * Note that ideally we would use the {@code DexoptUtils} to compute this. However we have no
627 * dependency here on the server so we hard code the logic again.
628 */
629 private static String getSystemServerClassLoaderContext(String classPath) {
630 return classPath == null ? "PCL[]" : "PCL[" + classPath + "]";
631 }
632
633 /**
634 * Encodes the class path in a format accepted by dexopt.
Chris Wailes143f7cc2019-01-11 14:30:43 -0800635 *
636 * @param classPath The old class path (may be empty).
637 * @param newElement The new class path elements
638 * @return The class path encoding resulted from appending {@code newElement} to {@code
639 * classPath}.
Calin Juravle2f09ff32017-07-24 15:29:56 -0700640 */
641 private static String encodeSystemServerClassPath(String classPath, String newElement) {
642 return (classPath == null || classPath.isEmpty())
643 ? newElement
644 : classPath + ":" + newElement;
645 }
646
647 /**
Narayan Kamathbf99d062017-07-05 14:45:38 +0100648 * Prepare the arguments and forks for the system server process.
649 *
Chris Wailes143f7cc2019-01-11 14:30:43 -0800650 * @return A {@code Runnable} that provides an entrypoint into system_server code in the child
651 * process; {@code null} in the parent.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800652 */
Narayan Kamathbf99d062017-07-05 14:45:38 +0100653 private static Runnable forkSystemServer(String abiList, String socketName,
654 ZygoteServer zygoteServer) {
Alex Klyubin48a06e72013-04-19 10:01:42 -0700655 long capabilities = posixCapabilitiesAsBits(
Chris Wailes143f7cc2019-01-11 14:30:43 -0800656 OsConstants.CAP_IPC_LOCK,
657 OsConstants.CAP_KILL,
658 OsConstants.CAP_NET_ADMIN,
659 OsConstants.CAP_NET_BIND_SERVICE,
660 OsConstants.CAP_NET_BROADCAST,
661 OsConstants.CAP_NET_RAW,
662 OsConstants.CAP_SYS_MODULE,
663 OsConstants.CAP_SYS_NICE,
664 OsConstants.CAP_SYS_PTRACE,
665 OsConstants.CAP_SYS_TIME,
666 OsConstants.CAP_SYS_TTY_CONFIG,
667 OsConstants.CAP_WAKE_ALARM,
668 OsConstants.CAP_BLOCK_SUSPEND
Alex Klyubin48a06e72013-04-19 10:01:42 -0700669 );
Luis Hector Chavez72042c92017-07-12 10:03:30 -0700670 /* Containers run without some capabilities, so drop any caps that are not available. */
671 StructCapUserHeader header = new StructCapUserHeader(
672 OsConstants._LINUX_CAPABILITY_VERSION_3, 0);
673 StructCapUserData[] data;
674 try {
675 data = Os.capget(header);
676 } catch (ErrnoException ex) {
677 throw new RuntimeException("Failed to capget()", ex);
Luis Hector Chavez5dd239a2015-10-06 14:01:45 -0700678 }
Luis Hector Chavez72042c92017-07-12 10:03:30 -0700679 capabilities &= ((long) data[0].effective) | (((long) data[1].effective) << 32);
680
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800681 /* Hardcoded command line to start the system server */
682 String args[] = {
Chris Wailes143f7cc2019-01-11 14:30:43 -0800683 "--setuid=1000",
684 "--setgid=1000",
685 "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,"
686 + "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010",
687 "--capabilities=" + capabilities + "," + capabilities,
688 "--nice-name=system_server",
689 "--runtime-args",
690 "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
691 "com.android.server.SystemServer",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800692 };
Chris Wailes2be26262019-01-11 16:14:43 -0800693 ZygoteArguments parsedArgs = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800694
695 int pid;
696
697 try {
Chris Wailes2be26262019-01-11 16:14:43 -0800698 parsedArgs = new ZygoteArguments(args);
699 Zygote.applyDebuggerSystemProperty(parsedArgs);
700 Zygote.applyInvokeWithSystemProperty(parsedArgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800701
Calin Juravle8eb891b2018-05-03 19:51:18 -0700702 boolean profileSystemServer = SystemProperties.getBoolean(
703 "dalvik.vm.profilesystemserver", false);
704 if (profileSystemServer) {
Chris Wailes2be26262019-01-11 16:14:43 -0800705 parsedArgs.mRuntimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
Calin Juravle8eb891b2018-05-03 19:51:18 -0700706 }
707
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800708 /* Request to fork the system server process */
709 pid = Zygote.forkSystemServer(
Chris Wailes2be26262019-01-11 16:14:43 -0800710 parsedArgs.mUid, parsedArgs.mGid,
711 parsedArgs.mGids,
712 parsedArgs.mRuntimeFlags,
Elliott Hughese1dfcb72011-07-08 11:08:07 -0700713 null,
Chris Wailes2be26262019-01-11 16:14:43 -0800714 parsedArgs.mPermittedCapabilities,
715 parsedArgs.mEffectiveCapabilities);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800716 } catch (IllegalArgumentException ex) {
717 throw new RuntimeException(ex);
Bob Leee5408332009-09-04 18:31:17 -0700718 }
719
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800720 /* For child process */
721 if (pid == 0) {
Narayan Kamath64cd9072014-05-13 13:35:14 +0100722 if (hasSecondZygote(abiList)) {
723 waitForSecondaryZygote(socketName);
724 }
725
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000726 zygoteServer.closeServerSocket();
Narayan Kamathbf99d062017-07-05 14:45:38 +0100727 return handleSystemServerProcess(parsedArgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800728 }
729
Narayan Kamathbf99d062017-07-05 14:45:38 +0100730 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800731 }
732
Alex Klyubin48a06e72013-04-19 10:01:42 -0700733 /**
734 * Gets the bit array representation of the provided list of POSIX capabilities.
735 */
736 private static long posixCapabilitiesAsBits(int... capabilities) {
737 long result = 0;
738 for (int capability : capabilities) {
739 if ((capability < 0) || (capability > OsConstants.CAP_LAST_CAP)) {
740 throw new IllegalArgumentException(String.valueOf(capability));
741 }
742 result |= (1L << capability);
743 }
744 return result;
745 }
746
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800747 public static void main(String argv[]) {
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800748 ZygoteServer zygoteServer = null;
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000749
Andreas Gampe1ef8aef2016-04-11 08:39:52 -0700750 // Mark zygote start. This ensures that thread creation will throw
751 // an error.
752 ZygoteHooks.startZygoteNoThreadCreation();
753
Robert Seseke4f8d692016-09-13 19:13:01 -0400754 // Zygote goes into its own process group.
755 try {
756 Os.setpgid(0, 0);
757 } catch (ErrnoException ex) {
758 throw new RuntimeException("Failed to setpgid(0,0)", ex);
759 }
760
Chris Wailesba4c2eb2019-01-11 17:13:00 -0800761 Runnable caller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800762 try {
Fyodor Kupolov6733e6c2017-01-06 18:27:05 -0800763 // Report Zygote start time to tron unless it is a runtime restart
764 if (!"1".equals(SystemProperties.get("sys.boot_completed"))) {
765 MetricsLogger.histogram(null, "boot_zygote_init",
766 (int) SystemClock.elapsedRealtime());
767 }
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800768
769 String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
Fyodor Kupolov6e3461b2017-08-10 17:00:43 -0700770 TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag,
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800771 Trace.TRACE_TAG_DALVIK);
772 bootTimingsTraceLog.traceBegin("ZygoteInit");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900773 RuntimeInit.enableDdms();
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900774
Narayan Kamathc41638c2014-04-07 13:56:15 +0100775 boolean startSystemServer = false;
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800776 String zygoteSocketName = "zygote";
Narayan Kamathc41638c2014-04-07 13:56:15 +0100777 String abiList = null;
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000778 boolean enableLazyPreload = false;
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900779 for (int i = 1; i < argv.length; i++) {
780 if ("start-system-server".equals(argv[i])) {
781 startSystemServer = true;
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000782 } else if ("--enable-lazy-preload".equals(argv[i])) {
783 enableLazyPreload = true;
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900784 } else if (argv[i].startsWith(ABI_LIST_ARG)) {
785 abiList = argv[i].substring(ABI_LIST_ARG.length());
786 } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800787 zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900788 } else {
789 throw new RuntimeException("Unknown command line argument: " + argv[i]);
Narayan Kamathc41638c2014-04-07 13:56:15 +0100790 }
791 }
792
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800793 final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME);
794
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900795 if (abiList == null) {
796 throw new RuntimeException("No ABI list supplied.");
797 }
798
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800799 Zygote.getSocketFDs(isPrimaryZygote);
Chris Wailesba4c2eb2019-01-11 17:13:00 -0800800
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000801 // In some configurations, we avoid preloading resources and classes eagerly.
802 // In such cases, we will preload things prior to our first fork.
803 if (!enableLazyPreload) {
804 bootTimingsTraceLog.traceBegin("ZygotePreload");
805 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
Chris Wailes143f7cc2019-01-11 14:30:43 -0800806 SystemClock.uptimeMillis());
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000807 preload(bootTimingsTraceLog);
808 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
Chris Wailes143f7cc2019-01-11 14:30:43 -0800809 SystemClock.uptimeMillis());
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000810 bootTimingsTraceLog.traceEnd(); // ZygotePreload
Narayan Kamathb49996d2017-02-06 20:24:08 +0000811 } else {
Hiroshi Yamauchi1e3db872017-03-02 13:39:07 -0800812 Zygote.resetNicePriority();
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000813 }
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900814
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900815 // Do an initial gc to clean up after startup
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800816 bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900817 gcAndFinalize();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800818 bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900819
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800820 bootTimingsTraceLog.traceEnd(); // ZygoteInit
Jamie Gennis6ad04522013-04-15 18:53:24 -0700821 // Disable tracing so that forked processes do not inherit stale tracing tags from
822 // Zygote.
John Reck62cc1192017-05-12 15:39:51 -0700823 Trace.setTracingEnabled(false, 0);
Jamie Gennis6ad04522013-04-15 18:53:24 -0700824
Victor Hsiehc8176ef2018-01-08 12:43:00 -0800825 Zygote.nativeSecurityInit();
826
doheon1.lee885b7422016-01-20 13:07:27 +0900827 // Zygote process unmounts root storage spaces.
828 Zygote.nativeUnmountStorageOnInit();
829
Andreas Gampe1ef8aef2016-04-11 08:39:52 -0700830 ZygoteHooks.stopZygoteNoThreadCreation();
831
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800832 zygoteServer = new ZygoteServer(isPrimaryZygote);
833
Narayan Kamathc41638c2014-04-07 13:56:15 +0100834 if (startSystemServer) {
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800835 Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
Narayan Kamathbf99d062017-07-05 14:45:38 +0100836
837 // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
838 // child (system_server) process.
839 if (r != null) {
840 r.run();
841 return;
842 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800843 }
844
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800845 Log.i(TAG, "Accepting command socket connections");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800846
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800847 // The select loop returns early in the child process after a fork and
848 // loops forever in the zygote.
849 caller = zygoteServer.runSelectLoop(abiList);
Christopher Ferrisea8b5de2016-06-17 15:29:58 -0700850 } catch (Throwable ex) {
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000851 Log.e(TAG, "System zygote died with exception", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800852 throw ex;
Narayan Kamathbf99d062017-07-05 14:45:38 +0100853 } finally {
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800854 if (zygoteServer != null) {
855 zygoteServer.closeServerSocket();
856 }
Narayan Kamathbf99d062017-07-05 14:45:38 +0100857 }
858
859 // We're in the child process and have exited the select loop. Proceed to execute the
860 // command.
861 if (caller != null) {
862 caller.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800863 }
864 }
865
866 /**
Narayan Kamath64cd9072014-05-13 13:35:14 +0100867 * Return {@code true} if this device configuration has another zygote.
868 *
Chris Wailes143f7cc2019-01-11 14:30:43 -0800869 * We determine this by comparing the device ABI list with this zygotes list. If this zygote
870 * supports all ABIs this device supports, there won't be another zygote.
Narayan Kamath64cd9072014-05-13 13:35:14 +0100871 */
872 private static boolean hasSecondZygote(String abiList) {
873 return !SystemProperties.get("ro.product.cpu.abilist").equals(abiList);
874 }
875
876 private static void waitForSecondaryZygote(String socketName) {
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800877 String otherZygoteName = Zygote.PRIMARY_SOCKET_NAME.equals(socketName)
878 ? Zygote.SECONDARY_SOCKET_NAME : Zygote.PRIMARY_SOCKET_NAME;
Gustav Senntonf0c52b52017-04-27 17:00:50 +0100879 ZygoteProcess.waitForConnectionToZygote(otherZygoteName);
Narayan Kamath64cd9072014-05-13 13:35:14 +0100880 }
881
Narayan Kamath669afcc2017-02-06 20:24:08 +0000882 static boolean isPreloadComplete() {
883 return sPreloadComplete;
884 }
885
Narayan Kamath64cd9072014-05-13 13:35:14 +0100886 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800887 * Class not instantiable.
888 */
889 private ZygoteInit() {
890 }
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800891
892 /**
Chris Wailes143f7cc2019-01-11 14:30:43 -0800893 * The main function called when started through the zygote process. This could be unified with
894 * main(), if the native code in nativeFinishInit() were rationalized with Zygote startup.<p>
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800895 *
896 * Current recognized args:
897 * <ul>
898 * <li> <code> [--] &lt;start class name&gt; &lt;args&gt;
899 * </ul>
900 *
901 * @param targetSdkVersion target SDK version
902 * @param argv arg strings
903 */
Chris Wailes143f7cc2019-01-11 14:30:43 -0800904 public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
905 ClassLoader classLoader) {
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800906 if (RuntimeInit.DEBUG) {
907 Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
908 }
909
910 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
911 RuntimeInit.redirectLogStreams();
912
913 RuntimeInit.commonInit();
914 ZygoteInit.nativeZygoteInit();
Narayan Kamathbf99d062017-07-05 14:45:38 +0100915 return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800916 }
917
Robert Sesekd0a190df2018-02-12 18:46:01 -0500918 /**
Chris Wailes143f7cc2019-01-11 14:30:43 -0800919 * The main function called when starting a child zygote process. This is used as an alternative
920 * to zygoteInit(), which skips calling into initialization routines that start the Binder
921 * threadpool.
Robert Sesekd0a190df2018-02-12 18:46:01 -0500922 */
923 static final Runnable childZygoteInit(
924 int targetSdkVersion, String[] argv, ClassLoader classLoader) {
925 RuntimeInit.Arguments args = new RuntimeInit.Arguments(argv);
926 return RuntimeInit.findStaticMain(args.startClass, args.startArgs, classLoader);
927 }
928
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800929 private static final native void nativeZygoteInit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800930}