blob: ad4c6dd7a92b3274a8a6d19550678ca4933fff29 [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
Andrei Onea15884392019-03-22 17:28:11 +000022import android.annotation.UnsupportedAppUsage;
Steven Morelandbdc27022019-03-29 21:23:48 +000023import android.app.ApplicationLoaders;
24import android.content.pm.SharedLibraryInfo;
Chris Wailes6d482d542019-04-03 13:00:52 -070025import android.content.res.Resources;
26import android.content.res.TypedArray;
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -070027import android.os.Build;
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -070028import android.os.Environment;
Mathew Inwood04194fe2018-04-04 14:48:03 +010029import android.os.IInstalld;
Jeff Brownebed7d62011-05-16 17:08:42 -070030import android.os.Process;
Jeff Sharkey740f5232016-12-09 14:31:26 -070031import android.os.RemoteException;
32import android.os.ServiceManager;
33import android.os.ServiceSpecificException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import android.os.SystemClock;
Romain Guyc5e36382013-05-09 11:08:17 -070035import android.os.SystemProperties;
Jamie Gennis6ad04522013-04-15 18:53:24 -070036import android.os.Trace;
Calin Juravle3f3a08a2018-05-02 23:39:19 -070037import android.os.UserHandle;
Robert Sesek8f8d1872016-03-18 16:52:57 -040038import android.os.ZygoteProcess;
Jeff Sharkeyc98c7bc2016-12-07 14:57:34 -070039import android.os.storage.StorageManager;
Mathieu Chartier77aca502019-08-19 13:08:14 -070040import android.provider.DeviceConfig;
Sergio Giro69de3202016-05-17 16:52:33 +010041import android.security.keystore.AndroidKeyStoreProvider;
Bill Yi9a76e9b2014-04-29 18:52:48 -070042import android.system.ErrnoException;
Elliott Hughes860c5912014-04-28 19:19:13 -070043import android.system.Os;
44import android.system.OsConstants;
Luis Hector Chavez72042c92017-07-12 10:03:30 -070045import android.system.StructCapUserData;
46import android.system.StructCapUserHeader;
Raph Levienc3dd1c12015-04-06 10:37:57 -070047import android.text.Hyphenator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048import android.util.EventLog;
49import android.util.Log;
Andreas Gampe76d4fc82017-02-07 19:44:37 -080050import android.util.Slog;
Mathew Inwood04194fe2018-04-04 14:48:03 +010051import android.util.TimingsTraceLog;
Torne (Richard Coles)08cfaf62014-05-08 16:07:05 +010052import android.webkit.WebViewFactory;
Andreas Gampeddc13972016-02-26 16:54:59 -080053import android.widget.TextView;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -080055import com.android.internal.logging.MetricsLogger;
Narayan Kamath669afcc2017-02-06 20:24:08 +000056import com.android.internal.util.Preconditions;
Mathew Inwood04194fe2018-04-04 14:48:03 +010057
Narayan Kamath29564cd2014-08-07 10:57:40 +010058import dalvik.system.DexFile;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059import dalvik.system.VMRuntime;
Andreas Gampe1ef8aef2016-04-11 08:39:52 -070060import dalvik.system.ZygoteHooks;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061
Brian Carlstrom46703b02011-04-06 15:41:29 -070062import libcore.io.IoUtils;
63
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064import java.io.BufferedReader;
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -070065import java.io.File;
Ying Wangd0c45352014-11-13 15:22:47 -080066import java.io.FileInputStream;
67import java.io.FileNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068import java.io.IOException;
69import java.io.InputStream;
70import java.io.InputStreamReader;
Sergio Giro6cb7b1c2016-05-13 16:34:46 +010071import java.security.Provider;
Mathew Inwood04194fe2018-04-04 14:48:03 +010072import java.security.Security;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073
74/**
75 * Startup class for the zygote process.
76 *
Chris Wailes143f7cc2019-01-11 14:30:43 -080077 * Pre-initializes some classes, and then waits for commands on a UNIX domain socket. Based on these
78 * commands, forks off child processes that inherit the initial state of the VM.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079 *
Chris Wailes2be26262019-01-11 16:14:43 -080080 * Please see {@link ZygoteArguments} for documentation on the client protocol.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081 *
82 * @hide
83 */
84public class ZygoteInit {
Chris Wailes143f7cc2019-01-11 14:30:43 -080085
86 // TODO (chriswailes): Change this so it is set with Zygote or ZygoteSecondary as appropriate
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087 private static final String TAG = "Zygote";
88
Yiwei Zhang4bf3d9e2019-04-15 16:24:32 -070089 private static final String PROPERTY_DISABLE_GRAPHICS_DRIVER_PRELOADING =
90 "ro.zygote.disable_gl_preload";
Romain Guyc5e36382013-05-09 11:08:17 -070091
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092 private static final int LOG_BOOT_PROGRESS_PRELOAD_START = 3020;
93 private static final int LOG_BOOT_PROGRESS_PRELOAD_END = 3030;
94
Narayan Kamathc41638c2014-04-07 13:56:15 +010095 private static final String ABI_LIST_ARG = "--abi-list=";
96
Chris Wailes143f7cc2019-01-11 14:30:43 -080097 // TODO (chriswailes): Re-name this --zygote-socket-name= and then add a
Chris Wailes7e797b62019-02-22 18:29:22 -080098 // --usap-socket-name parameter.
Narayan Kamathc41638c2014-04-07 13:56:15 +010099 private static final String SOCKET_NAME_ARG = "--socket-name=";
Barry Hayes0b3533a2010-01-20 12:46:47 -0800100
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101 /**
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000102 * Used to pre-load resources.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103 */
Andrei Onea15884392019-03-22 17:28:11 +0000104 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105 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
Andreas Gampe76b4b2c2019-03-15 11:56:48 -0700125 /**
126 * Cached classloader to use for the system server. Will only be populated in the system
127 * server process.
128 */
129 private static ClassLoader sCachedSystemServerClassLoader = null;
130
Fyodor Kupolov6e3461b2017-08-10 17:00:43 -0700131 static void preload(TimingsTraceLog bootTimingsTraceLog) {
Bill Yi9a76e9b2014-04-29 18:52:48 -0700132 Log.d(TAG, "begin preload");
Neil Fullera84056a2018-07-11 13:59:45 +0100133 bootTimingsTraceLog.traceBegin("BeginPreload");
134 beginPreload();
135 bootTimingsTraceLog.traceEnd(); // BeginPreload
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800136 bootTimingsTraceLog.traceBegin("PreloadClasses");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900137 preloadClasses();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800138 bootTimingsTraceLog.traceEnd(); // PreloadClasses
Steven Morelandbdc27022019-03-29 21:23:48 +0000139 bootTimingsTraceLog.traceBegin("CacheNonBootClasspathClassLoaders");
140 cacheNonBootClasspathClassLoaders();
141 bootTimingsTraceLog.traceEnd(); // CacheNonBootClasspathClassLoaders
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800142 bootTimingsTraceLog.traceBegin("PreloadResources");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900143 preloadResources();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800144 bootTimingsTraceLog.traceEnd(); // PreloadResources
Jesse Hall1fe1dc02017-07-06 15:30:39 -0700145 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs");
146 nativePreloadAppProcessHALs();
147 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Yiwei Zhang4bf3d9e2019-04-15 16:24:32 -0700148 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadGraphicsDriver");
149 maybePreloadGraphicsDriver();
Jesse Hallba0370e2017-02-09 14:43:14 -0800150 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Brian Carlstrom6c9af962014-09-11 15:36:00 -0700151 preloadSharedLibraries();
Raph Levienc3dd1c12015-04-06 10:37:57 -0700152 preloadTextResources();
Torne (Richard Coles)08cfaf62014-05-08 16:07:05 +0100153 // Ask the WebViewFactory to do any initialization that must run in the zygote process,
154 // for memory sharing purposes.
155 WebViewFactory.prepareWebViewInZygote();
Neil Fullera84056a2018-07-11 13:59:45 +0100156 endPreload();
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100157 warmUpJcaProviders();
Bill Yi9a76e9b2014-04-29 18:52:48 -0700158 Log.d(TAG, "end preload");
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000159
160 sPreloadComplete = true;
161 }
162
Narayan Kamath669afcc2017-02-06 20:24:08 +0000163 public static void lazyPreload() {
164 Preconditions.checkState(!sPreloadComplete);
165 Log.i(TAG, "Lazily preloading resources.");
166
Fyodor Kupolov6e3461b2017-08-10 17:00:43 -0700167 preload(new TimingsTraceLog("ZygoteInitTiming_lazy", Trace.TRACE_TAG_DALVIK));
Romain Guy74c69122013-05-08 17:54:20 -0700168 }
169
Neil Fullera84056a2018-07-11 13:59:45 +0100170 private static void beginPreload() {
171 Log.i(TAG, "Calling ZygoteHooks.beginPreload()");
Neil Fuller4f41f612016-05-09 16:55:36 +0100172
Neil Fullera84056a2018-07-11 13:59:45 +0100173 ZygoteHooks.onBeginPreload();
Neil Fuller4f41f612016-05-09 16:55:36 +0100174 }
175
Neil Fullera84056a2018-07-11 13:59:45 +0100176 private static void endPreload() {
177 ZygoteHooks.onEndPreload();
Neil Fuller4f41f612016-05-09 16:55:36 +0100178
Neil Fullera84056a2018-07-11 13:59:45 +0100179 Log.i(TAG, "Called ZygoteHooks.endPreload()");
Neil Fuller4f41f612016-05-09 16:55:36 +0100180 }
181
Brian Carlstrom6c9af962014-09-11 15:36:00 -0700182 private static void preloadSharedLibraries() {
183 Log.i(TAG, "Preloading shared libraries...");
184 System.loadLibrary("android");
185 System.loadLibrary("compiler_rt");
186 System.loadLibrary("jnigraphics");
187 }
188
Jesse Hall1fe1dc02017-07-06 15:30:39 -0700189 native private static void nativePreloadAppProcessHALs();
Chris Wailes143f7cc2019-01-11 14:30:43 -0800190
Chris Wailes35fdbc52019-04-17 17:55:48 -0700191 /**
Yiwei Zhang4bf3d9e2019-04-15 16:24:32 -0700192 * This call loads the graphics driver by making an OpenGL or Vulkan call. If the driver is
Chris Wailes35fdbc52019-04-17 17:55:48 -0700193 * not currently in memory it will load and initialize it. The OpenGL call itself is relatively
194 * cheap and pure. This means that it is a low overhead on the initial call, and is safe and
195 * cheap to call later. Calls after the initial invocation will effectively be no-ops for the
196 * system.
197 */
Yiwei Zhang4bf3d9e2019-04-15 16:24:32 -0700198 static native void nativePreloadGraphicsDriver();
Jesse Hall1fe1dc02017-07-06 15:30:39 -0700199
Yiwei Zhang4bf3d9e2019-04-15 16:24:32 -0700200 private static void maybePreloadGraphicsDriver() {
Yiwei Zhang6100c702019-06-04 16:25:28 -0700201 if (!SystemProperties.getBoolean(PROPERTY_DISABLE_GRAPHICS_DRIVER_PRELOADING, false)) {
Yiwei Zhang4bf3d9e2019-04-15 16:24:32 -0700202 nativePreloadGraphicsDriver();
Jesse Hallba0370e2017-02-09 14:43:14 -0800203 }
204 }
205
Raph Levienc3dd1c12015-04-06 10:37:57 -0700206 private static void preloadTextResources() {
207 Hyphenator.init();
Andreas Gampeddc13972016-02-26 16:54:59 -0800208 TextView.preloadFontCache();
Raph Levienc3dd1c12015-04-06 10:37:57 -0700209 }
210
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211 /**
Sergio Giro69de3202016-05-17 16:52:33 +0100212 * Register AndroidKeyStoreProvider and warm up the providers that are already registered.
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100213 *
Chris Wailes143f7cc2019-01-11 14:30:43 -0800214 * By doing it here we avoid that each app does it when requesting a service from the provider
215 * for the first time.
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100216 */
217 private static void warmUpJcaProviders() {
218 long startTime = SystemClock.uptimeMillis();
219 Trace.traceBegin(
Sergio Giro69de3202016-05-17 16:52:33 +0100220 Trace.TRACE_TAG_DALVIK, "Starting installation of AndroidKeyStoreProvider");
221 // AndroidKeyStoreProvider.install() manipulates the list of JCA providers to insert
222 // preferred providers. Note this is not done via security.properties as the JCA providers
223 // are not on the classpath in the case of, for example, raw dalvikvm runtimes.
224 AndroidKeyStoreProvider.install();
225 Log.i(TAG, "Installed AndroidKeyStoreProvider in "
226 + (SystemClock.uptimeMillis() - startTime) + "ms.");
227 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
228
229 startTime = SystemClock.uptimeMillis();
230 Trace.traceBegin(
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100231 Trace.TRACE_TAG_DALVIK, "Starting warm up of JCA providers");
232 for (Provider p : Security.getProviders()) {
233 p.warmUpServiceProvision();
234 }
235 Log.i(TAG, "Warmed up JCA providers in "
Sergio Giro69de3202016-05-17 16:52:33 +0100236 + (SystemClock.uptimeMillis() - startTime) + "ms.");
Sergio Giro6cb7b1c2016-05-13 16:34:46 +0100237 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
238 }
239
240 /**
Chris Wailes143f7cc2019-01-11 14:30:43 -0800241 * Performs Zygote process initialization. Loads and initializes commonly used classes.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800242 *
Chris Wailes143f7cc2019-01-11 14:30:43 -0800243 * Most classes only cause a few hundred bytes to be allocated, but a few will allocate a dozen
244 * Kbytes (in one case, 500+K).
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800245 */
246 private static void preloadClasses() {
247 final VMRuntime runtime = VMRuntime.getRuntime();
Bob Leee5408332009-09-04 18:31:17 -0700248
Ying Wangd0c45352014-11-13 15:22:47 -0800249 InputStream is;
250 try {
Mathieu Chartierd3c72db2019-10-23 09:53:39 -0700251 // If we are profiling the boot image, avoid preloading classes.
252 // Can't use device_config since we are the zygote.
253 String prop = SystemProperties.get(
254 "persist.device_config.runtime_native_boot.profilebootclasspath", "");
255 // Might be empty if the property is unset since the default is "".
256 if (prop.length() == 0) {
257 prop = SystemProperties.get("dalvik.vm.profilebootclasspath", "");
258 }
259 if ("true".equals(prop)) {
260 return;
261 }
262
Ying Wangd0c45352014-11-13 15:22:47 -0800263 is = new FileInputStream(PRELOADED_CLASSES);
264 } catch (FileNotFoundException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265 Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + ".");
Ying Wangd0c45352014-11-13 15:22:47 -0800266 return;
267 }
Bob Leee5408332009-09-04 18:31:17 -0700268
Ying Wangd0c45352014-11-13 15:22:47 -0800269 Log.i(TAG, "Preloading classes...");
270 long startTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800271
Ying Wangd0c45352014-11-13 15:22:47 -0800272 // Drop root perms while running static initializers.
Narayan Kamath23e68782015-01-16 17:22:41 +0000273 final int reuid = Os.getuid();
274 final int regid = Os.getgid();
275
276 // We need to drop root perms only if we're already root. In the case of "wrapped"
277 // processes (see WrapperInit), this function is called from an unprivileged uid
278 // and gid.
279 boolean droppedPriviliges = false;
280 if (reuid == ROOT_UID && regid == ROOT_GID) {
281 try {
282 Os.setregid(ROOT_GID, UNPRIVILEGED_GID);
283 Os.setreuid(ROOT_UID, UNPRIVILEGED_UID);
284 } catch (ErrnoException ex) {
285 throw new RuntimeException("Failed to drop root", ex);
286 }
287
288 droppedPriviliges = true;
Elliott Hughes26b56e62014-12-17 12:28:29 -0800289 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800290
Ying Wangd0c45352014-11-13 15:22:47 -0800291 try {
Chris Wailes143f7cc2019-01-11 14:30:43 -0800292 BufferedReader br =
Chris Wailesba4c2eb2019-01-11 17:13:00 -0800293 new BufferedReader(new InputStreamReader(is), Zygote.SOCKET_BUFFER_SIZE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800294
Ying Wangd0c45352014-11-13 15:22:47 -0800295 int count = 0;
296 String line;
297 while ((line = br.readLine()) != null) {
298 // Skip comments and blank lines.
299 line = line.trim();
300 if (line.startsWith("#") || line.equals("")) {
301 continue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800302 }
303
Andreas Gampec4253622016-10-28 18:19:30 -0700304 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, line);
Ying Wangd0c45352014-11-13 15:22:47 -0800305 try {
Andreas Gampedd8e5fb2015-04-21 09:01:51 -0700306 // Load and explicitly initialize the given class. Use
307 // Class.forName(String, boolean, ClassLoader) to avoid repeated stack lookups
308 // (to derive the caller's class-loader). Use true to force initialization, and
309 // null for the boot classpath class-loader (could as well cache the
310 // class-loader of this class in a variable).
Andreas Gampec917f742015-04-20 19:16:37 -0700311 Class.forName(line, true, null);
Ying Wangd0c45352014-11-13 15:22:47 -0800312 count++;
313 } catch (ClassNotFoundException e) {
314 Log.w(TAG, "Class not found for preloading: " + line);
315 } catch (UnsatisfiedLinkError e) {
316 Log.w(TAG, "Problem preloading " + line + ": " + e);
317 } catch (Throwable t) {
318 Log.e(TAG, "Error preloading " + line + ".", t);
319 if (t instanceof Error) {
320 throw (Error) t;
321 }
322 if (t instanceof RuntimeException) {
323 throw (RuntimeException) t;
324 }
325 throw new RuntimeException(t);
326 }
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900327 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800328 }
Ying Wangd0c45352014-11-13 15:22:47 -0800329
330 Log.i(TAG, "...preloaded " + count + " classes in "
Chris Wailes143f7cc2019-01-11 14:30:43 -0800331 + (SystemClock.uptimeMillis() - startTime) + "ms.");
Ying Wangd0c45352014-11-13 15:22:47 -0800332 } catch (IOException e) {
333 Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);
334 } finally {
335 IoUtils.closeQuietly(is);
Ying Wangd0c45352014-11-13 15:22:47 -0800336
337 // Fill in dex caches with classes, fields, and methods brought in by preloading.
Yasuhiro Matsuda1ab43d52015-06-30 17:07:32 +0900338 Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadDexCaches");
Ying Wangd0c45352014-11-13 15:22:47 -0800339 runtime.preloadDexCaches();
Yasuhiro Matsuda1ab43d52015-06-30 17:07:32 +0900340 Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
Ying Wangd0c45352014-11-13 15:22:47 -0800341
Narayan Kamath23e68782015-01-16 17:22:41 +0000342 // Bring back root. We'll need it later if we're in the zygote.
343 if (droppedPriviliges) {
344 try {
345 Os.setreuid(ROOT_UID, ROOT_UID);
346 Os.setregid(ROOT_GID, ROOT_GID);
347 } catch (ErrnoException ex) {
348 throw new RuntimeException("Failed to restore root", ex);
349 }
Elliott Hughes26b56e62014-12-17 12:28:29 -0800350 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800351 }
352 }
353
354 /**
Steven Morelandbdc27022019-03-29 21:23:48 +0000355 * Load in things which are used by many apps but which cannot be put in the boot
356 * classpath.
357 */
358 private static void cacheNonBootClasspathClassLoaders() {
359 // These libraries used to be part of the bootclasspath, but had to be removed.
360 // Old system applications still get them for backwards compatibility reasons,
361 // so they are cached here in order to preserve performance characteristics.
362 SharedLibraryInfo hidlBase = new SharedLibraryInfo(
363 "/system/framework/android.hidl.base-V1.0-java.jar", null /*packageName*/,
364 null /*codePaths*/, null /*name*/, 0 /*version*/, SharedLibraryInfo.TYPE_BUILTIN,
365 null /*declaringPackage*/, null /*dependentPackages*/, null /*dependencies*/);
366 SharedLibraryInfo hidlManager = new SharedLibraryInfo(
367 "/system/framework/android.hidl.manager-V1.0-java.jar", null /*packageName*/,
368 null /*codePaths*/, null /*name*/, 0 /*version*/, SharedLibraryInfo.TYPE_BUILTIN,
369 null /*declaringPackage*/, null /*dependentPackages*/, null /*dependencies*/);
370 hidlManager.addDependency(hidlBase);
371
372 ApplicationLoaders.getDefault().createAndCacheNonBootclasspathSystemClassLoaders(
373 new SharedLibraryInfo[]{
374 // ordered dependencies first
375 hidlBase,
376 hidlManager,
377 });
378 }
379
380 /**
Chris Wailes143f7cc2019-01-11 14:30:43 -0800381 * Load in commonly used resources, so they can be shared across processes.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382 *
Chris Wailes143f7cc2019-01-11 14:30:43 -0800383 * These tend to be a few Kbytes, but are frequently in the 20-40K range, and occasionally even
384 * larger.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800385 */
386 private static void preloadResources() {
387 final VMRuntime runtime = VMRuntime.getRuntime();
Bob Leee5408332009-09-04 18:31:17 -0700388
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800390 mResources = Resources.getSystem();
391 mResources.startPreloading();
392 if (PRELOAD_RESOURCES) {
393 Log.i(TAG, "Preloading resources...");
394
395 long startTime = SystemClock.uptimeMillis();
396 TypedArray ar = mResources.obtainTypedArray(
397 com.android.internal.R.array.preloaded_drawables);
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800398 int N = preloadDrawables(ar);
Jeff Brown14577c42012-03-08 16:40:14 -0800399 ar.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800400 Log.i(TAG, "...preloaded " + N + " resources in "
Chris Wailes143f7cc2019-01-11 14:30:43 -0800401 + (SystemClock.uptimeMillis() - startTime) + "ms.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402
403 startTime = SystemClock.uptimeMillis();
404 ar = mResources.obtainTypedArray(
405 com.android.internal.R.array.preloaded_color_state_lists);
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800406 N = preloadColorStateLists(ar);
Jeff Brown14577c42012-03-08 16:40:14 -0800407 ar.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800408 Log.i(TAG, "...preloaded " + N + " resources in "
Chris Wailes143f7cc2019-01-11 14:30:43 -0800409 + (SystemClock.uptimeMillis() - startTime) + "ms.");
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800410
411 if (mResources.getBoolean(
412 com.android.internal.R.bool.config_freeformWindowManagement)) {
413 startTime = SystemClock.uptimeMillis();
414 ar = mResources.obtainTypedArray(
415 com.android.internal.R.array.preloaded_freeform_multi_window_drawables);
416 N = preloadDrawables(ar);
417 ar.recycle();
418 Log.i(TAG, "...preloaded " + N + " resource in "
419 + (SystemClock.uptimeMillis() - startTime) + "ms.");
420 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800421 }
422 mResources.finishPreloading();
423 } catch (RuntimeException e) {
424 Log.w(TAG, "Failure preloading resources", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800425 }
426 }
427
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800428 private static int preloadColorStateLists(TypedArray ar) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800429 int N = ar.length();
Chris Wailes143f7cc2019-01-11 14:30:43 -0800430 for (int i = 0; i < N; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800431 int id = ar.getResourceId(i, 0);
Joe Onorato43a17652011-04-06 19:22:23 -0700432 if (false) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800433 Log.v(TAG, "Preloading resource #" + Integer.toHexString(id));
434 }
435 if (id != 0) {
Alan Viverette77bb6f12015-02-11 17:24:33 -0800436 if (mResources.getColorStateList(id, null) == null) {
Dianne Hackborndde331c2012-08-03 14:01:57 -0700437 throw new IllegalArgumentException(
438 "Unable to find preloaded color resource #0x"
Chris Wailes143f7cc2019-01-11 14:30:43 -0800439 + Integer.toHexString(id)
440 + " (" + ar.getString(i) + ")");
Dianne Hackborndde331c2012-08-03 14:01:57 -0700441 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800442 }
443 }
444 return N;
445 }
446
447
Filip Gruszczynski811dc3b2015-11-23 12:34:22 -0800448 private static int preloadDrawables(TypedArray ar) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800449 int N = ar.length();
Chris Wailes143f7cc2019-01-11 14:30:43 -0800450 for (int i = 0; i < N; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800451 int id = ar.getResourceId(i, 0);
Joe Onorato43a17652011-04-06 19:22:23 -0700452 if (false) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800453 Log.v(TAG, "Preloading resource #" + Integer.toHexString(id));
454 }
455 if (id != 0) {
Alan Viverette84e001a2014-09-22 00:04:22 -0700456 if (mResources.getDrawable(id, null) == null) {
Dianne Hackborndde331c2012-08-03 14:01:57 -0700457 throw new IllegalArgumentException(
458 "Unable to find preloaded drawable resource #0x"
Chris Wailes143f7cc2019-01-11 14:30:43 -0800459 + Integer.toHexString(id)
460 + " (" + ar.getString(i) + ")");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800461 }
462 }
463 }
464 return N;
465 }
466
467 /**
Chris Wailes143f7cc2019-01-11 14:30:43 -0800468 * Runs several special GCs to try to clean up a few generations of softly- and final-reachable
469 * objects, along with any other garbage. This is only useful just before a fork().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800470 */
Neil Fullera84056a2018-07-11 13:59:45 +0100471 private static void gcAndFinalize() {
472 ZygoteHooks.gcAndFinalize();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800473 }
474
Mathieu Chartier3b05e4d2019-09-09 13:05:31 -0700475 private static boolean shouldProfileSystemServer() {
Mathieu Chartier77aca502019-08-19 13:08:14 -0700476 boolean defaultValue = SystemProperties.getBoolean("dalvik.vm.profilesystemserver",
477 /*default=*/ false);
478 // Can't use DeviceConfig since it's not initialized at this point.
479 return SystemProperties.getBoolean(
480 "persist.device_config." + DeviceConfig.NAMESPACE_RUNTIME_NATIVE_BOOT
481 + ".profilesystemserver",
482 defaultValue);
483 }
484
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800485 /**
486 * Finish remaining work for the newly forked system server process.
487 */
Chris Wailes2be26262019-01-11 16:14:43 -0800488 private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
Mike Lockwood90960e82010-08-06 09:15:25 -0400489 // set umask to 0077 so new files and directories will default to owner-only permissions.
Elliott Hughes860c5912014-04-28 19:19:13 -0700490 Os.umask(S_IRWXG | S_IRWXO);
Mike Lockwood90960e82010-08-06 09:15:25 -0400491
Chris Wailes2be26262019-01-11 16:14:43 -0800492 if (parsedArgs.mNiceName != null) {
493 Process.setArgV0(parsedArgs.mNiceName);
Jeff Brownebed7d62011-05-16 17:08:42 -0700494 }
495
Narayan Kamath29564cd2014-08-07 10:57:40 +0100496 final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
497 if (systemServerClasspath != null) {
Andreas Gampe76b4b2c2019-03-15 11:56:48 -0700498 if (performSystemServerDexOpt(systemServerClasspath)) {
499 // Throw away the cached classloader. If we compiled here, the classloader would
500 // not have had AoT-ed artifacts.
501 // Note: This only works in a very special environment where selinux enforcement is
502 // disabled, e.g., Mac builds.
503 sCachedSystemServerClassLoader = null;
504 }
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -0700505 // Capturing profiles is only supported for debug or eng builds since selinux normally
506 // prevents it.
Mathieu Chartier3b05e4d2019-09-09 13:05:31 -0700507 if (shouldProfileSystemServer() && (Build.IS_USERDEBUG || Build.IS_ENG)) {
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -0700508 try {
Mathieu Chartier77aca502019-08-19 13:08:14 -0700509 Log.d(TAG, "Preparing system server profile");
Calin Juravle3f3a08a2018-05-02 23:39:19 -0700510 prepareSystemServerProfile(systemServerClasspath);
Mathieu Chartierb3eeceb2017-03-30 21:00:18 -0700511 } catch (Exception e) {
512 Log.wtf(TAG, "Failed to set up system server profile", e);
513 }
514 }
Narayan Kamath29564cd2014-08-07 10:57:40 +0100515 }
516
Chris Wailes2be26262019-01-11 16:14:43 -0800517 if (parsedArgs.mInvokeWith != null) {
518 String[] args = parsedArgs.mRemainingArgs;
Narayan Kamath29564cd2014-08-07 10:57:40 +0100519 // If we have a non-null system server class path, we'll have to duplicate the
520 // existing arguments and append the classpath to it. ART will handle the classpath
521 // correctly when we exec a new process.
522 if (systemServerClasspath != null) {
523 String[] amendedArgs = new String[args.length + 2];
524 amendedArgs[0] = "-cp";
525 amendedArgs[1] = systemServerClasspath;
tony.ys_liu34738172016-12-14 18:50:29 +0800526 System.arraycopy(args, 0, amendedArgs, 2, args.length);
527 args = amendedArgs;
Narayan Kamath29564cd2014-08-07 10:57:40 +0100528 }
529
Chris Wailes2be26262019-01-11 16:14:43 -0800530 WrapperInit.execApplication(parsedArgs.mInvokeWith,
531 parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,
Narayan Kamath37ad4b02015-01-19 16:05:24 +0000532 VMRuntime.getCurrentInstructionSet(), null, args);
Narayan Kamathbf99d062017-07-05 14:45:38 +0100533
534 throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");
Jeff Brownebed7d62011-05-16 17:08:42 -0700535 } else {
Andreas Gampe76b4b2c2019-03-15 11:56:48 -0700536 createSystemServerClassLoader();
537 ClassLoader cl = sCachedSystemServerClassLoader;
538 if (cl != null) {
Narayan Kamath29564cd2014-08-07 10:57:40 +0100539 Thread.currentThread().setContextClassLoader(cl);
540 }
541
Jeff Brownebed7d62011-05-16 17:08:42 -0700542 /*
543 * Pass the remaining arguments to SystemServer.
544 */
Chris Wailes2be26262019-01-11 16:14:43 -0800545 return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
546 parsedArgs.mRemainingArgs, cl);
Jeff Brownebed7d62011-05-16 17:08:42 -0700547 }
548
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800549 /* should never reach here */
550 }
551
Calin Juravle3f3a08a2018-05-02 23:39:19 -0700552 /**
Andreas Gampe76b4b2c2019-03-15 11:56:48 -0700553 * Create the classloader for the system server and store it in
554 * {@link sCachedSystemServerClassLoader}. This function may be called through JNI in
555 * system server startup, when the runtime is in a critically low state. Do not do
556 * extended computation etc here.
557 */
558 private static void createSystemServerClassLoader() {
559 if (sCachedSystemServerClassLoader != null) {
560 return;
561 }
562 final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
563 // TODO: Should we run optimization here?
564 if (systemServerClasspath != null) {
565 sCachedSystemServerClassLoader = createPathClassLoader(systemServerClasspath,
566 VMRuntime.SDK_VERSION_CUR_DEVELOPMENT);
567 }
568 }
569
570 /**
Chris Wailes143f7cc2019-01-11 14:30:43 -0800571 * Note that preparing the profiles for system server does not require special selinux
572 * permissions. From the installer perspective the system server is a regular package which can
573 * capture profile information.
Calin Juravle3f3a08a2018-05-02 23:39:19 -0700574 */
575 private static void prepareSystemServerProfile(String systemServerClasspath)
576 throws RemoteException {
577 if (systemServerClasspath.isEmpty()) {
578 return;
579 }
580 String[] codePaths = systemServerClasspath.split(":");
581
582 final IInstalld installd = IInstalld.Stub
583 .asInterface(ServiceManager.getService("installd"));
584
585 String systemServerPackageName = "android";
586 String systemServerProfileName = "primary.prof";
587 installd.prepareAppProfile(
588 systemServerPackageName,
589 UserHandle.USER_SYSTEM,
590 UserHandle.getAppId(Process.SYSTEM_UID),
591 systemServerProfileName,
592 codePaths[0],
593 /*dexMetadata*/ null);
594
595 File profileDir = Environment.getDataProfilesDePackageDirectory(
596 UserHandle.USER_SYSTEM, systemServerPackageName);
597 String profilePath = new File(profileDir, systemServerProfileName).getAbsolutePath();
598 VMRuntime.registerAppInfo(profilePath, codePaths);
599 }
600
Mathew Inwood8faeab82018-03-16 14:26:08 +0000601 public static void setApiBlacklistExemptions(String[] exemptions) {
602 VMRuntime.getRuntime().setHiddenApiExemptions(exemptions);
603 }
604
Mathew Inwood04194fe2018-04-04 14:48:03 +0100605 public static void setHiddenApiAccessLogSampleRate(int percent) {
606 VMRuntime.getRuntime().setHiddenApiAccessLogSamplingRate(percent);
607 }
608
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800609 /**
Andrei Onea6cd1b702019-01-25 16:29:44 +0000610 * Sets the implementation to be used for logging hidden API accesses
611 * @param logger the implementation of the VMRuntime.HiddenApiUsageLogger interface
612 */
613 public static void setHiddenApiUsageLogger(VMRuntime.HiddenApiUsageLogger logger) {
614 VMRuntime.getRuntime().setHiddenApiUsageLogger(logger);
615 }
616
617 /**
tony.ys_liu34738172016-12-14 18:50:29 +0800618 * Creates a PathClassLoader for the given class path that is associated with a shared
619 * namespace, i.e., this classloader can access platform-private native libraries. The
620 * classloader will use java.library.path as the native library path.
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700621 */
Narayan Kamathf9419f02017-06-15 11:35:38 +0100622 static ClassLoader createPathClassLoader(String classPath, int targetSdkVersion) {
623 String libraryPath = System.getProperty("java.library.path");
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700624
Nicolas Geoffray5d1814e2018-12-13 09:27:04 +0000625 // We use the boot class loader, that's what the runtime expects at AOT.
626 ClassLoader parent = ClassLoader.getSystemClassLoader().getParent();
627
Narayan Kamathf9419f02017-06-15 11:35:38 +0100628 return ClassLoaderFactory.createClassLoader(classPath, libraryPath, libraryPath,
Nicolas Geoffray5d1814e2018-12-13 09:27:04 +0000629 parent, targetSdkVersion, true /* isNamespaceShared */, null /* classLoaderName */);
Dimitry Ivanov89dad332016-04-20 16:02:00 -0700630 }
631
632 /**
Chris Wailes143f7cc2019-01-11 14:30:43 -0800633 * Performs dex-opt on the elements of {@code classPath}, if needed. We choose the instruction
Andreas Gampe76b4b2c2019-03-15 11:56:48 -0700634 * set of the current runtime. If something was compiled, return true.
Narayan Kamath29564cd2014-08-07 10:57:40 +0100635 */
Andreas Gampe76b4b2c2019-03-15 11:56:48 -0700636 private static boolean performSystemServerDexOpt(String classPath) {
Narayan Kamath29564cd2014-08-07 10:57:40 +0100637 final String[] classPathElements = classPath.split(":");
Jeff Sharkey740f5232016-12-09 14:31:26 -0700638 final IInstalld installd = IInstalld.Stub
639 .asInterface(ServiceManager.getService("installd"));
Narayan Kamath29564cd2014-08-07 10:57:40 +0100640 final String instructionSet = VMRuntime.getRuntime().vmInstructionSet();
641
Calin Juravle2f09ff32017-07-24 15:29:56 -0700642 String classPathForElement = "";
Andreas Gampe76b4b2c2019-03-15 11:56:48 -0700643 boolean compiledSomething = false;
Jeff Sharkey740f5232016-12-09 14:31:26 -0700644 for (String classPathElement : classPathElements) {
645 // System server is fully AOTed and never profiled
646 // for profile guided compilation.
Mathieu Chartier5e07a0d2017-06-15 19:09:38 -0700647 String systemServerFilter = SystemProperties.get(
648 "dalvik.vm.systemservercompilerfilter", "speed");
Andreas Gampee7bc1522016-08-09 20:44:04 -0700649
Jeff Sharkey740f5232016-12-09 14:31:26 -0700650 int dexoptNeeded;
651 try {
652 dexoptNeeded = DexFile.getDexOptNeeded(
Chris Wailes143f7cc2019-01-11 14:30:43 -0800653 classPathElement, instructionSet, systemServerFilter,
654 null /* classLoaderContext */, false /* newProfile */,
655 false /* downgrade */);
Jeff Sharkey740f5232016-12-09 14:31:26 -0700656 } catch (FileNotFoundException ignored) {
657 // Do not add to the classpath.
658 Log.w(TAG, "Missing classpath element for system server: " + classPathElement);
659 continue;
660 } catch (IOException e) {
661 // Not fully clear what to do here as we don't know the cause of the
662 // IO exception. Add to the classpath to be conservative, but don't
663 // attempt to compile it.
664 Log.w(TAG, "Error checking classpath element for system server: "
665 + classPathElement, e);
666 dexoptNeeded = DexFile.NO_DEXOPT_NEEDED;
Narayan Kamath29564cd2014-08-07 10:57:40 +0100667 }
Jeff Sharkey740f5232016-12-09 14:31:26 -0700668
669 if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
670 final String packageName = "*";
671 final String outputPath = null;
David Brazdilf7e31c02018-02-13 17:04:26 +0000672 final int dexFlags = 0;
Mathieu Chartier5e07a0d2017-06-15 19:09:38 -0700673 final String compilerFilter = systemServerFilter;
Jeff Sharkey740f5232016-12-09 14:31:26 -0700674 final String uuid = StorageManager.UUID_PRIVATE_INTERNAL;
Calin Juravle811a75a2017-04-05 22:49:38 -0700675 final String seInfo = null;
Calin Juravle2f09ff32017-07-24 15:29:56 -0700676 final String classLoaderContext =
677 getSystemServerClassLoaderContext(classPathForElement);
David Brazdil3d44ed02018-01-16 20:01:47 +0000678 final int targetSdkVersion = 0; // SystemServer targets the system's SDK version
Jeff Sharkey740f5232016-12-09 14:31:26 -0700679 try {
680 installd.dexopt(classPathElement, Process.SYSTEM_UID, packageName,
681 instructionSet, dexoptNeeded, outputPath, dexFlags, compilerFilter,
David Brazdil3d44ed02018-01-16 20:01:47 +0000682 uuid, classLoaderContext, seInfo, false /* downgrade */,
Calin Juravle4bc8f4d2018-02-12 12:00:44 -0800683 targetSdkVersion, /*profileName*/ null, /*dexMetadataPath*/ null,
684 "server-dexopt");
Andreas Gampe76b4b2c2019-03-15 11:56:48 -0700685 compiledSomething = true;
Jeff Sharkey740f5232016-12-09 14:31:26 -0700686 } catch (RemoteException | ServiceSpecificException e) {
687 // Ignore (but log), we need this on the classpath for fallback mode.
688 Log.w(TAG, "Failed compiling classpath element for system server: "
689 + classPathElement, e);
690 }
691 }
692
Calin Juravle2f09ff32017-07-24 15:29:56 -0700693 classPathForElement = encodeSystemServerClassPath(
694 classPathForElement, classPathElement);
Narayan Kamath29564cd2014-08-07 10:57:40 +0100695 }
Andreas Gampe76b4b2c2019-03-15 11:56:48 -0700696
697 return compiledSomething;
Narayan Kamath29564cd2014-08-07 10:57:40 +0100698 }
699
700 /**
Chris Wailes143f7cc2019-01-11 14:30:43 -0800701 * Encodes the system server class loader context in a format that is accepted by dexopt. This
702 * assumes the system server is always loaded with a {@link dalvik.system.PathClassLoader}.
Calin Juravle2f09ff32017-07-24 15:29:56 -0700703 *
704 * Note that ideally we would use the {@code DexoptUtils} to compute this. However we have no
705 * dependency here on the server so we hard code the logic again.
706 */
707 private static String getSystemServerClassLoaderContext(String classPath) {
708 return classPath == null ? "PCL[]" : "PCL[" + classPath + "]";
709 }
710
711 /**
712 * Encodes the class path in a format accepted by dexopt.
Chris Wailes143f7cc2019-01-11 14:30:43 -0800713 *
714 * @param classPath The old class path (may be empty).
715 * @param newElement The new class path elements
716 * @return The class path encoding resulted from appending {@code newElement} to {@code
717 * classPath}.
Calin Juravle2f09ff32017-07-24 15:29:56 -0700718 */
719 private static String encodeSystemServerClassPath(String classPath, String newElement) {
720 return (classPath == null || classPath.isEmpty())
721 ? newElement
722 : classPath + ":" + newElement;
723 }
724
725 /**
Narayan Kamathbf99d062017-07-05 14:45:38 +0100726 * Prepare the arguments and forks for the system server process.
727 *
Chris Wailes143f7cc2019-01-11 14:30:43 -0800728 * @return A {@code Runnable} that provides an entrypoint into system_server code in the child
729 * process; {@code null} in the parent.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800730 */
Narayan Kamathbf99d062017-07-05 14:45:38 +0100731 private static Runnable forkSystemServer(String abiList, String socketName,
732 ZygoteServer zygoteServer) {
Alex Klyubin48a06e72013-04-19 10:01:42 -0700733 long capabilities = posixCapabilitiesAsBits(
Chris Wailes143f7cc2019-01-11 14:30:43 -0800734 OsConstants.CAP_IPC_LOCK,
735 OsConstants.CAP_KILL,
736 OsConstants.CAP_NET_ADMIN,
737 OsConstants.CAP_NET_BIND_SERVICE,
738 OsConstants.CAP_NET_BROADCAST,
739 OsConstants.CAP_NET_RAW,
740 OsConstants.CAP_SYS_MODULE,
741 OsConstants.CAP_SYS_NICE,
742 OsConstants.CAP_SYS_PTRACE,
743 OsConstants.CAP_SYS_TIME,
744 OsConstants.CAP_SYS_TTY_CONFIG,
745 OsConstants.CAP_WAKE_ALARM,
746 OsConstants.CAP_BLOCK_SUSPEND
Alex Klyubin48a06e72013-04-19 10:01:42 -0700747 );
Luis Hector Chavez72042c92017-07-12 10:03:30 -0700748 /* Containers run without some capabilities, so drop any caps that are not available. */
749 StructCapUserHeader header = new StructCapUserHeader(
750 OsConstants._LINUX_CAPABILITY_VERSION_3, 0);
751 StructCapUserData[] data;
752 try {
753 data = Os.capget(header);
754 } catch (ErrnoException ex) {
755 throw new RuntimeException("Failed to capget()", ex);
Luis Hector Chavez5dd239a2015-10-06 14:01:45 -0700756 }
Luis Hector Chavez72042c92017-07-12 10:03:30 -0700757 capabilities &= ((long) data[0].effective) | (((long) data[1].effective) << 32);
758
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800759 /* Hardcoded command line to start the system server */
760 String args[] = {
Chris Wailes143f7cc2019-01-11 14:30:43 -0800761 "--setuid=1000",
762 "--setgid=1000",
763 "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,"
Siarhei Vishniakouc0216a12019-08-23 13:21:32 +0100764 + "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010,3011",
Chris Wailes143f7cc2019-01-11 14:30:43 -0800765 "--capabilities=" + capabilities + "," + capabilities,
766 "--nice-name=system_server",
767 "--runtime-args",
768 "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
769 "com.android.server.SystemServer",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800770 };
Chris Wailes2be26262019-01-11 16:14:43 -0800771 ZygoteArguments parsedArgs = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800772
773 int pid;
774
775 try {
Chris Wailes2be26262019-01-11 16:14:43 -0800776 parsedArgs = new ZygoteArguments(args);
777 Zygote.applyDebuggerSystemProperty(parsedArgs);
778 Zygote.applyInvokeWithSystemProperty(parsedArgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800779
Mathieu Chartier3b05e4d2019-09-09 13:05:31 -0700780 if (shouldProfileSystemServer()) {
Chris Wailes2be26262019-01-11 16:14:43 -0800781 parsedArgs.mRuntimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
Calin Juravle8eb891b2018-05-03 19:51:18 -0700782 }
783
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800784 /* Request to fork the system server process */
785 pid = Zygote.forkSystemServer(
Chris Wailes2be26262019-01-11 16:14:43 -0800786 parsedArgs.mUid, parsedArgs.mGid,
787 parsedArgs.mGids,
788 parsedArgs.mRuntimeFlags,
Elliott Hughese1dfcb72011-07-08 11:08:07 -0700789 null,
Chris Wailes2be26262019-01-11 16:14:43 -0800790 parsedArgs.mPermittedCapabilities,
791 parsedArgs.mEffectiveCapabilities);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800792 } catch (IllegalArgumentException ex) {
793 throw new RuntimeException(ex);
Bob Leee5408332009-09-04 18:31:17 -0700794 }
795
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800796 /* For child process */
797 if (pid == 0) {
Narayan Kamath64cd9072014-05-13 13:35:14 +0100798 if (hasSecondZygote(abiList)) {
799 waitForSecondaryZygote(socketName);
800 }
801
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000802 zygoteServer.closeServerSocket();
Narayan Kamathbf99d062017-07-05 14:45:38 +0100803 return handleSystemServerProcess(parsedArgs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800804 }
805
Narayan Kamathbf99d062017-07-05 14:45:38 +0100806 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800807 }
808
Alex Klyubin48a06e72013-04-19 10:01:42 -0700809 /**
810 * Gets the bit array representation of the provided list of POSIX capabilities.
811 */
812 private static long posixCapabilitiesAsBits(int... capabilities) {
813 long result = 0;
814 for (int capability : capabilities) {
815 if ((capability < 0) || (capability > OsConstants.CAP_LAST_CAP)) {
816 throw new IllegalArgumentException(String.valueOf(capability));
817 }
818 result |= (1L << capability);
819 }
820 return result;
821 }
822
Andrei Onea15884392019-03-22 17:28:11 +0000823 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800824 public static void main(String argv[]) {
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800825 ZygoteServer zygoteServer = null;
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000826
Andreas Gampe1ef8aef2016-04-11 08:39:52 -0700827 // Mark zygote start. This ensures that thread creation will throw
828 // an error.
829 ZygoteHooks.startZygoteNoThreadCreation();
830
Robert Seseke4f8d692016-09-13 19:13:01 -0400831 // Zygote goes into its own process group.
832 try {
833 Os.setpgid(0, 0);
834 } catch (ErrnoException ex) {
835 throw new RuntimeException("Failed to setpgid(0,0)", ex);
836 }
837
Chris Wailesba4c2eb2019-01-11 17:13:00 -0800838 Runnable caller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800839 try {
Fyodor Kupolov6733e6c2017-01-06 18:27:05 -0800840 // Report Zygote start time to tron unless it is a runtime restart
841 if (!"1".equals(SystemProperties.get("sys.boot_completed"))) {
842 MetricsLogger.histogram(null, "boot_zygote_init",
843 (int) SystemClock.elapsedRealtime());
844 }
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800845
846 String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
Fyodor Kupolov6e3461b2017-08-10 17:00:43 -0700847 TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag,
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800848 Trace.TRACE_TAG_DALVIK);
849 bootTimingsTraceLog.traceBegin("ZygoteInit");
Tobias Thierera45917e2019-09-26 16:03:28 +0100850 RuntimeInit.preForkInit();
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900851
Narayan Kamathc41638c2014-04-07 13:56:15 +0100852 boolean startSystemServer = false;
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800853 String zygoteSocketName = "zygote";
Narayan Kamathc41638c2014-04-07 13:56:15 +0100854 String abiList = null;
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000855 boolean enableLazyPreload = false;
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900856 for (int i = 1; i < argv.length; i++) {
857 if ("start-system-server".equals(argv[i])) {
858 startSystemServer = true;
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000859 } else if ("--enable-lazy-preload".equals(argv[i])) {
860 enableLazyPreload = true;
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900861 } else if (argv[i].startsWith(ABI_LIST_ARG)) {
862 abiList = argv[i].substring(ABI_LIST_ARG.length());
863 } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800864 zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900865 } else {
866 throw new RuntimeException("Unknown command line argument: " + argv[i]);
Narayan Kamathc41638c2014-04-07 13:56:15 +0100867 }
868 }
869
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800870 final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME);
871
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900872 if (abiList == null) {
873 throw new RuntimeException("No ABI list supplied.");
874 }
875
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000876 // In some configurations, we avoid preloading resources and classes eagerly.
877 // In such cases, we will preload things prior to our first fork.
878 if (!enableLazyPreload) {
879 bootTimingsTraceLog.traceBegin("ZygotePreload");
880 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
Chris Wailes143f7cc2019-01-11 14:30:43 -0800881 SystemClock.uptimeMillis());
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000882 preload(bootTimingsTraceLog);
883 EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
Chris Wailes143f7cc2019-01-11 14:30:43 -0800884 SystemClock.uptimeMillis());
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000885 bootTimingsTraceLog.traceEnd(); // ZygotePreload
Mathew Inwood3e68de12019-05-24 14:06:10 +0100886 } else {
887 Zygote.resetNicePriority();
Narayan Kamath5a3d0c62016-11-09 15:35:18 +0000888 }
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900889
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900890 // Do an initial gc to clean up after startup
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800891 bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900892 gcAndFinalize();
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800893 bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC
Yasuhiro Matsuda25878b22015-09-03 16:18:21 +0900894
Fyodor Kupolov3235e0c2016-11-17 11:44:49 -0800895 bootTimingsTraceLog.traceEnd(); // ZygoteInit
Jamie Gennis6ad04522013-04-15 18:53:24 -0700896 // Disable tracing so that forked processes do not inherit stale tracing tags from
897 // Zygote.
John Reck62cc1192017-05-12 15:39:51 -0700898 Trace.setTracingEnabled(false, 0);
Jamie Gennis6ad04522013-04-15 18:53:24 -0700899
Victor Hsiehc8176ef2018-01-08 12:43:00 -0800900
Chris Wailes6d482d542019-04-03 13:00:52 -0700901 Zygote.initNativeState(isPrimaryZygote);
doheon1.lee885b7422016-01-20 13:07:27 +0900902
Andreas Gampe1ef8aef2016-04-11 08:39:52 -0700903 ZygoteHooks.stopZygoteNoThreadCreation();
904
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800905 zygoteServer = new ZygoteServer(isPrimaryZygote);
906
Narayan Kamathc41638c2014-04-07 13:56:15 +0100907 if (startSystemServer) {
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800908 Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
Narayan Kamathbf99d062017-07-05 14:45:38 +0100909
910 // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
911 // child (system_server) process.
912 if (r != null) {
913 r.run();
914 return;
915 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800916 }
917
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800918 Log.i(TAG, "Accepting command socket connections");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800919
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800920 // The select loop returns early in the child process after a fork and
921 // loops forever in the zygote.
922 caller = zygoteServer.runSelectLoop(abiList);
Christopher Ferrisea8b5de2016-06-17 15:29:58 -0700923 } catch (Throwable ex) {
Tobias Sargeantdd4bb312016-01-19 16:34:54 +0000924 Log.e(TAG, "System zygote died with exception", ex);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800925 throw ex;
Narayan Kamathbf99d062017-07-05 14:45:38 +0100926 } finally {
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800927 if (zygoteServer != null) {
928 zygoteServer.closeServerSocket();
929 }
Narayan Kamathbf99d062017-07-05 14:45:38 +0100930 }
931
932 // We're in the child process and have exited the select loop. Proceed to execute the
933 // command.
934 if (caller != null) {
935 caller.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800936 }
937 }
938
939 /**
Narayan Kamath64cd9072014-05-13 13:35:14 +0100940 * Return {@code true} if this device configuration has another zygote.
941 *
Chris Wailes143f7cc2019-01-11 14:30:43 -0800942 * We determine this by comparing the device ABI list with this zygotes list. If this zygote
943 * supports all ABIs this device supports, there won't be another zygote.
Narayan Kamath64cd9072014-05-13 13:35:14 +0100944 */
945 private static boolean hasSecondZygote(String abiList) {
946 return !SystemProperties.get("ro.product.cpu.abilist").equals(abiList);
947 }
948
949 private static void waitForSecondaryZygote(String socketName) {
Mathieu Chartier0bccbf72019-01-30 15:56:17 -0800950 String otherZygoteName = Zygote.PRIMARY_SOCKET_NAME.equals(socketName)
951 ? Zygote.SECONDARY_SOCKET_NAME : Zygote.PRIMARY_SOCKET_NAME;
Gustav Senntonf0c52b52017-04-27 17:00:50 +0100952 ZygoteProcess.waitForConnectionToZygote(otherZygoteName);
Narayan Kamath64cd9072014-05-13 13:35:14 +0100953 }
954
Narayan Kamath669afcc2017-02-06 20:24:08 +0000955 static boolean isPreloadComplete() {
956 return sPreloadComplete;
957 }
958
Narayan Kamath64cd9072014-05-13 13:35:14 +0100959 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800960 * Class not instantiable.
961 */
962 private ZygoteInit() {
963 }
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800964
965 /**
Chris Wailes143f7cc2019-01-11 14:30:43 -0800966 * The main function called when started through the zygote process. This could be unified with
967 * main(), if the native code in nativeFinishInit() were rationalized with Zygote startup.<p>
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800968 *
969 * Current recognized args:
970 * <ul>
971 * <li> <code> [--] &lt;start class name&gt; &lt;args&gt;
972 * </ul>
973 *
974 * @param targetSdkVersion target SDK version
975 * @param argv arg strings
976 */
Chris Wailes143f7cc2019-01-11 14:30:43 -0800977 public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
978 ClassLoader classLoader) {
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800979 if (RuntimeInit.DEBUG) {
980 Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
981 }
982
983 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
984 RuntimeInit.redirectLogStreams();
985
986 RuntimeInit.commonInit();
987 ZygoteInit.nativeZygoteInit();
Narayan Kamathbf99d062017-07-05 14:45:38 +0100988 return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
Andreas Gampe76d4fc82017-02-07 19:44:37 -0800989 }
990
Robert Sesekd0a190df2018-02-12 18:46:01 -0500991 /**
Chris Wailes143f7cc2019-01-11 14:30:43 -0800992 * The main function called when starting a child zygote process. This is used as an alternative
993 * to zygoteInit(), which skips calling into initialization routines that start the Binder
994 * threadpool.
Robert Sesekd0a190df2018-02-12 18:46:01 -0500995 */
996 static final Runnable childZygoteInit(
997 int targetSdkVersion, String[] argv, ClassLoader classLoader) {
998 RuntimeInit.Arguments args = new RuntimeInit.Arguments(argv);
999 return RuntimeInit.findStaticMain(args.startClass, args.startArgs, classLoader);
1000 }
1001
Andreas Gampe76d4fc82017-02-07 19:44:37 -08001002 private static final native void nativeZygoteInit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001003}