blob: db8c905eac34dbed978fef77239b1859126e3f07 [file] [log] [blame]
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001/*
2 * Copyright (C) 2010 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 android.app;
18
Adam Lesinskid33ef562017-01-19 14:49:59 -080019import android.annotation.NonNull;
20import android.annotation.Nullable;
Mathew Inwood61e8ae62018-08-14 14:17:44 +010021import android.annotation.UnsupportedAppUsage;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070022import android.content.BroadcastReceiver;
23import android.content.ComponentName;
24import android.content.Context;
25import android.content.IIntentReceiver;
26import android.content.Intent;
27import android.content.ServiceConnection;
28import android.content.pm.ApplicationInfo;
29import android.content.pm.IPackageManager;
30import android.content.pm.PackageManager;
Adam Lesinski1665d0f2017-03-10 14:46:57 -080031import android.content.pm.PackageManager.NameNotFoundException;
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +000032import android.content.pm.SharedLibraryInfo;
Calin Juravle6ae39fc2018-01-19 20:32:47 -080033import android.content.pm.dex.ArtManager;
Adam Lesinski1665d0f2017-03-10 14:46:57 -080034import android.content.pm.split.SplitDependencyLoader;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070035import android.content.res.AssetManager;
36import android.content.res.CompatibilityInfo;
37import android.content.res.Resources;
Adam Lesinski4e862812016-11-21 16:02:24 -080038import android.os.Build;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070039import android.os.Bundle;
Jeff Sharkey15447792015-11-05 16:18:51 -080040import android.os.FileUtils;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070041import android.os.Handler;
42import android.os.IBinder;
43import android.os.Process;
44import android.os.RemoteException;
Brad Fitzpatrick624d50f2010-11-09 14:25:12 -080045import android.os.StrictMode;
Jeff Sharkey8a372a02016-03-16 16:25:45 -060046import android.os.SystemProperties;
Dianne Hackborn1ded0b12012-04-26 14:14:50 -070047import android.os.Trace;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070048import android.os.UserHandle;
Jeff Sharkey8a372a02016-03-16 16:25:45 -060049import android.text.TextUtils;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070050import android.util.AndroidRuntimeException;
Jeff Sharkey8a372a02016-03-16 16:25:45 -060051import android.util.ArrayMap;
Adam Lesinski2cb761e2014-08-15 13:59:02 -070052import android.util.Log;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070053import android.util.Slog;
Adam Lesinskide898ff2014-01-29 18:20:45 -080054import android.util.SparseArray;
Jeff Browna492c3a2012-08-23 19:48:44 -070055import android.view.Display;
Jeff Sharkey8a372a02016-03-16 16:25:45 -060056import android.view.DisplayAdjustments;
Calin Juravle6ae39fc2018-01-19 20:32:47 -080057
Adam Lesinski4e862812016-11-21 16:02:24 -080058import com.android.internal.util.ArrayUtils;
Calin Juravle6ae39fc2018-01-19 20:32:47 -080059
David Brazdil991ff902018-12-03 10:59:29 +000060import dalvik.system.BaseDexClassLoader;
Narayan Kamath7dba6eb2014-07-16 08:53:30 +010061import dalvik.system.VMRuntime;
Calin Juravle6ae39fc2018-01-19 20:32:47 -080062
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070063import java.io.File;
64import java.io.IOException;
65import java.io.InputStream;
66import java.lang.ref.WeakReference;
Adam Lesinski1e4663852014-08-15 14:47:28 -070067import java.lang.reflect.InvocationTargetException;
68import java.lang.reflect.Method;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070069import java.net.URL;
Jiyong Park29d9eba2018-05-04 12:44:38 +090070import java.nio.file.Paths;
Jeff Sharkey8a4c9722014-06-16 13:48:42 -070071import java.util.ArrayList;
Adam Lesinski4e862812016-11-21 16:02:24 -080072import java.util.Arrays;
Jeff Sharkey8a4c9722014-06-16 13:48:42 -070073import java.util.Collections;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070074import java.util.Enumeration;
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +000075import java.util.LinkedHashSet;
Jeff Sharkey8a372a02016-03-16 16:25:45 -060076import java.util.List;
Narayan Kamath20531682014-07-14 13:18:43 +010077import java.util.Objects;
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +000078import java.util.Set;
Bo Liu58a57662019-03-06 20:21:45 +000079import java.util.concurrent.Executor;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070080
81final class IntentReceiverLeaked extends AndroidRuntimeException {
Mathew Inwood61e8ae62018-08-14 14:17:44 +010082 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070083 public IntentReceiverLeaked(String msg) {
84 super(msg);
85 }
86}
87
88final class ServiceConnectionLeaked extends AndroidRuntimeException {
Mathew Inwood61e8ae62018-08-14 14:17:44 +010089 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070090 public ServiceConnectionLeaked(String msg) {
91 super(msg);
92 }
93}
94
95/**
96 * Local state maintained about a currently loaded .apk.
97 * @hide
98 */
Dianne Hackborn5fd21692011-06-07 14:09:47 -070099public final class LoadedApk {
Dianne Hackborn94846032017-03-31 17:55:23 -0700100 static final String TAG = "LoadedApk";
101 static final boolean DEBUG = false;
Patrick Baumann1bea2372018-03-13 14:26:58 -0700102 private static final String PROPERTY_NAME_APPEND_NATIVE = "pi.append_native_lib_paths";
Amith Yamasani742a6712011-05-04 14:49:28 -0700103
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100104 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700105 private final ActivityThread mActivityThread;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100106 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700107 final String mPackageName;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100108 @UnsupportedAppUsage
Todd Kennedy39bfee52016-02-24 10:28:21 -0800109 private ApplicationInfo mApplicationInfo;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100110 @UnsupportedAppUsage
Todd Kennedy39bfee52016-02-24 10:28:21 -0800111 private String mAppDir;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100112 @UnsupportedAppUsage
Todd Kennedy39bfee52016-02-24 10:28:21 -0800113 private String mResDir;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800114 private String[] mOverlayDirs;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100115 @UnsupportedAppUsage
Todd Kennedy39bfee52016-02-24 10:28:21 -0800116 private String mDataDir;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100117 @UnsupportedAppUsage
Todd Kennedy39bfee52016-02-24 10:28:21 -0800118 private String mLibDir;
Mathew Inwood8c854f82018-09-14 12:35:36 +0100119 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Todd Kennedy39bfee52016-02-24 10:28:21 -0800120 private File mDataDirFile;
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600121 private File mDeviceProtectedDataDirFile;
122 private File mCredentialProtectedDataDirFile;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100123 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700124 private final ClassLoader mBaseClassLoader;
David Brazdilfd6dcc22018-10-25 14:07:51 +0100125 private ClassLoader mDefaultClassLoader;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700126 private final boolean mSecurityViolation;
127 private final boolean mIncludeCode;
Dianne Hackbornfee756f2014-07-16 17:31:10 -0700128 private final boolean mRegisterPackage;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100129 @UnsupportedAppUsage
Craig Mautner48d0d182013-06-11 07:53:06 -0700130 private final DisplayAdjustments mDisplayAdjustments = new DisplayAdjustments();
Todd Kennedy39bfee52016-02-24 10:28:21 -0800131 /** WARNING: This may change. Don't hold external references to it. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100132 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700133 Resources mResources;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100134 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700135 private ClassLoader mClassLoader;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100136 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700137 private Application mApplication;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700138
Adam Lesinski4e862812016-11-21 16:02:24 -0800139 private String[] mSplitNames;
140 private String[] mSplitAppDirs;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100141 @UnsupportedAppUsage
Adam Lesinski4e862812016-11-21 16:02:24 -0800142 private String[] mSplitResDirs;
Narayan Kamathf9419f02017-06-15 11:35:38 +0100143 private String[] mSplitClassLoaderNames;
Adam Lesinski4e862812016-11-21 16:02:24 -0800144
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100145 @UnsupportedAppUsage
Dianne Hackbornadd005c2013-07-17 18:43:12 -0700146 private final ArrayMap<Context, ArrayMap<BroadcastReceiver, ReceiverDispatcher>> mReceivers
Adam Lesinski4e862812016-11-21 16:02:24 -0800147 = new ArrayMap<>();
Dianne Hackbornadd005c2013-07-17 18:43:12 -0700148 private final ArrayMap<Context, ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>> mUnregisteredReceivers
Adam Lesinski4e862812016-11-21 16:02:24 -0800149 = new ArrayMap<>();
Mathew Inwood8c854f82018-09-14 12:35:36 +0100150 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Dianne Hackbornadd005c2013-07-17 18:43:12 -0700151 private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mServices
Adam Lesinski4e862812016-11-21 16:02:24 -0800152 = new ArrayMap<>();
Dianne Hackbornadd005c2013-07-17 18:43:12 -0700153 private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mUnboundServices
Adam Lesinski4e862812016-11-21 16:02:24 -0800154 = new ArrayMap<>();
Jason Monka80bfb52017-11-16 17:15:37 -0500155 private AppComponentFactory mAppComponentFactory;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700156
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700157 Application getApplication() {
158 return mApplication;
159 }
160
Dianne Hackborn2f0b1752011-05-31 17:59:49 -0700161 /**
162 * Create information about a new .apk
163 *
164 * NOTE: This constructor is called with ActivityThread's lock held,
165 * so MUST NOT call back out to the activity manager.
166 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700167 public LoadedApk(ActivityThread activityThread, ApplicationInfo aInfo,
Jeff Browndefd4a62014-03-10 21:24:37 -0700168 CompatibilityInfo compatInfo, ClassLoader baseLoader,
Dianne Hackbornfee756f2014-07-16 17:31:10 -0700169 boolean securityViolation, boolean includeCode, boolean registerPackage) {
Narayan Kamath7dba6eb2014-07-16 08:53:30 +0100170
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700171 mActivityThread = activityThread;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800172 setApplicationInfo(aInfo);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700173 mPackageName = aInfo.packageName;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700174 mBaseClassLoader = baseLoader;
175 mSecurityViolation = securityViolation;
176 mIncludeCode = includeCode;
Dianne Hackbornfee756f2014-07-16 17:31:10 -0700177 mRegisterPackage = registerPackage;
Craig Mautner48d0d182013-06-11 07:53:06 -0700178 mDisplayAdjustments.setCompatibilityInfo(compatInfo);
Jason Monka80bfb52017-11-16 17:15:37 -0500179 mAppComponentFactory = createAppFactory(mApplicationInfo, mBaseClassLoader);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700180 }
181
Narayan Kamath7dba6eb2014-07-16 08:53:30 +0100182 private static ApplicationInfo adjustNativeLibraryPaths(ApplicationInfo info) {
183 // If we're dealing with a multi-arch application that has both
184 // 32 and 64 bit shared libraries, we might need to choose the secondary
185 // depending on what the current runtime's instruction set is.
186 if (info.primaryCpuAbi != null && info.secondaryCpuAbi != null) {
187 final String runtimeIsa = VMRuntime.getRuntime().vmInstructionSet();
jgu214741cd92014-12-17 17:23:29 -0500188
189 // Get the instruction set that the libraries of secondary Abi is supported.
190 // In presence of a native bridge this might be different than the one secondary Abi used.
191 String secondaryIsa = VMRuntime.getInstructionSet(info.secondaryCpuAbi);
192 final String secondaryDexCodeIsa = SystemProperties.get("ro.dalvik.vm.isa." + secondaryIsa);
193 secondaryIsa = secondaryDexCodeIsa.isEmpty() ? secondaryIsa : secondaryDexCodeIsa;
Narayan Kamath7dba6eb2014-07-16 08:53:30 +0100194
195 // If the runtimeIsa is the same as the primary isa, then we do nothing.
196 // Everything will be set up correctly because info.nativeLibraryDir will
197 // correspond to the right ISA.
198 if (runtimeIsa.equals(secondaryIsa)) {
199 final ApplicationInfo modified = new ApplicationInfo(info);
200 modified.nativeLibraryDir = modified.secondaryNativeLibraryDir;
Dmitriy Ivanove56b3f62015-06-05 22:00:13 -0700201 modified.primaryCpuAbi = modified.secondaryCpuAbi;
Narayan Kamath7dba6eb2014-07-16 08:53:30 +0100202 return modified;
203 }
204 }
205
206 return info;
207 }
208
Jeff Browndefd4a62014-03-10 21:24:37 -0700209 /**
210 * Create information about the system package.
211 * Must call {@link #installSystemApplicationInfo} later.
212 */
213 LoadedApk(ActivityThread activityThread) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700214 mActivityThread = activityThread;
Jeff Browndefd4a62014-03-10 21:24:37 -0700215 mApplicationInfo = new ApplicationInfo();
216 mApplicationInfo.packageName = "android";
217 mPackageName = "android";
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700218 mAppDir = null;
219 mResDir = null;
Jeff Sharkey8a4c9722014-06-16 13:48:42 -0700220 mSplitAppDirs = null;
221 mSplitResDirs = null;
Narayan Kamathf9419f02017-06-15 11:35:38 +0100222 mSplitClassLoaderNames = null;
MÃ¥rten Kongstad48d22322014-01-31 14:43:27 +0100223 mOverlayDirs = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700224 mDataDir = null;
225 mDataDirFile = null;
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600226 mDeviceProtectedDataDirFile = null;
227 mCredentialProtectedDataDirFile = null;
Kenny Root85387d72010-08-26 10:13:11 -0700228 mLibDir = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700229 mBaseClassLoader = null;
230 mSecurityViolation = false;
231 mIncludeCode = true;
Dianne Hackbornfee756f2014-07-16 17:31:10 -0700232 mRegisterPackage = false;
Jeff Browndefd4a62014-03-10 21:24:37 -0700233 mResources = Resources.getSystem();
David Brazdilfd6dcc22018-10-25 14:07:51 +0100234 mDefaultClassLoader = ClassLoader.getSystemClassLoader();
235 mAppComponentFactory = createAppFactory(mApplicationInfo, mDefaultClassLoader);
David Brazdil33bd3432019-02-27 20:15:18 +0000236 mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader,
237 new ApplicationInfo(mApplicationInfo));
Jeff Browndefd4a62014-03-10 21:24:37 -0700238 }
239
240 /**
241 * Sets application info about the system package.
242 */
Narayan Kamath29564cd2014-08-07 10:57:40 +0100243 void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
Jeff Browndefd4a62014-03-10 21:24:37 -0700244 assert info.packageName.equals("android");
245 mApplicationInfo = info;
David Brazdilfd6dcc22018-10-25 14:07:51 +0100246 mDefaultClassLoader = classLoader;
247 mAppComponentFactory = createAppFactory(info, mDefaultClassLoader);
David Brazdil33bd3432019-02-27 20:15:18 +0000248 mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader,
249 new ApplicationInfo(mApplicationInfo));
Jason Monka80bfb52017-11-16 17:15:37 -0500250 }
251
252 private AppComponentFactory createAppFactory(ApplicationInfo appInfo, ClassLoader cl) {
Jason Monk6ee51bb2018-03-02 11:20:31 -0500253 if (appInfo.appComponentFactory != null && cl != null) {
Jason Monka80bfb52017-11-16 17:15:37 -0500254 try {
David Brazdil33bd3432019-02-27 20:15:18 +0000255 return (AppComponentFactory)
256 cl.loadClass(appInfo.appComponentFactory).newInstance();
Jason Monka80bfb52017-11-16 17:15:37 -0500257 } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
258 Slog.e(TAG, "Unable to instantiate appComponentFactory", e);
259 }
260 }
261 return AppComponentFactory.DEFAULT;
262 }
263
264 public AppComponentFactory getAppFactory() {
265 return mAppComponentFactory;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700266 }
267
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100268 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700269 public String getPackageName() {
270 return mPackageName;
271 }
272
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100273 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700274 public ApplicationInfo getApplicationInfo() {
275 return mApplicationInfo;
276 }
277
Jeff Sharkey369f5092016-02-29 11:16:21 -0700278 public int getTargetSdkVersion() {
279 return mApplicationInfo.targetSdkVersion;
280 }
281
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700282 public boolean isSecurityViolation() {
283 return mSecurityViolation;
284 }
285
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100286 @UnsupportedAppUsage
Craig Mautner48d0d182013-06-11 07:53:06 -0700287 public CompatibilityInfo getCompatibilityInfo() {
288 return mDisplayAdjustments.getCompatibilityInfo();
289 }
290
291 public void setCompatibilityInfo(CompatibilityInfo compatInfo) {
292 mDisplayAdjustments.setCompatibilityInfo(compatInfo);
293 }
294
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700295 /**
296 * Gets the array of shared libraries that are listed as
297 * used by the given package.
298 *
299 * @param packageName the name of the package (note: not its
300 * file name)
301 * @return null-ok; the array of shared libraries, each one
302 * a fully-qualified path
303 */
304 private static String[] getLibrariesFor(String packageName) {
305 ApplicationInfo ai = null;
306 try {
307 ai = ActivityThread.getPackageManager().getApplicationInfo(packageName,
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700308 PackageManager.GET_SHARED_LIBRARY_FILES, UserHandle.myUserId());
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700309 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700310 throw e.rethrowFromSystemServer();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700311 }
312
313 if (ai == null) {
314 return null;
315 }
316
317 return ai.sharedLibraryFiles;
318 }
319
Adam Lesinskid33ef562017-01-19 14:49:59 -0800320 /**
321 * Update the ApplicationInfo for an app. If oldPaths is null, all the paths are considered
322 * new.
323 * @param aInfo The new ApplicationInfo to use for this LoadedApk
324 * @param oldPaths The code paths for the old ApplicationInfo object. null means no paths can
325 * be reused.
326 */
327 public void updateApplicationInfo(@NonNull ApplicationInfo aInfo,
328 @Nullable List<String> oldPaths) {
Todd Kennedy39bfee52016-02-24 10:28:21 -0800329 setApplicationInfo(aInfo);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700330
Todd Kennedy39bfee52016-02-24 10:28:21 -0800331 final List<String> newPaths = new ArrayList<>();
Dimitry Ivanov638d8102017-02-22 15:39:42 -0800332 makePaths(mActivityThread, aInfo, newPaths);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800333 final List<String> addedPaths = new ArrayList<>(newPaths.size());
334
335 if (oldPaths != null) {
336 for (String path : newPaths) {
337 final String apkName = path.substring(path.lastIndexOf(File.separator));
338 boolean match = false;
339 for (String oldPath : oldPaths) {
Adam Lesinskia5ca6242017-03-01 15:45:12 -0800340 final String oldApkName = oldPath.substring(oldPath.lastIndexOf(File.separator));
Todd Kennedy39bfee52016-02-24 10:28:21 -0800341 if (apkName.equals(oldApkName)) {
342 match = true;
343 break;
344 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700345 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800346 if (!match) {
347 addedPaths.add(path);
348 }
349 }
350 } else {
351 addedPaths.addAll(newPaths);
352 }
353 synchronized (this) {
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700354 createOrUpdateClassLoaderLocked(addedPaths);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800355 if (mResources != null) {
Adam Lesinski4e862812016-11-21 16:02:24 -0800356 final String[] splitPaths;
357 try {
358 splitPaths = getSplitPaths(null);
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800359 } catch (NameNotFoundException e) {
Adam Lesinski4e862812016-11-21 16:02:24 -0800360 // This should NEVER fail.
361 throw new AssertionError("null split not found");
362 }
363
364 mResources = ResourcesManager.getInstance().getResources(null, mResDir,
Adam Lesinski0e618832017-02-07 11:40:12 -0800365 splitPaths, mOverlayDirs, mApplicationInfo.sharedLibraryFiles,
Adam Lesinski4e862812016-11-21 16:02:24 -0800366 Display.DEFAULT_DISPLAY, null, getCompatibilityInfo(),
367 getClassLoader());
Todd Kennedy39bfee52016-02-24 10:28:21 -0800368 }
369 }
David Brazdilfd6dcc22018-10-25 14:07:51 +0100370 mAppComponentFactory = createAppFactory(aInfo, mDefaultClassLoader);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800371 }
372
373 private void setApplicationInfo(ApplicationInfo aInfo) {
374 final int myUid = Process.myUid();
375 aInfo = adjustNativeLibraryPaths(aInfo);
376 mApplicationInfo = aInfo;
377 mAppDir = aInfo.sourceDir;
378 mResDir = aInfo.uid == myUid ? aInfo.sourceDir : aInfo.publicSourceDir;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800379 mOverlayDirs = aInfo.resourceDirs;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800380 mDataDir = aInfo.dataDir;
381 mLibDir = aInfo.nativeLibraryDir;
382 mDataDirFile = FileUtils.newFileOrNull(aInfo.dataDir);
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600383 mDeviceProtectedDataDirFile = FileUtils.newFileOrNull(aInfo.deviceProtectedDataDir);
384 mCredentialProtectedDataDirFile = FileUtils.newFileOrNull(aInfo.credentialProtectedDataDir);
Adam Lesinski4e862812016-11-21 16:02:24 -0800385
386 mSplitNames = aInfo.splitNames;
387 mSplitAppDirs = aInfo.splitSourceDirs;
388 mSplitResDirs = aInfo.uid == myUid ? aInfo.splitSourceDirs : aInfo.splitPublicSourceDirs;
Narayan Kamathf9419f02017-06-15 11:35:38 +0100389 mSplitClassLoaderNames = aInfo.splitClassLoaderNames;
Adam Lesinski4e862812016-11-21 16:02:24 -0800390
391 if (aInfo.requestsIsolatedSplitLoading() && !ArrayUtils.isEmpty(mSplitNames)) {
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800392 mSplitLoader = new SplitDependencyLoaderImpl(aInfo.splitDependencies);
Adam Lesinski4e862812016-11-21 16:02:24 -0800393 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800394 }
395
Dimitry Ivanov638d8102017-02-22 15:39:42 -0800396 public static void makePaths(ActivityThread activityThread,
397 ApplicationInfo aInfo,
398 List<String> outZipPaths) {
399 makePaths(activityThread, false, aInfo, outZipPaths, null);
400 }
401
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000402 private static void appendSharedLibrariesLibPathsIfNeeded(
403 List<SharedLibraryInfo> sharedLibraries, ApplicationInfo aInfo,
404 Set<String> outSeenPaths,
405 List<String> outLibPaths) {
406 if (sharedLibraries == null) {
407 return;
408 }
409 for (SharedLibraryInfo lib : sharedLibraries) {
410 List<String> paths = lib.getAllCodePaths();
411 outSeenPaths.addAll(paths);
412 for (String path : paths) {
413 appendApkLibPathIfNeeded(path, aInfo, outLibPaths);
414 }
415 appendSharedLibrariesLibPathsIfNeeded(
416 lib.getDependencies(), aInfo, outSeenPaths, outLibPaths);
417 }
418 }
419
Dimitry Ivanov638d8102017-02-22 15:39:42 -0800420 public static void makePaths(ActivityThread activityThread,
421 boolean isBundledApp,
422 ApplicationInfo aInfo,
423 List<String> outZipPaths,
424 List<String> outLibPaths) {
Todd Kennedy39bfee52016-02-24 10:28:21 -0800425 final String appDir = aInfo.sourceDir;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800426 final String libDir = aInfo.nativeLibraryDir;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800427
428 outZipPaths.clear();
429 outZipPaths.add(appDir);
Adam Lesinski4e862812016-11-21 16:02:24 -0800430
431 // Do not load all available splits if the app requested isolated split loading.
432 if (aInfo.splitSourceDirs != null && !aInfo.requestsIsolatedSplitLoading()) {
433 Collections.addAll(outZipPaths, aInfo.splitSourceDirs);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800434 }
435
436 if (outLibPaths != null) {
437 outLibPaths.clear();
438 }
439
440 /*
441 * The following is a bit of a hack to inject
442 * instrumentation into the system: If the app
443 * being started matches one of the instrumentation names,
444 * then we combine both the "instrumentation" and
445 * "instrumented" app into the path, along with the
446 * concatenation of both apps' shared library lists.
447 */
448
Todd Kennedy39bfee52016-02-24 10:28:21 -0800449 String[] instrumentationLibs = null;
Torne (Richard Coles)3b6ca992016-10-10 15:11:36 +0100450 // activityThread will be null when called from the WebView zygote; just assume
451 // no instrumentation applies in this case.
452 if (activityThread != null) {
453 String instrumentationPackageName = activityThread.mInstrumentationPackageName;
454 String instrumentationAppDir = activityThread.mInstrumentationAppDir;
455 String[] instrumentationSplitAppDirs = activityThread.mInstrumentationSplitAppDirs;
456 String instrumentationLibDir = activityThread.mInstrumentationLibDir;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800457
Torne (Richard Coles)3b6ca992016-10-10 15:11:36 +0100458 String instrumentedAppDir = activityThread.mInstrumentedAppDir;
459 String[] instrumentedSplitAppDirs = activityThread.mInstrumentedSplitAppDirs;
460 String instrumentedLibDir = activityThread.mInstrumentedLibDir;
461
462 if (appDir.equals(instrumentationAppDir)
463 || appDir.equals(instrumentedAppDir)) {
464 outZipPaths.clear();
465 outZipPaths.add(instrumentationAppDir);
Adam Lesinski4e862812016-11-21 16:02:24 -0800466
467 // Only add splits if the app did not request isolated split loading.
468 if (!aInfo.requestsIsolatedSplitLoading()) {
469 if (instrumentationSplitAppDirs != null) {
470 Collections.addAll(outZipPaths, instrumentationSplitAppDirs);
471 }
472
473 if (!instrumentationAppDir.equals(instrumentedAppDir)) {
474 outZipPaths.add(instrumentedAppDir);
475 if (instrumentedSplitAppDirs != null) {
476 Collections.addAll(outZipPaths, instrumentedSplitAppDirs);
477 }
Torne (Richard Coles)3b6ca992016-10-10 15:11:36 +0100478 }
Jeff Haoc7b94822016-03-16 15:56:07 -0700479 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800480
Torne (Richard Coles)3b6ca992016-10-10 15:11:36 +0100481 if (outLibPaths != null) {
482 outLibPaths.add(instrumentationLibDir);
483 if (!instrumentationLibDir.equals(instrumentedLibDir)) {
484 outLibPaths.add(instrumentedLibDir);
485 }
486 }
487
488 if (!instrumentedAppDir.equals(instrumentationAppDir)) {
489 instrumentationLibs = getLibrariesFor(instrumentationPackageName);
490 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800491 }
492 }
493
494 if (outLibPaths != null) {
495 if (outLibPaths.isEmpty()) {
496 outLibPaths.add(libDir);
497 }
498
499 // Add path to libraries in apk for current abi. Do this now because more entries
500 // will be added to zipPaths that shouldn't be part of the library path.
501 if (aInfo.primaryCpuAbi != null) {
Alex Light20ed24f2016-04-20 14:07:43 -0700502 // Add fake libs into the library search path if we target prior to N.
Adam Lesinski4e862812016-11-21 16:02:24 -0800503 if (aInfo.targetSdkVersion < Build.VERSION_CODES.N) {
Alex Light20ed24f2016-04-20 14:07:43 -0700504 outLibPaths.add("/system/fake-libs" +
505 (VMRuntime.is64BitAbi(aInfo.primaryCpuAbi) ? "64" : ""));
506 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800507 for (String apk : outZipPaths) {
508 outLibPaths.add(apk + "!/lib/" + aInfo.primaryCpuAbi);
509 }
510 }
511
Dimitry Ivanov638d8102017-02-22 15:39:42 -0800512 if (isBundledApp) {
Todd Kennedy39bfee52016-02-24 10:28:21 -0800513 // Add path to system libraries to libPaths;
514 // Access to system libs should be limited
515 // to bundled applications; this is why updated
516 // system apps are not included.
517 outLibPaths.add(System.getProperty("java.library.path"));
518 }
519 }
520
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000521 // Add the shared libraries native paths. The dex files in shared libraries will
522 // be resolved through shared library loaders, which are setup later.
523 Set<String> outSeenPaths = new LinkedHashSet<>();
524 appendSharedLibrariesLibPathsIfNeeded(
525 aInfo.sharedLibraryInfos, aInfo, outSeenPaths, outLibPaths);
526
527 // ApplicationInfo.sharedLibraryFiles is a public API, so anyone can change it.
528 // We prepend shared libraries that the package manager hasn't seen, maintaining their
529 // original order where possible.
530 if (aInfo.sharedLibraryFiles != null) {
Jeff Hao090892f2017-04-24 17:37:31 -0700531 int index = 0;
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000532 for (String lib : aInfo.sharedLibraryFiles) {
533 if (!outSeenPaths.contains(lib) && !outZipPaths.contains(lib)) {
Jeff Hao090892f2017-04-24 17:37:31 -0700534 outZipPaths.add(index, lib);
535 index++;
Svetoslav Ganov40610e32017-06-20 19:35:51 -0700536 appendApkLibPathIfNeeded(lib, aInfo, outLibPaths);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800537 }
538 }
539 }
540
541 if (instrumentationLibs != null) {
542 for (String lib : instrumentationLibs) {
543 if (!outZipPaths.contains(lib)) {
544 outZipPaths.add(0, lib);
Svetoslav Ganov40610e32017-06-20 19:35:51 -0700545 appendApkLibPathIfNeeded(lib, aInfo, outLibPaths);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800546 }
547 }
548 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800549 }
550
Svetoslav Ganov40610e32017-06-20 19:35:51 -0700551 /**
552 * This method appends a path to the appropriate native library folder of a
553 * library if this library is hosted in an APK. This allows support for native
554 * shared libraries. The library API is determined based on the application
555 * ABI.
556 *
557 * @param path Path to the library.
558 * @param applicationInfo The application depending on the library.
559 * @param outLibPaths List to which to add the native lib path if needed.
560 */
561 private static void appendApkLibPathIfNeeded(@NonNull String path,
562 @NonNull ApplicationInfo applicationInfo, @Nullable List<String> outLibPaths) {
563 // Looking at the suffix is a little hacky but a safe and simple solution.
564 // We will be revisiting code in the next release and clean this up.
565 if (outLibPaths != null && applicationInfo.primaryCpuAbi != null && path.endsWith(".apk")) {
566 if (applicationInfo.targetSdkVersion >= Build.VERSION_CODES.O) {
567 outLibPaths.add(path + "!/lib/" + applicationInfo.primaryCpuAbi);
568 }
569 }
570 }
571
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800572 /*
573 * All indices received by the super class should be shifted by 1 when accessing mSplitNames,
574 * etc. The super class assumes the base APK is index 0, while the PackageManager APIs don't
575 * include the base APK in the list of splits.
576 */
577 private class SplitDependencyLoaderImpl extends SplitDependencyLoader<NameNotFoundException> {
Adam Lesinski4e862812016-11-21 16:02:24 -0800578 private final String[][] mCachedResourcePaths;
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800579 private final ClassLoader[] mCachedClassLoaders;
Adam Lesinski4e862812016-11-21 16:02:24 -0800580
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800581 SplitDependencyLoaderImpl(@NonNull SparseArray<int[]> dependencies) {
Adam Lesinski4e862812016-11-21 16:02:24 -0800582 super(dependencies);
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800583 mCachedResourcePaths = new String[mSplitNames.length + 1][];
584 mCachedClassLoaders = new ClassLoader[mSplitNames.length + 1];
Adam Lesinski4e862812016-11-21 16:02:24 -0800585 }
586
587 @Override
588 protected boolean isSplitCached(int splitIdx) {
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800589 return mCachedClassLoaders[splitIdx] != null;
Adam Lesinski4e862812016-11-21 16:02:24 -0800590 }
591
592 @Override
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800593 protected void constructSplit(int splitIdx, @NonNull int[] configSplitIndices,
594 int parentSplitIdx) throws NameNotFoundException {
Adam Lesinski4e862812016-11-21 16:02:24 -0800595 final ArrayList<String> splitPaths = new ArrayList<>();
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800596 if (splitIdx == 0) {
Adam Lesinski4e862812016-11-21 16:02:24 -0800597 createOrUpdateClassLoaderLocked(null);
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800598 mCachedClassLoaders[0] = mClassLoader;
599
600 // Never add the base resources here, they always get added no matter what.
601 for (int configSplitIdx : configSplitIndices) {
602 splitPaths.add(mSplitResDirs[configSplitIdx - 1]);
603 }
604 mCachedResourcePaths[0] = splitPaths.toArray(new String[splitPaths.size()]);
Adam Lesinski4e862812016-11-21 16:02:24 -0800605 return;
606 }
607
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800608 // Since we handled the special base case above, parentSplitIdx is always valid.
609 final ClassLoader parent = mCachedClassLoaders[parentSplitIdx];
610 mCachedClassLoaders[splitIdx] = ApplicationLoaders.getDefault().getClassLoader(
Narayan Kamathf9419f02017-06-15 11:35:38 +0100611 mSplitAppDirs[splitIdx - 1], getTargetSdkVersion(), false, null, null, parent,
612 mSplitClassLoaderNames[splitIdx - 1]);
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800613
614 Collections.addAll(splitPaths, mCachedResourcePaths[parentSplitIdx]);
615 splitPaths.add(mSplitResDirs[splitIdx - 1]);
616 for (int configSplitIdx : configSplitIndices) {
617 splitPaths.add(mSplitResDirs[configSplitIdx - 1]);
Adam Lesinski4e862812016-11-21 16:02:24 -0800618 }
Adam Lesinski4e862812016-11-21 16:02:24 -0800619 mCachedResourcePaths[splitIdx] = splitPaths.toArray(new String[splitPaths.size()]);
620 }
621
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800622 private int ensureSplitLoaded(String splitName) throws NameNotFoundException {
623 int idx = 0;
624 if (splitName != null) {
Adam Lesinski4e862812016-11-21 16:02:24 -0800625 idx = Arrays.binarySearch(mSplitNames, splitName);
626 if (idx < 0) {
627 throw new PackageManager.NameNotFoundException(
628 "Split name '" + splitName + "' is not installed");
629 }
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800630 idx += 1;
Adam Lesinski4e862812016-11-21 16:02:24 -0800631 }
Adam Lesinski4e862812016-11-21 16:02:24 -0800632 loadDependenciesForSplit(idx);
633 return idx;
634 }
635
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800636 ClassLoader getClassLoaderForSplit(String splitName) throws NameNotFoundException {
637 return mCachedClassLoaders[ensureSplitLoaded(splitName)];
Adam Lesinski4e862812016-11-21 16:02:24 -0800638 }
639
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800640 String[] getSplitPathsForSplit(String splitName) throws NameNotFoundException {
641 return mCachedResourcePaths[ensureSplitLoaded(splitName)];
Adam Lesinski4e862812016-11-21 16:02:24 -0800642 }
643 }
644
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800645 private SplitDependencyLoaderImpl mSplitLoader;
Adam Lesinski4e862812016-11-21 16:02:24 -0800646
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800647 ClassLoader getSplitClassLoader(String splitName) throws NameNotFoundException {
Adam Lesinski4e862812016-11-21 16:02:24 -0800648 if (mSplitLoader == null) {
649 return mClassLoader;
650 }
651 return mSplitLoader.getClassLoaderForSplit(splitName);
652 }
653
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800654 String[] getSplitPaths(String splitName) throws NameNotFoundException {
Adam Lesinski4e862812016-11-21 16:02:24 -0800655 if (mSplitLoader == null) {
656 return mSplitResDirs;
657 }
658 return mSplitLoader.getSplitPathsForSplit(splitName);
659 }
660
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000661 /**
662 * Create a class loader for the {@code sharedLibrary}. Shared libraries are canonicalized,
663 * so if we already created a class loader with that shared library, we return it.
664 *
665 * Implementation notes: the canonicalization of shared libraries is something dex2oat
666 * also does.
667 */
668 ClassLoader createSharedLibraryLoader(SharedLibraryInfo sharedLibrary,
669 boolean isBundledApp, String librarySearchPath, String libraryPermittedPath) {
670 List<String> paths = sharedLibrary.getAllCodePaths();
671 List<ClassLoader> sharedLibraries = createSharedLibrariesLoaders(
672 sharedLibrary.getDependencies(), isBundledApp, librarySearchPath,
673 libraryPermittedPath);
674 final String jars = (paths.size() == 1) ? paths.get(0) :
675 TextUtils.join(File.pathSeparator, paths);
676
677 // Shared libraries get a null parent: this has the side effect of having canonicalized
678 // shared libraries using ApplicationLoaders cache, which is the behavior we want.
679 return ApplicationLoaders.getDefault().getClassLoaderWithSharedLibraries(jars,
680 mApplicationInfo.targetSdkVersion, isBundledApp, librarySearchPath,
681 libraryPermittedPath, /* parent */ null,
682 /* classLoaderName */ null, sharedLibraries);
683 }
684
685 private List<ClassLoader> createSharedLibrariesLoaders(List<SharedLibraryInfo> sharedLibraries,
686 boolean isBundledApp, String librarySearchPath, String libraryPermittedPath) {
687 if (sharedLibraries == null) {
688 return null;
689 }
690 List<ClassLoader> loaders = new ArrayList<>();
691 for (SharedLibraryInfo info : sharedLibraries) {
692 loaders.add(createSharedLibraryLoader(
693 info, isBundledApp, librarySearchPath, libraryPermittedPath));
694 }
695 return loaders;
696 }
697
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100698 private StrictMode.ThreadPolicy allowThreadDiskReads() {
699 if (mActivityThread == null) {
700 // When LoadedApk is used without an ActivityThread (usually in a
701 // zygote context), don't call into StrictMode, as it initializes
702 // the binder subsystem, which we don't want.
703 return null;
704 }
705
706 return StrictMode.allowThreadDiskReads();
707 }
708
709 private void setThreadPolicy(StrictMode.ThreadPolicy policy) {
710 if (mActivityThread != null && policy != null) {
711 StrictMode.setThreadPolicy(policy);
712 }
713 }
714
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700715 private void createOrUpdateClassLoaderLocked(List<String> addedPaths) {
716 if (mPackageName.equals("android")) {
Calin Juravle430ef452016-04-22 17:43:07 +0100717 // Note: This branch is taken for system server and we don't need to setup
718 // jit profiling support.
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700719 if (mClassLoader != null) {
720 // nothing to update
721 return;
Dimitry Ivanovb9c90262016-02-19 14:09:20 -0800722 }
723
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700724 if (mBaseClassLoader != null) {
David Brazdilfd6dcc22018-10-25 14:07:51 +0100725 mDefaultClassLoader = mBaseClassLoader;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800726 } else {
David Brazdilfd6dcc22018-10-25 14:07:51 +0100727 mDefaultClassLoader = ClassLoader.getSystemClassLoader();
Todd Kennedy39bfee52016-02-24 10:28:21 -0800728 }
David Brazdilfd6dcc22018-10-25 14:07:51 +0100729 mAppComponentFactory = createAppFactory(mApplicationInfo, mDefaultClassLoader);
David Brazdil33bd3432019-02-27 20:15:18 +0000730 mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader,
731 new ApplicationInfo(mApplicationInfo));
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700732 return;
733 }
734
735 // Avoid the binder call when the package is the current application package.
736 // The activity manager will perform ensure that dexopt is performed before
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100737 // spinning up the process. Similarly, don't call into binder when we don't
738 // have an ActivityThread object.
739 if (mActivityThread != null
740 && !Objects.equals(mPackageName, ActivityThread.currentPackageName())
741 && mIncludeCode) {
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700742 try {
Brian Carlstromca82e612016-04-19 23:16:08 -0700743 ActivityThread.getPackageManager().notifyPackageUse(mPackageName,
744 PackageManager.NOTIFY_PACKAGE_USE_CROSS_PACKAGE);
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700745 } catch (RemoteException re) {
746 throw re.rethrowFromSystemServer();
Todd Kennedy39bfee52016-02-24 10:28:21 -0800747 }
748 }
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700749
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700750 if (mRegisterPackage) {
751 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -0800752 ActivityManager.getService().addPackageDependency(mPackageName);
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700753 } catch (RemoteException e) {
754 throw e.rethrowFromSystemServer();
755 }
756 }
757
Andreas Gampea8a58ff2016-05-18 11:58:39 -0700758 // Lists for the elements of zip/code and native libraries.
759 //
760 // Both lists are usually not empty. We expect on average one APK for the zip component,
761 // but shared libraries and splits are not uncommon. We expect at least three elements
762 // for native libraries (app-based, system, vendor). As such, give both some breathing
763 // space and initialize to a small value (instead of incurring growth code).
764 final List<String> zipPaths = new ArrayList<>(10);
765 final List<String> libPaths = new ArrayList<>(10);
Narayan Kamath8995b002016-05-11 20:31:09 +0100766
Jiyong Parkfcad6962017-08-22 10:24:28 +0900767 boolean isBundledApp = mApplicationInfo.isSystemApp()
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700768 && !mApplicationInfo.isUpdatedSystemApp();
Dimitry Ivanovbf3b5f72016-05-03 11:34:58 -0700769
Jiyong Parkfcad6962017-08-22 10:24:28 +0900770 // Vendor apks are treated as bundled only when /vendor/lib is in the default search
771 // paths. If not, they are treated as unbundled; access to system libs is limited.
772 // Having /vendor/lib in the default search paths means that all system processes
773 // are allowed to use any vendor library, which in turn means that system is dependent
774 // on vendor partition. In the contrary, not having /vendor/lib in the default search
775 // paths mean that the two partitions are separated and thus we can treat vendor apks
776 // as unbundled.
777 final String defaultSearchPaths = System.getProperty("java.library.path");
778 final boolean treatVendorApkAsUnbundled = !defaultSearchPaths.contains("/vendor/lib");
Jiyong Park63495c22017-09-15 07:48:06 +0900779 if (mApplicationInfo.getCodePath() != null
Jiyong Park002fdbd2017-02-13 20:50:31 +0900780 && mApplicationInfo.isVendor() && treatVendorApkAsUnbundled) {
Jiyong Parkfcad6962017-08-22 10:24:28 +0900781 isBundledApp = false;
782 }
783
Dimitry Ivanov638d8102017-02-22 15:39:42 -0800784 makePaths(mActivityThread, isBundledApp, mApplicationInfo, zipPaths, libPaths);
785
Dimitry Ivanoveb96b002016-05-10 10:51:40 -0700786 String libraryPermittedPath = mDataDir;
Jiyong Park29d9eba2018-05-04 12:44:38 +0900787
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700788 if (isBundledApp) {
Jiyong Park29d9eba2018-05-04 12:44:38 +0900789 // For bundled apps, add the base directory of the app (e.g.,
790 // /system/app/Foo/) to the permitted paths so that it can load libraries
791 // embedded in module apks under the directory. For now, GmsCore is relying
792 // on this, but this isn't specific to the app. Also note that, we don't
793 // need to do this for unbundled apps as entire /data is already set to
794 // the permitted paths for them.
795 libraryPermittedPath += File.pathSeparator
796 + Paths.get(getAppDir()).getParent().toString();
797
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700798 // This is necessary to grant bundled apps access to
799 // libraries located in subdirectories of /system/lib
Jiyong Parkfcad6962017-08-22 10:24:28 +0900800 libraryPermittedPath += File.pathSeparator + defaultSearchPaths;
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700801 }
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700802
803 final String librarySearchPath = TextUtils.join(File.pathSeparator, libPaths);
804
Narayan Kamath8995b002016-05-11 20:31:09 +0100805 // If we're not asked to include code, we construct a classloader that has
806 // no code path included. We still need to set up the library search paths
807 // and permitted path because NativeActivity relies on it (it attempts to
808 // call System.loadLibrary() on a classloader from a LoadedApk with
809 // mIncludeCode == false).
810 if (!mIncludeCode) {
David Brazdilfd6dcc22018-10-25 14:07:51 +0100811 if (mDefaultClassLoader == null) {
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100812 StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads();
David Brazdilfd6dcc22018-10-25 14:07:51 +0100813 mDefaultClassLoader = ApplicationLoaders.getDefault().getClassLoader(
Narayan Kamathf9419f02017-06-15 11:35:38 +0100814 "" /* codePath */, mApplicationInfo.targetSdkVersion, isBundledApp,
815 librarySearchPath, libraryPermittedPath, mBaseClassLoader,
816 null /* classLoaderName */);
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100817 setThreadPolicy(oldPolicy);
Jason Monk2544c692018-05-15 11:30:09 -0400818 mAppComponentFactory = AppComponentFactory.DEFAULT;
Narayan Kamath8995b002016-05-11 20:31:09 +0100819 }
820
David Brazdilfd6dcc22018-10-25 14:07:51 +0100821 if (mClassLoader == null) {
David Brazdil33bd3432019-02-27 20:15:18 +0000822 mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader,
823 new ApplicationInfo(mApplicationInfo));
David Brazdilfd6dcc22018-10-25 14:07:51 +0100824 }
825
Narayan Kamath8995b002016-05-11 20:31:09 +0100826 return;
827 }
828
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700829 /*
Narayan Kamath8995b002016-05-11 20:31:09 +0100830 * With all the combination done (if necessary, actually create the java class
831 * loader and set up JIT profiling support if necessary.
Andreas Gampea8a58ff2016-05-18 11:58:39 -0700832 *
833 * In many cases this is a single APK, so try to avoid the StringBuilder in TextUtils.
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700834 */
Andreas Gampea8a58ff2016-05-18 11:58:39 -0700835 final String zip = (zipPaths.size() == 1) ? zipPaths.get(0) :
836 TextUtils.join(File.pathSeparator, zipPaths);
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700837
Dianne Hackborn94846032017-03-31 17:55:23 -0700838 if (DEBUG) Slog.v(ActivityThread.TAG, "Class path: " + zip +
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700839 ", JNI path: " + librarySearchPath);
840
Calin Juravle430ef452016-04-22 17:43:07 +0100841 boolean needToSetupJitProfiles = false;
David Brazdilfd6dcc22018-10-25 14:07:51 +0100842 if (mDefaultClassLoader == null) {
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700843 // Temporarily disable logging of disk reads on the Looper thread
844 // as this is early and necessary.
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100845 StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads();
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700846
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000847 List<ClassLoader> sharedLibraries = createSharedLibrariesLoaders(
848 mApplicationInfo.sharedLibraryInfos, isBundledApp, librarySearchPath,
849 libraryPermittedPath);
850
851 mDefaultClassLoader = ApplicationLoaders.getDefault().getClassLoaderWithSharedLibraries(
852 zip, mApplicationInfo.targetSdkVersion, isBundledApp, librarySearchPath,
Narayan Kamathf9419f02017-06-15 11:35:38 +0100853 libraryPermittedPath, mBaseClassLoader,
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000854 mApplicationInfo.classLoaderName, sharedLibraries);
David Brazdilfd6dcc22018-10-25 14:07:51 +0100855 mAppComponentFactory = createAppFactory(mApplicationInfo, mDefaultClassLoader);
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700856
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100857 setThreadPolicy(oldPolicy);
Calin Juravle430ef452016-04-22 17:43:07 +0100858 // Setup the class loader paths for profiling.
859 needToSetupJitProfiles = true;
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700860 }
861
Patrick Baumann1bea2372018-03-13 14:26:58 -0700862 if (!libPaths.isEmpty() && SystemProperties.getBoolean(PROPERTY_NAME_APPEND_NATIVE, true)) {
Patrick Baumann5c5daa42018-05-09 11:12:49 -0700863 // Temporarily disable logging of disk reads on the Looper thread as this is necessary
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100864 StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads();
Patrick Baumann5c5daa42018-05-09 11:12:49 -0700865 try {
David Brazdilfd6dcc22018-10-25 14:07:51 +0100866 ApplicationLoaders.getDefault().addNative(mDefaultClassLoader, libPaths);
Patrick Baumann5c5daa42018-05-09 11:12:49 -0700867 } finally {
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100868 setThreadPolicy(oldPolicy);
Patrick Baumann5c5daa42018-05-09 11:12:49 -0700869 }
Patrick Baumann1bea2372018-03-13 14:26:58 -0700870 }
871
Victor Changa366cc82019-02-07 15:20:25 +0000872 // /aepx/com.android.runtime/lib, /vendor/lib, /odm/lib and /product/lib
873 // are added to the native lib search paths of the classloader.
874 // Note that this is done AFTER the classloader is
Jiyong Parkcfe38cd2018-06-04 15:05:29 +0900875 // created by ApplicationLoaders.getDefault().getClassLoader(...). The
876 // reason is because if we have added the paths when creating the classloader
877 // above, the paths are also added to the search path of the linker namespace
878 // 'classloader-namespace', which will allow ALL libs in the paths to apps.
879 // Since only the libs listed in <partition>/etc/public.libraries.txt can be
880 // available to apps, we shouldn't add the paths then.
881 //
882 // However, we need to add the paths to the classloader (Java) though. This
883 // is because when a native lib is requested via System.loadLibrary(), the
884 // classloader first tries to find the requested lib in its own native libs
885 // search paths. If a lib is not found in one of the paths, dlopen() is not
886 // called at all. This can cause a problem that a vendor public native lib
887 // is accessible when directly opened via dlopen(), but inaccesible via
888 // System.loadLibrary(). In order to prevent the problem, we explicitly
889 // add the paths only to the classloader, and not to the native loader
890 // (linker namespace).
Victor Changa366cc82019-02-07 15:20:25 +0000891 List<String> extraLibPaths = new ArrayList<>(4);
Jiyong Parkcfe38cd2018-06-04 15:05:29 +0900892 String abiSuffix = VMRuntime.getRuntime().is64Bit() ? "64" : "";
Victor Changa366cc82019-02-07 15:20:25 +0000893 if (!defaultSearchPaths.contains("/apex/com.android.runtime/lib")) {
894 extraLibPaths.add("/apex/com.android.runtime/lib" + abiSuffix);
895 }
Jiyong Parkcfe38cd2018-06-04 15:05:29 +0900896 if (!defaultSearchPaths.contains("/vendor/lib")) {
897 extraLibPaths.add("/vendor/lib" + abiSuffix);
898 }
899 if (!defaultSearchPaths.contains("/odm/lib")) {
900 extraLibPaths.add("/odm/lib" + abiSuffix);
901 }
902 if (!defaultSearchPaths.contains("/product/lib")) {
903 extraLibPaths.add("/product/lib" + abiSuffix);
904 }
905 if (!extraLibPaths.isEmpty()) {
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100906 StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads();
Jiyong Parkcfe38cd2018-06-04 15:05:29 +0900907 try {
David Brazdilfd6dcc22018-10-25 14:07:51 +0100908 ApplicationLoaders.getDefault().addNative(mDefaultClassLoader, extraLibPaths);
Jiyong Parkcfe38cd2018-06-04 15:05:29 +0900909 } finally {
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100910 setThreadPolicy(oldPolicy);
Jiyong Parkcfe38cd2018-06-04 15:05:29 +0900911 }
912 }
913
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700914 if (addedPaths != null && addedPaths.size() > 0) {
915 final String add = TextUtils.join(File.pathSeparator, addedPaths);
David Brazdilfd6dcc22018-10-25 14:07:51 +0100916 ApplicationLoaders.getDefault().addPath(mDefaultClassLoader, add);
Calin Juravle430ef452016-04-22 17:43:07 +0100917 // Setup the new code paths for profiling.
918 needToSetupJitProfiles = true;
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700919 }
Calin Juravle2a727d72016-04-15 19:33:46 +0100920
921 // Setup jit profile support.
Narayan Kamath2d4a2222016-04-25 19:16:56 +0100922 //
Calin Juravle2a727d72016-04-15 19:33:46 +0100923 // It is ok to call this multiple times if the application gets updated with new splits.
924 // The runtime only keeps track of unique code paths and can handle re-registration of
925 // the same code path. There's no need to pass `addedPaths` since any new code paths
926 // are already in `mApplicationInfo`.
Narayan Kamath2d4a2222016-04-25 19:16:56 +0100927 //
928 // It is NOT ok to call this function from the system_server (for any of the packages it
929 // loads code from) so we explicitly disallow it there.
930 if (needToSetupJitProfiles && !ActivityThread.isSystem()) {
Calin Juravle430ef452016-04-22 17:43:07 +0100931 setupJitProfileSupport();
Calin Juravle430ef452016-04-22 17:43:07 +0100932 }
David Brazdilfd6dcc22018-10-25 14:07:51 +0100933
934 // Call AppComponentFactory to select/create the main class loader of this app.
935 // Since this may call code in the app, mDefaultClassLoader must be fully set up
936 // before invoking the factory.
David Brazdil33bd3432019-02-27 20:15:18 +0000937 // Invoke with a copy of ApplicationInfo to protect against the app changing it.
David Brazdilfd6dcc22018-10-25 14:07:51 +0100938 if (mClassLoader == null) {
David Brazdil33bd3432019-02-27 20:15:18 +0000939 mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader,
940 new ApplicationInfo(mApplicationInfo));
David Brazdilfd6dcc22018-10-25 14:07:51 +0100941 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800942 }
943
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100944 @UnsupportedAppUsage
Todd Kennedy39bfee52016-02-24 10:28:21 -0800945 public ClassLoader getClassLoader() {
946 synchronized (this) {
947 if (mClassLoader == null) {
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700948 createOrUpdateClassLoaderLocked(null /*addedPaths*/);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800949 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700950 return mClassLoader;
951 }
952 }
953
Calin Juravle2a727d72016-04-15 19:33:46 +0100954 private void setupJitProfileSupport() {
955 if (!SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false)) {
956 return;
957 }
David Brazdil991ff902018-12-03 10:59:29 +0000958
959 // If we use profiles, setup the dex reporter to notify package manager
960 // of any relevant dex loads. The idle maintenance job will use the information
961 // reported to optimize the loaded dex files.
962 // Note that we only need one global reporter per app.
963 // Make sure we do this before invoking app code for the first time so that we
964 // can capture the complete application startup.
965 BaseDexClassLoader.setReporter(DexLoadReporter.getInstance());
966
Calin Juravle126f7802016-05-24 15:23:47 +0100967 // Only set up profile support if the loaded apk has the same uid as the
968 // current process.
969 // Currently, we do not support profiling across different apps.
970 // (e.g. application's uid might be different when the code is
971 // loaded by another app via createApplicationContext)
972 if (mApplicationInfo.uid != Process.myUid()) {
973 return;
974 }
975
Calin Juravle2a727d72016-04-15 19:33:46 +0100976 final List<String> codePaths = new ArrayList<>();
977 if ((mApplicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0) {
978 codePaths.add(mApplicationInfo.sourceDir);
979 }
980 if (mApplicationInfo.splitSourceDirs != null) {
981 Collections.addAll(codePaths, mApplicationInfo.splitSourceDirs);
982 }
983
984 if (codePaths.isEmpty()) {
985 // If there are no code paths there's no need to setup a profile file and register with
986 // the runtime,
987 return;
988 }
989
Calin Juravle6ae39fc2018-01-19 20:32:47 -0800990 for (int i = codePaths.size() - 1; i >= 0; i--) {
991 String splitName = i == 0 ? null : mApplicationInfo.splitNames[i - 1];
992 String profileFile = ArtManager.getCurrentProfilePath(
993 mPackageName, UserHandle.myUserId(), splitName);
994 VMRuntime.registerAppInfo(profileFile, new String[] {codePaths.get(i)});
995 }
Calin Juravlef5a7bfc2017-03-13 23:30:30 -0700996
997 // Register the app data directory with the reporter. It will
998 // help deciding whether or not a dex file is the primary apk or a
999 // secondary dex.
1000 DexLoadReporter.getInstance().registerAppDataDir(mPackageName, mDataDir);
Calin Juravle2a727d72016-04-15 19:33:46 +01001001 }
1002
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001003 /**
1004 * Setup value for Thread.getContextClassLoader(). If the
1005 * package will not run in in a VM with other packages, we set
1006 * the Java context ClassLoader to the
1007 * PackageInfo.getClassLoader value. However, if this VM can
1008 * contain multiple packages, we intead set the Java context
1009 * ClassLoader to a proxy that will warn about the use of Java
1010 * context ClassLoaders and then fall through to use the
1011 * system ClassLoader.
1012 *
1013 * <p> Note that this is similar to but not the same as the
1014 * android.content.Context.getClassLoader(). While both
1015 * context class loaders are typically set to the
1016 * PathClassLoader used to load the package archive in the
1017 * single application per VM case, a single Android process
1018 * may contain several Contexts executing on one thread with
1019 * their own logical ClassLoaders while the Java context
1020 * ClassLoader is a thread local. This is why in the case when
1021 * we have multiple packages per VM we do not set the Java
1022 * context ClassLoader to an arbitrary but instead warn the
1023 * user to set their own if we detect that they are using a
1024 * Java library that expects it to be set.
1025 */
1026 private void initializeJavaContextClassLoader() {
1027 IPackageManager pm = ActivityThread.getPackageManager();
1028 android.content.pm.PackageInfo pi;
1029 try {
Jeff Sharkeyc7bacab2016-02-09 15:56:11 -07001030 pi = pm.getPackageInfo(mPackageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
1031 UserHandle.myUserId());
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001032 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001033 throw e.rethrowFromSystemServer();
Dianne Hackborn208d9372013-02-25 13:17:54 -08001034 }
1035 if (pi == null) {
1036 throw new IllegalStateException("Unable to get package info for "
1037 + mPackageName + "; is package not installed?");
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001038 }
1039 /*
1040 * Two possible indications that this package could be
1041 * sharing its virtual machine with other packages:
1042 *
1043 * 1.) the sharedUserId attribute is set in the manifest,
1044 * indicating a request to share a VM with other
1045 * packages with the same sharedUserId.
1046 *
1047 * 2.) the application element of the manifest has an
1048 * attribute specifying a non-default process name,
1049 * indicating the desire to run in another packages VM.
1050 */
1051 boolean sharedUserIdSet = (pi.sharedUserId != null);
1052 boolean processNameNotDefault =
1053 (pi.applicationInfo != null &&
1054 !mPackageName.equals(pi.applicationInfo.processName));
1055 boolean sharable = (sharedUserIdSet || processNameNotDefault);
1056 ClassLoader contextClassLoader =
1057 (sharable)
1058 ? new WarningContextClassLoader()
1059 : mClassLoader;
1060 Thread.currentThread().setContextClassLoader(contextClassLoader);
1061 }
1062
1063 private static class WarningContextClassLoader extends ClassLoader {
1064
1065 private static boolean warned = false;
1066
1067 private void warn(String methodName) {
1068 if (warned) {
1069 return;
1070 }
1071 warned = true;
1072 Thread.currentThread().setContextClassLoader(getParent());
1073 Slog.w(ActivityThread.TAG, "ClassLoader." + methodName + ": " +
1074 "The class loader returned by " +
1075 "Thread.getContextClassLoader() may fail for processes " +
1076 "that host multiple applications. You should explicitly " +
1077 "specify a context class loader. For example: " +
1078 "Thread.setContextClassLoader(getClass().getClassLoader());");
1079 }
1080
1081 @Override public URL getResource(String resName) {
1082 warn("getResource");
1083 return getParent().getResource(resName);
1084 }
1085
1086 @Override public Enumeration<URL> getResources(String resName) throws IOException {
1087 warn("getResources");
1088 return getParent().getResources(resName);
1089 }
1090
1091 @Override public InputStream getResourceAsStream(String resName) {
1092 warn("getResourceAsStream");
1093 return getParent().getResourceAsStream(resName);
1094 }
1095
1096 @Override public Class<?> loadClass(String className) throws ClassNotFoundException {
1097 warn("loadClass");
1098 return getParent().loadClass(className);
1099 }
1100
1101 @Override public void setClassAssertionStatus(String cname, boolean enable) {
1102 warn("setClassAssertionStatus");
1103 getParent().setClassAssertionStatus(cname, enable);
1104 }
1105
1106 @Override public void setPackageAssertionStatus(String pname, boolean enable) {
1107 warn("setPackageAssertionStatus");
1108 getParent().setPackageAssertionStatus(pname, enable);
1109 }
1110
1111 @Override public void setDefaultAssertionStatus(boolean enable) {
1112 warn("setDefaultAssertionStatus");
1113 getParent().setDefaultAssertionStatus(enable);
1114 }
1115
1116 @Override public void clearAssertionStatus() {
1117 warn("clearAssertionStatus");
1118 getParent().clearAssertionStatus();
1119 }
1120 }
1121
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001122 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001123 public String getAppDir() {
1124 return mAppDir;
1125 }
1126
Brian Carlstromd893a892012-04-01 21:30:26 -07001127 public String getLibDir() {
1128 return mLibDir;
1129 }
1130
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001131 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001132 public String getResDir() {
1133 return mResDir;
1134 }
1135
Jeff Sharkey8a4c9722014-06-16 13:48:42 -07001136 public String[] getSplitAppDirs() {
1137 return mSplitAppDirs;
1138 }
1139
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001140 @UnsupportedAppUsage
Jeff Sharkey8a4c9722014-06-16 13:48:42 -07001141 public String[] getSplitResDirs() {
1142 return mSplitResDirs;
1143 }
1144
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001145 @UnsupportedAppUsage
MÃ¥rten Kongstad48d22322014-01-31 14:43:27 +01001146 public String[] getOverlayDirs() {
1147 return mOverlayDirs;
1148 }
1149
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001150 public String getDataDir() {
1151 return mDataDir;
1152 }
1153
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001154 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001155 public File getDataDirFile() {
1156 return mDataDirFile;
1157 }
1158
Jeff Sharkey8a372a02016-03-16 16:25:45 -06001159 public File getDeviceProtectedDataDirFile() {
1160 return mDeviceProtectedDataDirFile;
Jeff Sharkey15447792015-11-05 16:18:51 -08001161 }
1162
Jeff Sharkey8a372a02016-03-16 16:25:45 -06001163 public File getCredentialProtectedDataDirFile() {
1164 return mCredentialProtectedDataDirFile;
Jeff Sharkey15447792015-11-05 16:18:51 -08001165 }
1166
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001167 @UnsupportedAppUsage
Adam Lesinski4e862812016-11-21 16:02:24 -08001168 public AssetManager getAssets() {
1169 return getResources().getAssets();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001170 }
1171
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001172 @UnsupportedAppUsage
Adam Lesinski4e862812016-11-21 16:02:24 -08001173 public Resources getResources() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001174 if (mResources == null) {
Adam Lesinski4e862812016-11-21 16:02:24 -08001175 final String[] splitPaths;
1176 try {
1177 splitPaths = getSplitPaths(null);
Adam Lesinski1665d0f2017-03-10 14:46:57 -08001178 } catch (NameNotFoundException e) {
Adam Lesinski4e862812016-11-21 16:02:24 -08001179 // This should never fail.
1180 throw new AssertionError("null split not found");
1181 }
1182
Todd Kennedy233a0b12018-01-29 20:30:24 +00001183 mResources = ResourcesManager.getInstance().getResources(null, mResDir,
1184 splitPaths, mOverlayDirs, mApplicationInfo.sharedLibraryFiles,
1185 Display.DEFAULT_DISPLAY, null, getCompatibilityInfo(),
Adam Lesinski4e862812016-11-21 16:02:24 -08001186 getClassLoader());
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001187 }
1188 return mResources;
1189 }
1190
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001191 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001192 public Application makeApplication(boolean forceDefaultAppClass,
1193 Instrumentation instrumentation) {
1194 if (mApplication != null) {
1195 return mApplication;
1196 }
1197
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001198 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");
1199
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001200 Application app = null;
1201
1202 String appClass = mApplicationInfo.className;
1203 if (forceDefaultAppClass || (appClass == null)) {
1204 appClass = "android.app.Application";
1205 }
1206
1207 try {
1208 java.lang.ClassLoader cl = getClassLoader();
Narayan Kamath8091edb2014-10-15 11:38:44 +01001209 if (!mPackageName.equals("android")) {
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001210 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
1211 "initializeJavaContextClassLoader");
Narayan Kamath8091edb2014-10-15 11:38:44 +01001212 initializeJavaContextClassLoader();
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001213 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Narayan Kamath8091edb2014-10-15 11:38:44 +01001214 }
Jeff Browndefd4a62014-03-10 21:24:37 -07001215 ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001216 app = mActivityThread.mInstrumentation.newApplication(
1217 cl, appClass, appContext);
1218 appContext.setOuterContext(app);
1219 } catch (Exception e) {
1220 if (!mActivityThread.mInstrumentation.onException(app, e)) {
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001221 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001222 throw new RuntimeException(
1223 "Unable to instantiate application " + appClass
1224 + ": " + e.toString(), e);
1225 }
1226 }
1227 mActivityThread.mAllApplications.add(app);
1228 mApplication = app;
1229
1230 if (instrumentation != null) {
1231 try {
1232 instrumentation.callApplicationOnCreate(app);
1233 } catch (Exception e) {
1234 if (!instrumentation.onException(app, e)) {
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001235 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001236 throw new RuntimeException(
1237 "Unable to create application " + app.getClass().getName()
1238 + ": " + e.toString(), e);
1239 }
1240 }
1241 }
Adam Lesinskide898ff2014-01-29 18:20:45 -08001242
1243 // Rewrite the R 'constants' for all library apks.
Adam Lesinski4e862812016-11-21 16:02:24 -08001244 SparseArray<String> packageIdentifiers = getAssets().getAssignedPackageIdentifiers();
Adam Lesinskide898ff2014-01-29 18:20:45 -08001245 final int N = packageIdentifiers.size();
1246 for (int i = 0; i < N; i++) {
1247 final int id = packageIdentifiers.keyAt(i);
1248 if (id == 0x01 || id == 0x7f) {
1249 continue;
1250 }
1251
1252 rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);
1253 }
1254
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001255 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1256
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001257 return app;
1258 }
1259
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001260 @UnsupportedAppUsage
Adam Lesinskide898ff2014-01-29 18:20:45 -08001261 private void rewriteRValues(ClassLoader cl, String packageName, int id) {
Adam Lesinski2cb761e2014-08-15 13:59:02 -07001262 final Class<?> rClazz;
Adam Lesinskide898ff2014-01-29 18:20:45 -08001263 try {
Adam Lesinski2cb761e2014-08-15 13:59:02 -07001264 rClazz = cl.loadClass(packageName + ".R");
1265 } catch (ClassNotFoundException e) {
1266 // This is not necessarily an error, as some packages do not ship with resources
1267 // (or they do not need rewriting).
Adam Lesinski1e4663852014-08-15 14:47:28 -07001268 Log.i(TAG, "No resource references to update in package " + packageName);
Adam Lesinski2cb761e2014-08-15 13:59:02 -07001269 return;
1270 }
1271
Adam Lesinski1e4663852014-08-15 14:47:28 -07001272 final Method callback;
Adam Lesinski2cb761e2014-08-15 13:59:02 -07001273 try {
Adam Lesinski1e4663852014-08-15 14:47:28 -07001274 callback = rClazz.getMethod("onResourcesLoaded", int.class);
1275 } catch (NoSuchMethodException e) {
1276 // No rewriting to be done.
1277 return;
Adam Lesinskide898ff2014-01-29 18:20:45 -08001278 }
Adam Lesinski1e4663852014-08-15 14:47:28 -07001279
1280 Throwable cause;
1281 try {
1282 callback.invoke(null, id);
1283 return;
1284 } catch (IllegalAccessException e) {
1285 cause = e;
1286 } catch (InvocationTargetException e) {
1287 cause = e.getCause();
1288 }
1289
1290 throw new RuntimeException("Failed to rewrite resource references for " + packageName,
1291 cause);
Adam Lesinskide898ff2014-01-29 18:20:45 -08001292 }
1293
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001294 public void removeContextRegistrations(Context context,
1295 String who, String what) {
Jeff Sharkeyd7026f12012-03-01 20:50:32 -08001296 final boolean reportRegistrationLeaks = StrictMode.vmRegistrationLeaksEnabled();
Adam Lesinski23d40c42014-11-20 11:58:21 -08001297 synchronized (mReceivers) {
1298 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> rmap =
1299 mReceivers.remove(context);
1300 if (rmap != null) {
1301 for (int i = 0; i < rmap.size(); i++) {
1302 LoadedApk.ReceiverDispatcher rd = rmap.valueAt(i);
1303 IntentReceiverLeaked leak = new IntentReceiverLeaked(
1304 what + " " + who + " has leaked IntentReceiver "
1305 + rd.getIntentReceiver() + " that was " +
1306 "originally registered here. Are you missing a " +
1307 "call to unregisterReceiver()?");
1308 leak.setStackTrace(rd.getLocation().getStackTrace());
1309 Slog.e(ActivityThread.TAG, leak.getMessage(), leak);
1310 if (reportRegistrationLeaks) {
1311 StrictMode.onIntentReceiverLeaked(leak);
1312 }
1313 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001314 ActivityManager.getService().unregisterReceiver(
Adam Lesinski23d40c42014-11-20 11:58:21 -08001315 rd.getIIntentReceiver());
1316 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001317 throw e.rethrowFromSystemServer();
Adam Lesinski23d40c42014-11-20 11:58:21 -08001318 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001319 }
1320 }
Adam Lesinski23d40c42014-11-20 11:58:21 -08001321 mUnregisteredReceivers.remove(context);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001322 }
Adam Lesinski23d40c42014-11-20 11:58:21 -08001323
1324 synchronized (mServices) {
1325 //Slog.i(TAG, "Receiver registrations: " + mReceivers);
1326 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> smap =
1327 mServices.remove(context);
1328 if (smap != null) {
1329 for (int i = 0; i < smap.size(); i++) {
1330 LoadedApk.ServiceDispatcher sd = smap.valueAt(i);
1331 ServiceConnectionLeaked leak = new ServiceConnectionLeaked(
1332 what + " " + who + " has leaked ServiceConnection "
1333 + sd.getServiceConnection() + " that was originally bound here");
1334 leak.setStackTrace(sd.getLocation().getStackTrace());
1335 Slog.e(ActivityThread.TAG, leak.getMessage(), leak);
1336 if (reportRegistrationLeaks) {
1337 StrictMode.onServiceConnectionLeaked(leak);
1338 }
1339 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001340 ActivityManager.getService().unbindService(
Adam Lesinski23d40c42014-11-20 11:58:21 -08001341 sd.getIServiceConnection());
1342 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001343 throw e.rethrowFromSystemServer();
Adam Lesinski23d40c42014-11-20 11:58:21 -08001344 }
1345 sd.doForget();
Jeff Sharkeyd7026f12012-03-01 20:50:32 -08001346 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001347 }
Adam Lesinski23d40c42014-11-20 11:58:21 -08001348 mUnboundServices.remove(context);
1349 //Slog.i(TAG, "Service registrations: " + mServices);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001350 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001351 }
1352
1353 public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r,
1354 Context context, Handler handler,
1355 Instrumentation instrumentation, boolean registered) {
1356 synchronized (mReceivers) {
1357 LoadedApk.ReceiverDispatcher rd = null;
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001358 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001359 if (registered) {
1360 map = mReceivers.get(context);
1361 if (map != null) {
1362 rd = map.get(r);
1363 }
1364 }
1365 if (rd == null) {
1366 rd = new ReceiverDispatcher(r, context, handler,
1367 instrumentation, registered);
1368 if (registered) {
1369 if (map == null) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001370 map = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001371 mReceivers.put(context, map);
1372 }
1373 map.put(r, rd);
1374 }
1375 } else {
1376 rd.validate(context, handler);
1377 }
Dianne Hackbornc2d9c8e2011-01-24 21:59:21 -08001378 rd.mForgotten = false;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001379 return rd.getIIntentReceiver();
1380 }
1381 }
1382
1383 public IIntentReceiver forgetReceiverDispatcher(Context context,
1384 BroadcastReceiver r) {
1385 synchronized (mReceivers) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001386 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = mReceivers.get(context);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001387 LoadedApk.ReceiverDispatcher rd = null;
1388 if (map != null) {
1389 rd = map.get(r);
1390 if (rd != null) {
1391 map.remove(r);
1392 if (map.size() == 0) {
1393 mReceivers.remove(context);
1394 }
1395 if (r.getDebugUnregister()) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001396 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> holder
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001397 = mUnregisteredReceivers.get(context);
1398 if (holder == null) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001399 holder = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001400 mUnregisteredReceivers.put(context, holder);
1401 }
1402 RuntimeException ex = new IllegalArgumentException(
1403 "Originally unregistered here:");
1404 ex.fillInStackTrace();
1405 rd.setUnregisterLocation(ex);
1406 holder.put(r, rd);
1407 }
Dianne Hackbornc2d9c8e2011-01-24 21:59:21 -08001408 rd.mForgotten = true;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001409 return rd.getIIntentReceiver();
1410 }
1411 }
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001412 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> holder
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001413 = mUnregisteredReceivers.get(context);
1414 if (holder != null) {
1415 rd = holder.get(r);
1416 if (rd != null) {
1417 RuntimeException ex = rd.getUnregisterLocation();
1418 throw new IllegalArgumentException(
1419 "Unregistering Receiver " + r
1420 + " that was already unregistered", ex);
1421 }
1422 }
1423 if (context == null) {
1424 throw new IllegalStateException("Unbinding Receiver " + r
1425 + " from Context that is no longer in use: " + context);
1426 } else {
1427 throw new IllegalArgumentException("Receiver not registered: " + r);
1428 }
1429
1430 }
1431 }
1432
1433 static final class ReceiverDispatcher {
1434
1435 final static class InnerReceiver extends IIntentReceiver.Stub {
1436 final WeakReference<LoadedApk.ReceiverDispatcher> mDispatcher;
1437 final LoadedApk.ReceiverDispatcher mStrongRef;
1438
1439 InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) {
1440 mDispatcher = new WeakReference<LoadedApk.ReceiverDispatcher>(rd);
1441 mStrongRef = strong ? rd : null;
1442 }
Jeff Sharkeyd136e512016-03-09 22:30:56 -07001443
1444 @Override
Dianne Hackborn20e80982012-08-31 19:00:44 -07001445 public void performReceive(Intent intent, int resultCode, String data,
1446 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
Dianne Hackborn26756162016-05-17 13:40:44 -07001447 final LoadedApk.ReceiverDispatcher rd;
1448 if (intent == null) {
1449 Log.wtf(TAG, "Null intent received");
1450 rd = null;
1451 } else {
1452 rd = mDispatcher.get();
1453 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001454 if (ActivityThread.DEBUG_BROADCAST) {
1455 int seq = intent.getIntExtra("seq", -1);
Dianne Hackborn26756162016-05-17 13:40:44 -07001456 Slog.i(ActivityThread.TAG, "Receiving broadcast " + intent.getAction()
1457 + " seq=" + seq + " to " + (rd != null ? rd.mReceiver : null));
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001458 }
1459 if (rd != null) {
1460 rd.performReceive(intent, resultCode, data, extras,
Dianne Hackborn20e80982012-08-31 19:00:44 -07001461 ordered, sticky, sendingUser);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001462 } else {
1463 // The activity manager dispatched a broadcast to a registered
1464 // receiver in this process, but before it could be delivered the
1465 // receiver was unregistered. Acknowledge the broadcast on its
1466 // behalf so that the system's broadcast sequence can continue.
1467 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1468 "Finishing broadcast to unregistered receiver");
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001469 IActivityManager mgr = ActivityManager.getService();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001470 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001471 if (extras != null) {
1472 extras.setAllowFds(false);
1473 }
riddle_hsu1f5ac4d2015-01-03 15:38:21 +08001474 mgr.finishReceiver(this, resultCode, data, extras, false, intent.getFlags());
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001475 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001476 throw e.rethrowFromSystemServer();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001477 }
1478 }
1479 }
1480 }
1481
1482 final IIntentReceiver.Stub mIIntentReceiver;
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001483 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001484 final BroadcastReceiver mReceiver;
Mathew Inwood8c854f82018-09-14 12:35:36 +01001485 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001486 final Context mContext;
1487 final Handler mActivityThread;
1488 final Instrumentation mInstrumentation;
1489 final boolean mRegistered;
1490 final IntentReceiverLeaked mLocation;
1491 RuntimeException mUnregisterLocation;
Dianne Hackbornc2d9c8e2011-01-24 21:59:21 -08001492 boolean mForgotten;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001493
Makoto Onuki08408b92017-05-09 13:48:53 -07001494 final class Args extends BroadcastReceiver.PendingResult {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001495 private Intent mCurIntent;
Dianne Hackborne829fef2010-10-26 17:44:01 -07001496 private final boolean mOrdered;
Dianne Hackborn17c77532016-06-22 16:49:14 -07001497 private boolean mDispatched;
Makoto Onukif3bb6f32017-05-02 12:02:23 -07001498 private Throwable mPreviousRunStacktrace; // To investigate b/37809561. STOPSHIP remove.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001499
Dianne Hackborne829fef2010-10-26 17:44:01 -07001500 public Args(Intent intent, int resultCode, String resultData, Bundle resultExtras,
Dianne Hackborn20e80982012-08-31 19:00:44 -07001501 boolean ordered, boolean sticky, int sendingUser) {
Dianne Hackborne829fef2010-10-26 17:44:01 -07001502 super(resultCode, resultData, resultExtras,
riddle_hsu1f5ac4d2015-01-03 15:38:21 +08001503 mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED, ordered,
1504 sticky, mIIntentReceiver.asBinder(), sendingUser, intent.getFlags());
Dianne Hackborne829fef2010-10-26 17:44:01 -07001505 mCurIntent = intent;
1506 mOrdered = ordered;
1507 }
Dianne Hackborn17c77532016-06-22 16:49:14 -07001508
Makoto Onuki08408b92017-05-09 13:48:53 -07001509 public final Runnable getRunnable() {
1510 return () -> {
1511 final BroadcastReceiver receiver = mReceiver;
1512 final boolean ordered = mOrdered;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001513
Makoto Onuki08408b92017-05-09 13:48:53 -07001514 if (ActivityThread.DEBUG_BROADCAST) {
1515 int seq = mCurIntent.getIntExtra("seq", -1);
1516 Slog.i(ActivityThread.TAG, "Dispatching broadcast " + mCurIntent.getAction()
1517 + " seq=" + seq + " to " + mReceiver);
1518 Slog.i(ActivityThread.TAG, " mRegistered=" + mRegistered
1519 + " mOrderedHint=" + ordered);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001520 }
Makoto Onuki08408b92017-05-09 13:48:53 -07001521
1522 final IActivityManager mgr = ActivityManager.getService();
1523 final Intent intent = mCurIntent;
1524 if (intent == null) {
1525 Log.wtf(TAG, "Null intent being dispatched, mDispatched=" + mDispatched
1526 + ": run() previously called at "
1527 + Log.getStackTraceString(mPreviousRunStacktrace));
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001528 }
Makoto Onuki08408b92017-05-09 13:48:53 -07001529
1530 mCurIntent = null;
1531 mDispatched = true;
1532 mPreviousRunStacktrace = new Throwable("Previous stacktrace");
1533 if (receiver == null || intent == null || mForgotten) {
1534 if (mRegistered && ordered) {
1535 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1536 "Finishing null broadcast to " + mReceiver);
1537 sendFinished(mgr);
1538 }
1539 return;
1540 }
1541
1542 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveReg");
1543 try {
1544 ClassLoader cl = mReceiver.getClass().getClassLoader();
1545 intent.setExtrasClassLoader(cl);
1546 intent.prepareToEnterProcess();
1547 setExtrasClassLoader(cl);
1548 receiver.setPendingResult(this);
1549 receiver.onReceive(mContext, intent);
1550 } catch (Exception e) {
1551 if (mRegistered && ordered) {
1552 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1553 "Finishing failed broadcast to " + mReceiver);
1554 sendFinished(mgr);
1555 }
1556 if (mInstrumentation == null ||
1557 !mInstrumentation.onException(mReceiver, e)) {
1558 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1559 throw new RuntimeException(
1560 "Error receiving broadcast " + intent
1561 + " in " + mReceiver, e);
1562 }
1563 }
1564
1565 if (receiver.getPendingResult() != null) {
1566 finish();
1567 }
1568 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1569 };
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001570 }
1571 }
1572
1573 ReceiverDispatcher(BroadcastReceiver receiver, Context context,
1574 Handler activityThread, Instrumentation instrumentation,
1575 boolean registered) {
1576 if (activityThread == null) {
1577 throw new NullPointerException("Handler must not be null");
1578 }
1579
1580 mIIntentReceiver = new InnerReceiver(this, !registered);
1581 mReceiver = receiver;
1582 mContext = context;
1583 mActivityThread = activityThread;
1584 mInstrumentation = instrumentation;
1585 mRegistered = registered;
1586 mLocation = new IntentReceiverLeaked(null);
1587 mLocation.fillInStackTrace();
1588 }
1589
1590 void validate(Context context, Handler activityThread) {
1591 if (mContext != context) {
1592 throw new IllegalStateException(
1593 "Receiver " + mReceiver +
1594 " registered with differing Context (was " +
1595 mContext + " now " + context + ")");
1596 }
1597 if (mActivityThread != activityThread) {
1598 throw new IllegalStateException(
1599 "Receiver " + mReceiver +
1600 " registered with differing handler (was " +
1601 mActivityThread + " now " + activityThread + ")");
1602 }
1603 }
1604
1605 IntentReceiverLeaked getLocation() {
1606 return mLocation;
1607 }
1608
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001609 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001610 BroadcastReceiver getIntentReceiver() {
1611 return mReceiver;
1612 }
1613
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001614 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001615 IIntentReceiver getIIntentReceiver() {
1616 return mIIntentReceiver;
1617 }
1618
1619 void setUnregisterLocation(RuntimeException ex) {
1620 mUnregisterLocation = ex;
1621 }
1622
1623 RuntimeException getUnregisterLocation() {
1624 return mUnregisterLocation;
1625 }
1626
Dianne Hackborn20e80982012-08-31 19:00:44 -07001627 public void performReceive(Intent intent, int resultCode, String data,
1628 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
Dianne Hackborn41bfaf82016-06-08 16:33:29 -07001629 final Args args = new Args(intent, resultCode, data, extras, ordered,
Dianne Hackborn20e80982012-08-31 19:00:44 -07001630 sticky, sendingUser);
Dianne Hackborn41bfaf82016-06-08 16:33:29 -07001631 if (intent == null) {
1632 Log.wtf(TAG, "Null intent received");
1633 } else {
1634 if (ActivityThread.DEBUG_BROADCAST) {
1635 int seq = intent.getIntExtra("seq", -1);
1636 Slog.i(ActivityThread.TAG, "Enqueueing broadcast " + intent.getAction()
1637 + " seq=" + seq + " to " + mReceiver);
1638 }
1639 }
Makoto Onuki08408b92017-05-09 13:48:53 -07001640 if (intent == null || !mActivityThread.post(args.getRunnable())) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001641 if (mRegistered && ordered) {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001642 IActivityManager mgr = ActivityManager.getService();
Dianne Hackborne829fef2010-10-26 17:44:01 -07001643 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1644 "Finishing sync broadcast to " + mReceiver);
1645 args.sendFinished(mgr);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001646 }
1647 }
1648 }
1649
1650 }
1651
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001652 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001653 public final IServiceConnection getServiceDispatcher(ServiceConnection c,
1654 Context context, Handler handler, int flags) {
Bo Liu58a57662019-03-06 20:21:45 +00001655 return getServiceDispatcherCommon(c, context, handler, null, flags);
1656 }
1657
1658 public final IServiceConnection getServiceDispatcher(ServiceConnection c,
1659 Context context, Executor executor, int flags) {
1660 return getServiceDispatcherCommon(c, context, null, executor, flags);
1661 }
1662
1663 private IServiceConnection getServiceDispatcherCommon(ServiceConnection c,
1664 Context context, Handler handler, Executor executor, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001665 synchronized (mServices) {
1666 LoadedApk.ServiceDispatcher sd = null;
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001667 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001668 if (map != null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001669 if (DEBUG) Slog.d(TAG, "Returning existing dispatcher " + sd + " for conn " + c);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001670 sd = map.get(c);
1671 }
1672 if (sd == null) {
Bo Liu58a57662019-03-06 20:21:45 +00001673 if (executor != null) {
1674 sd = new ServiceDispatcher(c, context, executor, flags);
1675 } else {
1676 sd = new ServiceDispatcher(c, context, handler, flags);
1677 }
Dianne Hackborn94846032017-03-31 17:55:23 -07001678 if (DEBUG) Slog.d(TAG, "Creating new dispatcher " + sd + " for conn " + c);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001679 if (map == null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001680 map = new ArrayMap<>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001681 mServices.put(context, map);
1682 }
1683 map.put(c, sd);
1684 } else {
Bo Liu58a57662019-03-06 20:21:45 +00001685 sd.validate(context, handler, executor);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001686 }
1687 return sd.getIServiceConnection();
1688 }
1689 }
1690
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08001691 @UnsupportedAppUsage
1692 public IServiceConnection lookupServiceDispatcher(ServiceConnection c,
1693 Context context) {
1694 synchronized (mServices) {
1695 LoadedApk.ServiceDispatcher sd = null;
1696 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
1697 if (map != null) {
1698 sd = map.get(c);
1699 }
1700 return sd != null ? sd.getIServiceConnection() : null;
1701 }
1702 }
1703
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001704 public final IServiceConnection forgetServiceDispatcher(Context context,
1705 ServiceConnection c) {
1706 synchronized (mServices) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001707 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001708 = mServices.get(context);
1709 LoadedApk.ServiceDispatcher sd = null;
1710 if (map != null) {
1711 sd = map.get(c);
1712 if (sd != null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001713 if (DEBUG) Slog.d(TAG, "Removing dispatcher " + sd + " for conn " + c);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001714 map.remove(c);
1715 sd.doForget();
1716 if (map.size() == 0) {
1717 mServices.remove(context);
1718 }
1719 if ((sd.getFlags()&Context.BIND_DEBUG_UNBIND) != 0) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001720 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> holder
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001721 = mUnboundServices.get(context);
1722 if (holder == null) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001723 holder = new ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001724 mUnboundServices.put(context, holder);
1725 }
1726 RuntimeException ex = new IllegalArgumentException(
1727 "Originally unbound here:");
1728 ex.fillInStackTrace();
1729 sd.setUnbindLocation(ex);
1730 holder.put(c, sd);
1731 }
1732 return sd.getIServiceConnection();
1733 }
1734 }
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001735 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> holder
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001736 = mUnboundServices.get(context);
1737 if (holder != null) {
1738 sd = holder.get(c);
1739 if (sd != null) {
1740 RuntimeException ex = sd.getUnbindLocation();
1741 throw new IllegalArgumentException(
1742 "Unbinding Service " + c
1743 + " that was already unbound", ex);
1744 }
1745 }
1746 if (context == null) {
1747 throw new IllegalStateException("Unbinding Service " + c
1748 + " from Context that is no longer in use: " + context);
1749 } else {
1750 throw new IllegalArgumentException("Service not registered: " + c);
1751 }
1752 }
1753 }
1754
1755 static final class ServiceDispatcher {
1756 private final ServiceDispatcher.InnerConnection mIServiceConnection;
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001757 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001758 private final ServiceConnection mConnection;
Mathew Inwood8c854f82018-09-14 12:35:36 +01001759 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001760 private final Context mContext;
1761 private final Handler mActivityThread;
Bo Liu58a57662019-03-06 20:21:45 +00001762 private final Executor mActivityExecutor;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001763 private final ServiceConnectionLeaked mLocation;
1764 private final int mFlags;
1765
1766 private RuntimeException mUnbindLocation;
1767
Dianne Hackborn5a6ef732011-11-11 12:31:52 -08001768 private boolean mForgotten;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001769
1770 private static class ConnectionInfo {
1771 IBinder binder;
1772 IBinder.DeathRecipient deathMonitor;
1773 }
1774
1775 private static class InnerConnection extends IServiceConnection.Stub {
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001776 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001777 final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;
1778
1779 InnerConnection(LoadedApk.ServiceDispatcher sd) {
1780 mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
1781 }
1782
Dianne Hackborn94846032017-03-31 17:55:23 -07001783 public void connected(ComponentName name, IBinder service, boolean dead)
1784 throws RemoteException {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001785 LoadedApk.ServiceDispatcher sd = mDispatcher.get();
1786 if (sd != null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001787 sd.connected(name, service, dead);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001788 }
1789 }
1790 }
1791
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001792 private final ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo> mActiveConnections
1793 = new ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001794
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001795 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001796 ServiceDispatcher(ServiceConnection conn,
1797 Context context, Handler activityThread, int flags) {
1798 mIServiceConnection = new InnerConnection(this);
1799 mConnection = conn;
1800 mContext = context;
1801 mActivityThread = activityThread;
Bo Liu58a57662019-03-06 20:21:45 +00001802 mActivityExecutor = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001803 mLocation = new ServiceConnectionLeaked(null);
1804 mLocation.fillInStackTrace();
1805 mFlags = flags;
1806 }
1807
Bo Liu58a57662019-03-06 20:21:45 +00001808 ServiceDispatcher(ServiceConnection conn,
1809 Context context, Executor activityExecutor, int flags) {
1810 mIServiceConnection = new InnerConnection(this);
1811 mConnection = conn;
1812 mContext = context;
1813 mActivityThread = null;
1814 mActivityExecutor = activityExecutor;
1815 mLocation = new ServiceConnectionLeaked(null);
1816 mLocation.fillInStackTrace();
1817 mFlags = flags;
1818 }
1819
1820 void validate(Context context, Handler activityThread, Executor activityExecutor) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001821 if (mContext != context) {
1822 throw new RuntimeException(
1823 "ServiceConnection " + mConnection +
1824 " registered with differing Context (was " +
1825 mContext + " now " + context + ")");
1826 }
1827 if (mActivityThread != activityThread) {
1828 throw new RuntimeException(
1829 "ServiceConnection " + mConnection +
1830 " registered with differing handler (was " +
1831 mActivityThread + " now " + activityThread + ")");
1832 }
Bo Liu58a57662019-03-06 20:21:45 +00001833 if (mActivityExecutor != activityExecutor) {
1834 throw new RuntimeException(
1835 "ServiceConnection " + mConnection +
1836 " registered with differing executor (was " +
1837 mActivityExecutor + " now " + activityExecutor + ")");
1838 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001839 }
1840
1841 void doForget() {
1842 synchronized(this) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001843 for (int i=0; i<mActiveConnections.size(); i++) {
1844 ServiceDispatcher.ConnectionInfo ci = mActiveConnections.valueAt(i);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001845 ci.binder.unlinkToDeath(ci.deathMonitor, 0);
1846 }
1847 mActiveConnections.clear();
Dianne Hackborn5a6ef732011-11-11 12:31:52 -08001848 mForgotten = true;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001849 }
1850 }
1851
1852 ServiceConnectionLeaked getLocation() {
1853 return mLocation;
1854 }
1855
1856 ServiceConnection getServiceConnection() {
1857 return mConnection;
1858 }
1859
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001860 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001861 IServiceConnection getIServiceConnection() {
1862 return mIServiceConnection;
1863 }
1864
1865 int getFlags() {
1866 return mFlags;
1867 }
1868
1869 void setUnbindLocation(RuntimeException ex) {
1870 mUnbindLocation = ex;
1871 }
1872
1873 RuntimeException getUnbindLocation() {
1874 return mUnbindLocation;
1875 }
1876
Dianne Hackborn94846032017-03-31 17:55:23 -07001877 public void connected(ComponentName name, IBinder service, boolean dead) {
Bo Liu58a57662019-03-06 20:21:45 +00001878 if (mActivityExecutor != null) {
1879 mActivityExecutor.execute(new RunConnection(name, service, 0, dead));
1880 } else if (mActivityThread != null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001881 mActivityThread.post(new RunConnection(name, service, 0, dead));
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001882 } else {
Dianne Hackborn94846032017-03-31 17:55:23 -07001883 doConnected(name, service, dead);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001884 }
1885 }
1886
1887 public void death(ComponentName name, IBinder service) {
Bo Liu58a57662019-03-06 20:21:45 +00001888 if (mActivityExecutor != null) {
1889 mActivityExecutor.execute(new RunConnection(name, service, 1, false));
1890 } else if (mActivityThread != null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001891 mActivityThread.post(new RunConnection(name, service, 1, false));
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001892 } else {
1893 doDeath(name, service);
1894 }
1895 }
1896
Dianne Hackborn94846032017-03-31 17:55:23 -07001897 public void doConnected(ComponentName name, IBinder service, boolean dead) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001898 ServiceDispatcher.ConnectionInfo old;
1899 ServiceDispatcher.ConnectionInfo info;
1900
1901 synchronized (this) {
Dianne Hackborn5a6ef732011-11-11 12:31:52 -08001902 if (mForgotten) {
1903 // We unbound before receiving the connection; ignore
1904 // any connection received.
1905 return;
1906 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001907 old = mActiveConnections.get(name);
1908 if (old != null && old.binder == service) {
1909 // Huh, already have this one. Oh well!
1910 return;
1911 }
1912
1913 if (service != null) {
1914 // A new service is being connected... set it all up.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001915 info = new ConnectionInfo();
1916 info.binder = service;
1917 info.deathMonitor = new DeathMonitor(name, service);
1918 try {
1919 service.linkToDeath(info.deathMonitor, 0);
1920 mActiveConnections.put(name, info);
1921 } catch (RemoteException e) {
1922 // This service was dead before we got it... just
1923 // don't do anything with it.
1924 mActiveConnections.remove(name);
1925 return;
1926 }
1927
1928 } else {
1929 // The named service is being disconnected... clean up.
1930 mActiveConnections.remove(name);
1931 }
1932
1933 if (old != null) {
1934 old.binder.unlinkToDeath(old.deathMonitor, 0);
1935 }
1936 }
1937
Adrian Roosa9b43182016-07-21 13:20:38 -07001938 // If there was an old service, it is now disconnected.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001939 if (old != null) {
1940 mConnection.onServiceDisconnected(name);
1941 }
Dianne Hackborn94846032017-03-31 17:55:23 -07001942 if (dead) {
Dianne Hackbornac265342017-04-19 14:53:18 -07001943 mConnection.onBindingDied(name);
Dianne Hackborn94846032017-03-31 17:55:23 -07001944 }
Christopher Tate5d73b6d2017-10-06 16:15:34 -07001945 // If there is a new viable service, it is now connected.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001946 if (service != null) {
1947 mConnection.onServiceConnected(name, service);
Christopher Tate5d73b6d2017-10-06 16:15:34 -07001948 } else {
1949 // The binding machinery worked, but the remote returned null from onBind().
1950 mConnection.onNullBinding(name);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001951 }
1952 }
1953
1954 public void doDeath(ComponentName name, IBinder service) {
Adrian Roosa9b43182016-07-21 13:20:38 -07001955 synchronized (this) {
1956 ConnectionInfo old = mActiveConnections.get(name);
1957 if (old == null || old.binder != service) {
1958 // Death for someone different than who we last
1959 // reported... just ignore it.
1960 return;
1961 }
1962 mActiveConnections.remove(name);
1963 old.binder.unlinkToDeath(old.deathMonitor, 0);
1964 }
1965
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001966 mConnection.onServiceDisconnected(name);
1967 }
1968
1969 private final class RunConnection implements Runnable {
Dianne Hackborn94846032017-03-31 17:55:23 -07001970 RunConnection(ComponentName name, IBinder service, int command, boolean dead) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001971 mName = name;
1972 mService = service;
1973 mCommand = command;
Dianne Hackborn94846032017-03-31 17:55:23 -07001974 mDead = dead;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001975 }
1976
1977 public void run() {
1978 if (mCommand == 0) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001979 doConnected(mName, mService, mDead);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001980 } else if (mCommand == 1) {
1981 doDeath(mName, mService);
1982 }
1983 }
1984
1985 final ComponentName mName;
1986 final IBinder mService;
1987 final int mCommand;
Dianne Hackborn94846032017-03-31 17:55:23 -07001988 final boolean mDead;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001989 }
1990
1991 private final class DeathMonitor implements IBinder.DeathRecipient
1992 {
1993 DeathMonitor(ComponentName name, IBinder service) {
1994 mName = name;
1995 mService = service;
1996 }
1997
1998 public void binderDied() {
1999 death(mName, mService);
2000 }
2001
2002 final ComponentName mName;
2003 final IBinder mService;
2004 }
2005 }
2006}