blob: 44c248637f491a80ff2a326815d0636c9433cf34 [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;
Artur Satayevc895b1b2019-12-10 17:47:51 +000021import android.compat.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;
Justin Yun1ef374f2019-12-17 15:15:34 +090049import android.sysprop.VndkProperties;
Jeff Sharkey8a372a02016-03-16 16:25:45 -060050import android.text.TextUtils;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070051import android.util.AndroidRuntimeException;
Jeff Sharkey8a372a02016-03-16 16:25:45 -060052import android.util.ArrayMap;
Adam Lesinski2cb761e2014-08-15 13:59:02 -070053import android.util.Log;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070054import android.util.Slog;
Adam Lesinskide898ff2014-01-29 18:20:45 -080055import android.util.SparseArray;
Jeff Browna492c3a2012-08-23 19:48:44 -070056import android.view.Display;
Jeff Sharkey8a372a02016-03-16 16:25:45 -060057import android.view.DisplayAdjustments;
Calin Juravle6ae39fc2018-01-19 20:32:47 -080058
Adam Lesinski4e862812016-11-21 16:02:24 -080059import com.android.internal.util.ArrayUtils;
Calin Juravle6ae39fc2018-01-19 20:32:47 -080060
David Brazdil991ff902018-12-03 10:59:29 +000061import dalvik.system.BaseDexClassLoader;
Narayan Kamath7dba6eb2014-07-16 08:53:30 +010062import dalvik.system.VMRuntime;
Calin Juravle6ae39fc2018-01-19 20:32:47 -080063
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070064import java.io.File;
65import java.io.IOException;
66import java.io.InputStream;
67import java.lang.ref.WeakReference;
Adam Lesinski1e4663852014-08-15 14:47:28 -070068import java.lang.reflect.InvocationTargetException;
69import java.lang.reflect.Method;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070070import java.net.URL;
Jiyong Park29d9eba2018-05-04 12:44:38 +090071import java.nio.file.Paths;
Jeff Sharkey8a4c9722014-06-16 13:48:42 -070072import java.util.ArrayList;
Adam Lesinski4e862812016-11-21 16:02:24 -080073import java.util.Arrays;
Jeff Sharkey8a4c9722014-06-16 13:48:42 -070074import java.util.Collections;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070075import java.util.Enumeration;
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +000076import java.util.LinkedHashSet;
Jeff Sharkey8a372a02016-03-16 16:25:45 -060077import java.util.List;
Narayan Kamath20531682014-07-14 13:18:43 +010078import java.util.Objects;
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +000079import java.util.Set;
Bo Liu58a57662019-03-06 20:21:45 +000080import java.util.concurrent.Executor;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070081
82final class IntentReceiverLeaked extends AndroidRuntimeException {
Mathew Inwood61e8ae62018-08-14 14:17:44 +010083 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070084 public IntentReceiverLeaked(String msg) {
85 super(msg);
86 }
87}
88
89final class ServiceConnectionLeaked extends AndroidRuntimeException {
Mathew Inwood61e8ae62018-08-14 14:17:44 +010090 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070091 public ServiceConnectionLeaked(String msg) {
92 super(msg);
93 }
94}
95
96/**
97 * Local state maintained about a currently loaded .apk.
98 * @hide
99 */
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700100public final class LoadedApk {
Dianne Hackborn94846032017-03-31 17:55:23 -0700101 static final String TAG = "LoadedApk";
102 static final boolean DEBUG = false;
Patrick Baumann1bea2372018-03-13 14:26:58 -0700103 private static final String PROPERTY_NAME_APPEND_NATIVE = "pi.append_native_lib_paths";
Amith Yamasani742a6712011-05-04 14:49:28 -0700104
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100105 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700106 private final ActivityThread mActivityThread;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100107 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700108 final String mPackageName;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100109 @UnsupportedAppUsage
Todd Kennedy39bfee52016-02-24 10:28:21 -0800110 private ApplicationInfo mApplicationInfo;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100111 @UnsupportedAppUsage
Todd Kennedy39bfee52016-02-24 10:28:21 -0800112 private String mAppDir;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100113 @UnsupportedAppUsage
Todd Kennedy39bfee52016-02-24 10:28:21 -0800114 private String mResDir;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800115 private String[] mOverlayDirs;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100116 @UnsupportedAppUsage
Todd Kennedy39bfee52016-02-24 10:28:21 -0800117 private String mDataDir;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100118 @UnsupportedAppUsage
Todd Kennedy39bfee52016-02-24 10:28:21 -0800119 private String mLibDir;
Mathew Inwood8c854f82018-09-14 12:35:36 +0100120 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Todd Kennedy39bfee52016-02-24 10:28:21 -0800121 private File mDataDirFile;
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600122 private File mDeviceProtectedDataDirFile;
123 private File mCredentialProtectedDataDirFile;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100124 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700125 private final ClassLoader mBaseClassLoader;
David Brazdilfd6dcc22018-10-25 14:07:51 +0100126 private ClassLoader mDefaultClassLoader;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700127 private final boolean mSecurityViolation;
128 private final boolean mIncludeCode;
Dianne Hackbornfee756f2014-07-16 17:31:10 -0700129 private final boolean mRegisterPackage;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100130 @UnsupportedAppUsage
Craig Mautner48d0d182013-06-11 07:53:06 -0700131 private final DisplayAdjustments mDisplayAdjustments = new DisplayAdjustments();
Todd Kennedy39bfee52016-02-24 10:28:21 -0800132 /** WARNING: This may change. Don't hold external references to it. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100133 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700134 Resources mResources;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100135 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700136 private ClassLoader mClassLoader;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100137 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700138 private Application mApplication;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700139
Adam Lesinski4e862812016-11-21 16:02:24 -0800140 private String[] mSplitNames;
141 private String[] mSplitAppDirs;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100142 @UnsupportedAppUsage
Adam Lesinski4e862812016-11-21 16:02:24 -0800143 private String[] mSplitResDirs;
Narayan Kamathf9419f02017-06-15 11:35:38 +0100144 private String[] mSplitClassLoaderNames;
Adam Lesinski4e862812016-11-21 16:02:24 -0800145
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100146 @UnsupportedAppUsage
Dianne Hackbornadd005c2013-07-17 18:43:12 -0700147 private final ArrayMap<Context, ArrayMap<BroadcastReceiver, ReceiverDispatcher>> mReceivers
Adam Lesinski4e862812016-11-21 16:02:24 -0800148 = new ArrayMap<>();
Dianne Hackbornadd005c2013-07-17 18:43:12 -0700149 private final ArrayMap<Context, ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>> mUnregisteredReceivers
Adam Lesinski4e862812016-11-21 16:02:24 -0800150 = new ArrayMap<>();
Mathew Inwood8c854f82018-09-14 12:35:36 +0100151 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Dianne Hackbornadd005c2013-07-17 18:43:12 -0700152 private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mServices
Adam Lesinski4e862812016-11-21 16:02:24 -0800153 = new ArrayMap<>();
Dianne Hackbornadd005c2013-07-17 18:43:12 -0700154 private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mUnboundServices
Adam Lesinski4e862812016-11-21 16:02:24 -0800155 = new ArrayMap<>();
Jason Monka80bfb52017-11-16 17:15:37 -0500156 private AppComponentFactory mAppComponentFactory;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700157
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700158 Application getApplication() {
159 return mApplication;
160 }
161
Dianne Hackborn2f0b1752011-05-31 17:59:49 -0700162 /**
163 * Create information about a new .apk
164 *
165 * NOTE: This constructor is called with ActivityThread's lock held,
166 * so MUST NOT call back out to the activity manager.
167 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700168 public LoadedApk(ActivityThread activityThread, ApplicationInfo aInfo,
Jeff Browndefd4a62014-03-10 21:24:37 -0700169 CompatibilityInfo compatInfo, ClassLoader baseLoader,
Dianne Hackbornfee756f2014-07-16 17:31:10 -0700170 boolean securityViolation, boolean includeCode, boolean registerPackage) {
Narayan Kamath7dba6eb2014-07-16 08:53:30 +0100171
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700172 mActivityThread = activityThread;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800173 setApplicationInfo(aInfo);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700174 mPackageName = aInfo.packageName;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700175 mBaseClassLoader = baseLoader;
176 mSecurityViolation = securityViolation;
177 mIncludeCode = includeCode;
Dianne Hackbornfee756f2014-07-16 17:31:10 -0700178 mRegisterPackage = registerPackage;
Craig Mautner48d0d182013-06-11 07:53:06 -0700179 mDisplayAdjustments.setCompatibilityInfo(compatInfo);
Jason Monka80bfb52017-11-16 17:15:37 -0500180 mAppComponentFactory = createAppFactory(mApplicationInfo, mBaseClassLoader);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700181 }
182
Narayan Kamath7dba6eb2014-07-16 08:53:30 +0100183 private static ApplicationInfo adjustNativeLibraryPaths(ApplicationInfo info) {
184 // If we're dealing with a multi-arch application that has both
185 // 32 and 64 bit shared libraries, we might need to choose the secondary
186 // depending on what the current runtime's instruction set is.
187 if (info.primaryCpuAbi != null && info.secondaryCpuAbi != null) {
188 final String runtimeIsa = VMRuntime.getRuntime().vmInstructionSet();
jgu214741cd92014-12-17 17:23:29 -0500189
190 // Get the instruction set that the libraries of secondary Abi is supported.
191 // In presence of a native bridge this might be different than the one secondary Abi used.
192 String secondaryIsa = VMRuntime.getInstructionSet(info.secondaryCpuAbi);
193 final String secondaryDexCodeIsa = SystemProperties.get("ro.dalvik.vm.isa." + secondaryIsa);
194 secondaryIsa = secondaryDexCodeIsa.isEmpty() ? secondaryIsa : secondaryDexCodeIsa;
Narayan Kamath7dba6eb2014-07-16 08:53:30 +0100195
196 // If the runtimeIsa is the same as the primary isa, then we do nothing.
197 // Everything will be set up correctly because info.nativeLibraryDir will
198 // correspond to the right ISA.
199 if (runtimeIsa.equals(secondaryIsa)) {
200 final ApplicationInfo modified = new ApplicationInfo(info);
201 modified.nativeLibraryDir = modified.secondaryNativeLibraryDir;
Dmitriy Ivanove56b3f62015-06-05 22:00:13 -0700202 modified.primaryCpuAbi = modified.secondaryCpuAbi;
Narayan Kamath7dba6eb2014-07-16 08:53:30 +0100203 return modified;
204 }
205 }
206
207 return info;
208 }
209
Jeff Browndefd4a62014-03-10 21:24:37 -0700210 /**
211 * Create information about the system package.
212 * Must call {@link #installSystemApplicationInfo} later.
213 */
214 LoadedApk(ActivityThread activityThread) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700215 mActivityThread = activityThread;
Jeff Browndefd4a62014-03-10 21:24:37 -0700216 mApplicationInfo = new ApplicationInfo();
217 mApplicationInfo.packageName = "android";
218 mPackageName = "android";
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700219 mAppDir = null;
220 mResDir = null;
Jeff Sharkey8a4c9722014-06-16 13:48:42 -0700221 mSplitAppDirs = null;
222 mSplitResDirs = null;
Narayan Kamathf9419f02017-06-15 11:35:38 +0100223 mSplitClassLoaderNames = null;
MÃ¥rten Kongstad48d22322014-01-31 14:43:27 +0100224 mOverlayDirs = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700225 mDataDir = null;
226 mDataDirFile = null;
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600227 mDeviceProtectedDataDirFile = null;
228 mCredentialProtectedDataDirFile = null;
Kenny Root85387d72010-08-26 10:13:11 -0700229 mLibDir = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700230 mBaseClassLoader = null;
231 mSecurityViolation = false;
232 mIncludeCode = true;
Dianne Hackbornfee756f2014-07-16 17:31:10 -0700233 mRegisterPackage = false;
Jeff Browndefd4a62014-03-10 21:24:37 -0700234 mResources = Resources.getSystem();
David Brazdilfd6dcc22018-10-25 14:07:51 +0100235 mDefaultClassLoader = ClassLoader.getSystemClassLoader();
236 mAppComponentFactory = createAppFactory(mApplicationInfo, mDefaultClassLoader);
David Brazdil33bd3432019-02-27 20:15:18 +0000237 mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader,
238 new ApplicationInfo(mApplicationInfo));
Jeff Browndefd4a62014-03-10 21:24:37 -0700239 }
240
241 /**
242 * Sets application info about the system package.
243 */
Narayan Kamath29564cd2014-08-07 10:57:40 +0100244 void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
Jeff Browndefd4a62014-03-10 21:24:37 -0700245 assert info.packageName.equals("android");
246 mApplicationInfo = info;
David Brazdilfd6dcc22018-10-25 14:07:51 +0100247 mDefaultClassLoader = classLoader;
248 mAppComponentFactory = createAppFactory(info, mDefaultClassLoader);
David Brazdil33bd3432019-02-27 20:15:18 +0000249 mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader,
250 new ApplicationInfo(mApplicationInfo));
Jason Monka80bfb52017-11-16 17:15:37 -0500251 }
252
253 private AppComponentFactory createAppFactory(ApplicationInfo appInfo, ClassLoader cl) {
Winson13fb2ca2020-01-10 15:21:36 -0800254 if (mIncludeCode && appInfo.appComponentFactory != null && cl != null) {
Jason Monka80bfb52017-11-16 17:15:37 -0500255 try {
David Brazdil33bd3432019-02-27 20:15:18 +0000256 return (AppComponentFactory)
257 cl.loadClass(appInfo.appComponentFactory).newInstance();
Jason Monka80bfb52017-11-16 17:15:37 -0500258 } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
259 Slog.e(TAG, "Unable to instantiate appComponentFactory", e);
260 }
261 }
262 return AppComponentFactory.DEFAULT;
263 }
264
265 public AppComponentFactory getAppFactory() {
266 return mAppComponentFactory;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700267 }
268
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100269 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700270 public String getPackageName() {
271 return mPackageName;
272 }
273
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100274 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700275 public ApplicationInfo getApplicationInfo() {
276 return mApplicationInfo;
277 }
278
Jeff Sharkey369f5092016-02-29 11:16:21 -0700279 public int getTargetSdkVersion() {
280 return mApplicationInfo.targetSdkVersion;
281 }
282
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700283 public boolean isSecurityViolation() {
284 return mSecurityViolation;
285 }
286
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100287 @UnsupportedAppUsage
Craig Mautner48d0d182013-06-11 07:53:06 -0700288 public CompatibilityInfo getCompatibilityInfo() {
289 return mDisplayAdjustments.getCompatibilityInfo();
290 }
291
292 public void setCompatibilityInfo(CompatibilityInfo compatInfo) {
293 mDisplayAdjustments.setCompatibilityInfo(compatInfo);
294 }
295
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700296 /**
297 * Gets the array of shared libraries that are listed as
298 * used by the given package.
299 *
300 * @param packageName the name of the package (note: not its
301 * file name)
302 * @return null-ok; the array of shared libraries, each one
303 * a fully-qualified path
304 */
305 private static String[] getLibrariesFor(String packageName) {
306 ApplicationInfo ai = null;
307 try {
308 ai = ActivityThread.getPackageManager().getApplicationInfo(packageName,
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700309 PackageManager.GET_SHARED_LIBRARY_FILES, UserHandle.myUserId());
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700310 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700311 throw e.rethrowFromSystemServer();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700312 }
313
314 if (ai == null) {
315 return null;
316 }
317
318 return ai.sharedLibraryFiles;
319 }
320
Adam Lesinskid33ef562017-01-19 14:49:59 -0800321 /**
322 * Update the ApplicationInfo for an app. If oldPaths is null, all the paths are considered
323 * new.
324 * @param aInfo The new ApplicationInfo to use for this LoadedApk
325 * @param oldPaths The code paths for the old ApplicationInfo object. null means no paths can
326 * be reused.
327 */
328 public void updateApplicationInfo(@NonNull ApplicationInfo aInfo,
329 @Nullable List<String> oldPaths) {
Todd Kennedy39bfee52016-02-24 10:28:21 -0800330 setApplicationInfo(aInfo);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700331
Todd Kennedy39bfee52016-02-24 10:28:21 -0800332 final List<String> newPaths = new ArrayList<>();
Dimitry Ivanov638d8102017-02-22 15:39:42 -0800333 makePaths(mActivityThread, aInfo, newPaths);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800334 final List<String> addedPaths = new ArrayList<>(newPaths.size());
335
336 if (oldPaths != null) {
337 for (String path : newPaths) {
338 final String apkName = path.substring(path.lastIndexOf(File.separator));
339 boolean match = false;
340 for (String oldPath : oldPaths) {
Adam Lesinskia5ca6242017-03-01 15:45:12 -0800341 final String oldApkName = oldPath.substring(oldPath.lastIndexOf(File.separator));
Todd Kennedy39bfee52016-02-24 10:28:21 -0800342 if (apkName.equals(oldApkName)) {
343 match = true;
344 break;
345 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700346 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800347 if (!match) {
348 addedPaths.add(path);
349 }
350 }
351 } else {
352 addedPaths.addAll(newPaths);
353 }
354 synchronized (this) {
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700355 createOrUpdateClassLoaderLocked(addedPaths);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800356 if (mResources != null) {
Adam Lesinski4e862812016-11-21 16:02:24 -0800357 final String[] splitPaths;
358 try {
359 splitPaths = getSplitPaths(null);
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800360 } catch (NameNotFoundException e) {
Adam Lesinski4e862812016-11-21 16:02:24 -0800361 // This should NEVER fail.
362 throw new AssertionError("null split not found");
363 }
364
365 mResources = ResourcesManager.getInstance().getResources(null, mResDir,
Adam Lesinski0e618832017-02-07 11:40:12 -0800366 splitPaths, mOverlayDirs, mApplicationInfo.sharedLibraryFiles,
Adam Lesinski4e862812016-11-21 16:02:24 -0800367 Display.DEFAULT_DISPLAY, null, getCompatibilityInfo(),
Ryan Mitchell4579c0a2020-01-08 16:29:11 -0800368 getClassLoader(), mApplication == null ? null
369 : mApplication.getResources().getLoaders());
Todd Kennedy39bfee52016-02-24 10:28:21 -0800370 }
371 }
David Brazdilfd6dcc22018-10-25 14:07:51 +0100372 mAppComponentFactory = createAppFactory(aInfo, mDefaultClassLoader);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800373 }
374
375 private void setApplicationInfo(ApplicationInfo aInfo) {
376 final int myUid = Process.myUid();
377 aInfo = adjustNativeLibraryPaths(aInfo);
378 mApplicationInfo = aInfo;
379 mAppDir = aInfo.sourceDir;
380 mResDir = aInfo.uid == myUid ? aInfo.sourceDir : aInfo.publicSourceDir;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800381 mOverlayDirs = aInfo.resourceDirs;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800382 mDataDir = aInfo.dataDir;
383 mLibDir = aInfo.nativeLibraryDir;
384 mDataDirFile = FileUtils.newFileOrNull(aInfo.dataDir);
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600385 mDeviceProtectedDataDirFile = FileUtils.newFileOrNull(aInfo.deviceProtectedDataDir);
386 mCredentialProtectedDataDirFile = FileUtils.newFileOrNull(aInfo.credentialProtectedDataDir);
Adam Lesinski4e862812016-11-21 16:02:24 -0800387
388 mSplitNames = aInfo.splitNames;
389 mSplitAppDirs = aInfo.splitSourceDirs;
390 mSplitResDirs = aInfo.uid == myUid ? aInfo.splitSourceDirs : aInfo.splitPublicSourceDirs;
Narayan Kamathf9419f02017-06-15 11:35:38 +0100391 mSplitClassLoaderNames = aInfo.splitClassLoaderNames;
Adam Lesinski4e862812016-11-21 16:02:24 -0800392
393 if (aInfo.requestsIsolatedSplitLoading() && !ArrayUtils.isEmpty(mSplitNames)) {
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800394 mSplitLoader = new SplitDependencyLoaderImpl(aInfo.splitDependencies);
Adam Lesinski4e862812016-11-21 16:02:24 -0800395 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800396 }
397
Dimitry Ivanov638d8102017-02-22 15:39:42 -0800398 public static void makePaths(ActivityThread activityThread,
399 ApplicationInfo aInfo,
400 List<String> outZipPaths) {
401 makePaths(activityThread, false, aInfo, outZipPaths, null);
402 }
403
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000404 private static void appendSharedLibrariesLibPathsIfNeeded(
405 List<SharedLibraryInfo> sharedLibraries, ApplicationInfo aInfo,
406 Set<String> outSeenPaths,
407 List<String> outLibPaths) {
408 if (sharedLibraries == null) {
409 return;
410 }
411 for (SharedLibraryInfo lib : sharedLibraries) {
412 List<String> paths = lib.getAllCodePaths();
413 outSeenPaths.addAll(paths);
414 for (String path : paths) {
415 appendApkLibPathIfNeeded(path, aInfo, outLibPaths);
416 }
417 appendSharedLibrariesLibPathsIfNeeded(
418 lib.getDependencies(), aInfo, outSeenPaths, outLibPaths);
419 }
420 }
421
Dimitry Ivanov638d8102017-02-22 15:39:42 -0800422 public static void makePaths(ActivityThread activityThread,
423 boolean isBundledApp,
424 ApplicationInfo aInfo,
425 List<String> outZipPaths,
426 List<String> outLibPaths) {
Todd Kennedy39bfee52016-02-24 10:28:21 -0800427 final String appDir = aInfo.sourceDir;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800428 final String libDir = aInfo.nativeLibraryDir;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800429
430 outZipPaths.clear();
431 outZipPaths.add(appDir);
Adam Lesinski4e862812016-11-21 16:02:24 -0800432
433 // Do not load all available splits if the app requested isolated split loading.
434 if (aInfo.splitSourceDirs != null && !aInfo.requestsIsolatedSplitLoading()) {
435 Collections.addAll(outZipPaths, aInfo.splitSourceDirs);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800436 }
437
438 if (outLibPaths != null) {
439 outLibPaths.clear();
440 }
441
442 /*
443 * The following is a bit of a hack to inject
444 * instrumentation into the system: If the app
445 * being started matches one of the instrumentation names,
446 * then we combine both the "instrumentation" and
447 * "instrumented" app into the path, along with the
448 * concatenation of both apps' shared library lists.
449 */
450
Todd Kennedy39bfee52016-02-24 10:28:21 -0800451 String[] instrumentationLibs = null;
Torne (Richard Coles)3b6ca992016-10-10 15:11:36 +0100452 // activityThread will be null when called from the WebView zygote; just assume
453 // no instrumentation applies in this case.
454 if (activityThread != null) {
455 String instrumentationPackageName = activityThread.mInstrumentationPackageName;
456 String instrumentationAppDir = activityThread.mInstrumentationAppDir;
457 String[] instrumentationSplitAppDirs = activityThread.mInstrumentationSplitAppDirs;
458 String instrumentationLibDir = activityThread.mInstrumentationLibDir;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800459
Torne (Richard Coles)3b6ca992016-10-10 15:11:36 +0100460 String instrumentedAppDir = activityThread.mInstrumentedAppDir;
461 String[] instrumentedSplitAppDirs = activityThread.mInstrumentedSplitAppDirs;
462 String instrumentedLibDir = activityThread.mInstrumentedLibDir;
463
464 if (appDir.equals(instrumentationAppDir)
465 || appDir.equals(instrumentedAppDir)) {
466 outZipPaths.clear();
467 outZipPaths.add(instrumentationAppDir);
Jason O'Brien6f2978c92020-01-08 11:03:37 -0600468 if (!instrumentationAppDir.equals(instrumentedAppDir)) {
469 outZipPaths.add(instrumentedAppDir);
470 }
Adam Lesinski4e862812016-11-21 16:02:24 -0800471
472 // Only add splits if the app did not request isolated split loading.
473 if (!aInfo.requestsIsolatedSplitLoading()) {
474 if (instrumentationSplitAppDirs != null) {
475 Collections.addAll(outZipPaths, instrumentationSplitAppDirs);
476 }
477
478 if (!instrumentationAppDir.equals(instrumentedAppDir)) {
Adam Lesinski4e862812016-11-21 16:02:24 -0800479 if (instrumentedSplitAppDirs != null) {
480 Collections.addAll(outZipPaths, instrumentedSplitAppDirs);
481 }
Torne (Richard Coles)3b6ca992016-10-10 15:11:36 +0100482 }
Jeff Haoc7b94822016-03-16 15:56:07 -0700483 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800484
Torne (Richard Coles)3b6ca992016-10-10 15:11:36 +0100485 if (outLibPaths != null) {
486 outLibPaths.add(instrumentationLibDir);
487 if (!instrumentationLibDir.equals(instrumentedLibDir)) {
488 outLibPaths.add(instrumentedLibDir);
489 }
490 }
491
492 if (!instrumentedAppDir.equals(instrumentationAppDir)) {
493 instrumentationLibs = getLibrariesFor(instrumentationPackageName);
494 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800495 }
496 }
497
498 if (outLibPaths != null) {
499 if (outLibPaths.isEmpty()) {
500 outLibPaths.add(libDir);
501 }
502
503 // Add path to libraries in apk for current abi. Do this now because more entries
504 // will be added to zipPaths that shouldn't be part of the library path.
505 if (aInfo.primaryCpuAbi != null) {
Alex Light20ed24f2016-04-20 14:07:43 -0700506 // Add fake libs into the library search path if we target prior to N.
Adam Lesinski4e862812016-11-21 16:02:24 -0800507 if (aInfo.targetSdkVersion < Build.VERSION_CODES.N) {
Alex Light20ed24f2016-04-20 14:07:43 -0700508 outLibPaths.add("/system/fake-libs" +
509 (VMRuntime.is64BitAbi(aInfo.primaryCpuAbi) ? "64" : ""));
510 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800511 for (String apk : outZipPaths) {
512 outLibPaths.add(apk + "!/lib/" + aInfo.primaryCpuAbi);
513 }
514 }
515
Dimitry Ivanov638d8102017-02-22 15:39:42 -0800516 if (isBundledApp) {
Todd Kennedy39bfee52016-02-24 10:28:21 -0800517 // Add path to system libraries to libPaths;
518 // Access to system libs should be limited
519 // to bundled applications; this is why updated
520 // system apps are not included.
521 outLibPaths.add(System.getProperty("java.library.path"));
522 }
523 }
524
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000525 // Add the shared libraries native paths. The dex files in shared libraries will
526 // be resolved through shared library loaders, which are setup later.
527 Set<String> outSeenPaths = new LinkedHashSet<>();
528 appendSharedLibrariesLibPathsIfNeeded(
529 aInfo.sharedLibraryInfos, aInfo, outSeenPaths, outLibPaths);
530
531 // ApplicationInfo.sharedLibraryFiles is a public API, so anyone can change it.
532 // We prepend shared libraries that the package manager hasn't seen, maintaining their
533 // original order where possible.
534 if (aInfo.sharedLibraryFiles != null) {
Jeff Hao090892f2017-04-24 17:37:31 -0700535 int index = 0;
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000536 for (String lib : aInfo.sharedLibraryFiles) {
537 if (!outSeenPaths.contains(lib) && !outZipPaths.contains(lib)) {
Jeff Hao090892f2017-04-24 17:37:31 -0700538 outZipPaths.add(index, lib);
539 index++;
Svetoslav Ganov40610e32017-06-20 19:35:51 -0700540 appendApkLibPathIfNeeded(lib, aInfo, outLibPaths);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800541 }
542 }
543 }
544
545 if (instrumentationLibs != null) {
546 for (String lib : instrumentationLibs) {
547 if (!outZipPaths.contains(lib)) {
548 outZipPaths.add(0, lib);
Svetoslav Ganov40610e32017-06-20 19:35:51 -0700549 appendApkLibPathIfNeeded(lib, aInfo, outLibPaths);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800550 }
551 }
552 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800553 }
554
Svetoslav Ganov40610e32017-06-20 19:35:51 -0700555 /**
556 * This method appends a path to the appropriate native library folder of a
557 * library if this library is hosted in an APK. This allows support for native
558 * shared libraries. The library API is determined based on the application
559 * ABI.
560 *
561 * @param path Path to the library.
562 * @param applicationInfo The application depending on the library.
563 * @param outLibPaths List to which to add the native lib path if needed.
564 */
565 private static void appendApkLibPathIfNeeded(@NonNull String path,
566 @NonNull ApplicationInfo applicationInfo, @Nullable List<String> outLibPaths) {
567 // Looking at the suffix is a little hacky but a safe and simple solution.
568 // We will be revisiting code in the next release and clean this up.
569 if (outLibPaths != null && applicationInfo.primaryCpuAbi != null && path.endsWith(".apk")) {
570 if (applicationInfo.targetSdkVersion >= Build.VERSION_CODES.O) {
571 outLibPaths.add(path + "!/lib/" + applicationInfo.primaryCpuAbi);
572 }
573 }
574 }
575
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800576 /*
577 * All indices received by the super class should be shifted by 1 when accessing mSplitNames,
578 * etc. The super class assumes the base APK is index 0, while the PackageManager APIs don't
579 * include the base APK in the list of splits.
580 */
581 private class SplitDependencyLoaderImpl extends SplitDependencyLoader<NameNotFoundException> {
Adam Lesinski4e862812016-11-21 16:02:24 -0800582 private final String[][] mCachedResourcePaths;
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800583 private final ClassLoader[] mCachedClassLoaders;
Adam Lesinski4e862812016-11-21 16:02:24 -0800584
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800585 SplitDependencyLoaderImpl(@NonNull SparseArray<int[]> dependencies) {
Adam Lesinski4e862812016-11-21 16:02:24 -0800586 super(dependencies);
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800587 mCachedResourcePaths = new String[mSplitNames.length + 1][];
588 mCachedClassLoaders = new ClassLoader[mSplitNames.length + 1];
Adam Lesinski4e862812016-11-21 16:02:24 -0800589 }
590
591 @Override
592 protected boolean isSplitCached(int splitIdx) {
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800593 return mCachedClassLoaders[splitIdx] != null;
Adam Lesinski4e862812016-11-21 16:02:24 -0800594 }
595
596 @Override
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800597 protected void constructSplit(int splitIdx, @NonNull int[] configSplitIndices,
598 int parentSplitIdx) throws NameNotFoundException {
Adam Lesinski4e862812016-11-21 16:02:24 -0800599 final ArrayList<String> splitPaths = new ArrayList<>();
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800600 if (splitIdx == 0) {
Adam Lesinski4e862812016-11-21 16:02:24 -0800601 createOrUpdateClassLoaderLocked(null);
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800602 mCachedClassLoaders[0] = mClassLoader;
603
604 // Never add the base resources here, they always get added no matter what.
605 for (int configSplitIdx : configSplitIndices) {
606 splitPaths.add(mSplitResDirs[configSplitIdx - 1]);
607 }
608 mCachedResourcePaths[0] = splitPaths.toArray(new String[splitPaths.size()]);
Adam Lesinski4e862812016-11-21 16:02:24 -0800609 return;
610 }
611
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800612 // Since we handled the special base case above, parentSplitIdx is always valid.
613 final ClassLoader parent = mCachedClassLoaders[parentSplitIdx];
614 mCachedClassLoaders[splitIdx] = ApplicationLoaders.getDefault().getClassLoader(
Narayan Kamathf9419f02017-06-15 11:35:38 +0100615 mSplitAppDirs[splitIdx - 1], getTargetSdkVersion(), false, null, null, parent,
616 mSplitClassLoaderNames[splitIdx - 1]);
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800617
618 Collections.addAll(splitPaths, mCachedResourcePaths[parentSplitIdx]);
619 splitPaths.add(mSplitResDirs[splitIdx - 1]);
620 for (int configSplitIdx : configSplitIndices) {
621 splitPaths.add(mSplitResDirs[configSplitIdx - 1]);
Adam Lesinski4e862812016-11-21 16:02:24 -0800622 }
Adam Lesinski4e862812016-11-21 16:02:24 -0800623 mCachedResourcePaths[splitIdx] = splitPaths.toArray(new String[splitPaths.size()]);
624 }
625
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800626 private int ensureSplitLoaded(String splitName) throws NameNotFoundException {
627 int idx = 0;
628 if (splitName != null) {
Adam Lesinski4e862812016-11-21 16:02:24 -0800629 idx = Arrays.binarySearch(mSplitNames, splitName);
630 if (idx < 0) {
631 throw new PackageManager.NameNotFoundException(
632 "Split name '" + splitName + "' is not installed");
633 }
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800634 idx += 1;
Adam Lesinski4e862812016-11-21 16:02:24 -0800635 }
Adam Lesinski4e862812016-11-21 16:02:24 -0800636 loadDependenciesForSplit(idx);
637 return idx;
638 }
639
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800640 ClassLoader getClassLoaderForSplit(String splitName) throws NameNotFoundException {
641 return mCachedClassLoaders[ensureSplitLoaded(splitName)];
Adam Lesinski4e862812016-11-21 16:02:24 -0800642 }
643
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800644 String[] getSplitPathsForSplit(String splitName) throws NameNotFoundException {
645 return mCachedResourcePaths[ensureSplitLoaded(splitName)];
Adam Lesinski4e862812016-11-21 16:02:24 -0800646 }
647 }
648
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800649 private SplitDependencyLoaderImpl mSplitLoader;
Adam Lesinski4e862812016-11-21 16:02:24 -0800650
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800651 ClassLoader getSplitClassLoader(String splitName) throws NameNotFoundException {
Adam Lesinski4e862812016-11-21 16:02:24 -0800652 if (mSplitLoader == null) {
653 return mClassLoader;
654 }
655 return mSplitLoader.getClassLoaderForSplit(splitName);
656 }
657
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800658 String[] getSplitPaths(String splitName) throws NameNotFoundException {
Adam Lesinski4e862812016-11-21 16:02:24 -0800659 if (mSplitLoader == null) {
660 return mSplitResDirs;
661 }
662 return mSplitLoader.getSplitPathsForSplit(splitName);
663 }
664
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000665 /**
666 * Create a class loader for the {@code sharedLibrary}. Shared libraries are canonicalized,
667 * so if we already created a class loader with that shared library, we return it.
668 *
669 * Implementation notes: the canonicalization of shared libraries is something dex2oat
670 * also does.
671 */
672 ClassLoader createSharedLibraryLoader(SharedLibraryInfo sharedLibrary,
673 boolean isBundledApp, String librarySearchPath, String libraryPermittedPath) {
674 List<String> paths = sharedLibrary.getAllCodePaths();
675 List<ClassLoader> sharedLibraries = createSharedLibrariesLoaders(
676 sharedLibrary.getDependencies(), isBundledApp, librarySearchPath,
677 libraryPermittedPath);
678 final String jars = (paths.size() == 1) ? paths.get(0) :
679 TextUtils.join(File.pathSeparator, paths);
680
681 // Shared libraries get a null parent: this has the side effect of having canonicalized
682 // shared libraries using ApplicationLoaders cache, which is the behavior we want.
Steven Morelandbdc27022019-03-29 21:23:48 +0000683 return ApplicationLoaders.getDefault().getSharedLibraryClassLoaderWithSharedLibraries(jars,
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000684 mApplicationInfo.targetSdkVersion, isBundledApp, librarySearchPath,
685 libraryPermittedPath, /* parent */ null,
686 /* classLoaderName */ null, sharedLibraries);
687 }
688
689 private List<ClassLoader> createSharedLibrariesLoaders(List<SharedLibraryInfo> sharedLibraries,
690 boolean isBundledApp, String librarySearchPath, String libraryPermittedPath) {
691 if (sharedLibraries == null) {
692 return null;
693 }
694 List<ClassLoader> loaders = new ArrayList<>();
695 for (SharedLibraryInfo info : sharedLibraries) {
696 loaders.add(createSharedLibraryLoader(
697 info, isBundledApp, librarySearchPath, libraryPermittedPath));
698 }
699 return loaders;
700 }
701
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100702 private StrictMode.ThreadPolicy allowThreadDiskReads() {
703 if (mActivityThread == null) {
704 // When LoadedApk is used without an ActivityThread (usually in a
705 // zygote context), don't call into StrictMode, as it initializes
706 // the binder subsystem, which we don't want.
707 return null;
708 }
709
710 return StrictMode.allowThreadDiskReads();
711 }
712
713 private void setThreadPolicy(StrictMode.ThreadPolicy policy) {
714 if (mActivityThread != null && policy != null) {
715 StrictMode.setThreadPolicy(policy);
716 }
717 }
718
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700719 private void createOrUpdateClassLoaderLocked(List<String> addedPaths) {
720 if (mPackageName.equals("android")) {
Calin Juravle430ef452016-04-22 17:43:07 +0100721 // Note: This branch is taken for system server and we don't need to setup
722 // jit profiling support.
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700723 if (mClassLoader != null) {
724 // nothing to update
725 return;
Dimitry Ivanovb9c90262016-02-19 14:09:20 -0800726 }
727
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700728 if (mBaseClassLoader != null) {
David Brazdilfd6dcc22018-10-25 14:07:51 +0100729 mDefaultClassLoader = mBaseClassLoader;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800730 } else {
David Brazdilfd6dcc22018-10-25 14:07:51 +0100731 mDefaultClassLoader = ClassLoader.getSystemClassLoader();
Todd Kennedy39bfee52016-02-24 10:28:21 -0800732 }
David Brazdilfd6dcc22018-10-25 14:07:51 +0100733 mAppComponentFactory = createAppFactory(mApplicationInfo, mDefaultClassLoader);
David Brazdil33bd3432019-02-27 20:15:18 +0000734 mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader,
735 new ApplicationInfo(mApplicationInfo));
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700736 return;
737 }
738
739 // Avoid the binder call when the package is the current application package.
740 // The activity manager will perform ensure that dexopt is performed before
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100741 // spinning up the process. Similarly, don't call into binder when we don't
742 // have an ActivityThread object.
743 if (mActivityThread != null
744 && !Objects.equals(mPackageName, ActivityThread.currentPackageName())
745 && mIncludeCode) {
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700746 try {
Brian Carlstromca82e612016-04-19 23:16:08 -0700747 ActivityThread.getPackageManager().notifyPackageUse(mPackageName,
748 PackageManager.NOTIFY_PACKAGE_USE_CROSS_PACKAGE);
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700749 } catch (RemoteException re) {
750 throw re.rethrowFromSystemServer();
Todd Kennedy39bfee52016-02-24 10:28:21 -0800751 }
752 }
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700753
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700754 if (mRegisterPackage) {
755 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -0800756 ActivityManager.getService().addPackageDependency(mPackageName);
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700757 } catch (RemoteException e) {
758 throw e.rethrowFromSystemServer();
759 }
760 }
761
Andreas Gampea8a58ff2016-05-18 11:58:39 -0700762 // Lists for the elements of zip/code and native libraries.
763 //
764 // Both lists are usually not empty. We expect on average one APK for the zip component,
765 // but shared libraries and splits are not uncommon. We expect at least three elements
766 // for native libraries (app-based, system, vendor). As such, give both some breathing
767 // space and initialize to a small value (instead of incurring growth code).
768 final List<String> zipPaths = new ArrayList<>(10);
769 final List<String> libPaths = new ArrayList<>(10);
Narayan Kamath8995b002016-05-11 20:31:09 +0100770
Jiyong Parkfcad6962017-08-22 10:24:28 +0900771 boolean isBundledApp = mApplicationInfo.isSystemApp()
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700772 && !mApplicationInfo.isUpdatedSystemApp();
Dimitry Ivanovbf3b5f72016-05-03 11:34:58 -0700773
Jiyong Parkfcad6962017-08-22 10:24:28 +0900774 // Vendor apks are treated as bundled only when /vendor/lib is in the default search
775 // paths. If not, they are treated as unbundled; access to system libs is limited.
776 // Having /vendor/lib in the default search paths means that all system processes
777 // are allowed to use any vendor library, which in turn means that system is dependent
778 // on vendor partition. In the contrary, not having /vendor/lib in the default search
779 // paths mean that the two partitions are separated and thus we can treat vendor apks
780 // as unbundled.
781 final String defaultSearchPaths = System.getProperty("java.library.path");
782 final boolean treatVendorApkAsUnbundled = !defaultSearchPaths.contains("/vendor/lib");
Jiyong Park63495c22017-09-15 07:48:06 +0900783 if (mApplicationInfo.getCodePath() != null
Jiyong Park002fdbd2017-02-13 20:50:31 +0900784 && mApplicationInfo.isVendor() && treatVendorApkAsUnbundled) {
Jiyong Parkfcad6962017-08-22 10:24:28 +0900785 isBundledApp = false;
786 }
787
Kiyoung Kimdd6861e2019-03-11 11:48:14 +0900788 // Similar to vendor apks, we should add /product/lib for apks from product partition
Kiyoung Kim22557fe2019-03-28 13:38:12 +0900789 // when product apps are marked as unbundled. We cannot use the same way from vendor
790 // to check if lib path exists because there is possibility that /product/lib would not
Justin Yun1ef374f2019-12-17 15:15:34 +0900791 // exist from legacy device while product apks are bundled. To make this clear, we use
792 // "ro.product.vndk.version" property. If the property is defined, we regard all product
793 // apks as unbundled.
Kiyoung Kimdd6861e2019-03-11 11:48:14 +0900794 if (mApplicationInfo.getCodePath() != null
Justin Yun1ef374f2019-12-17 15:15:34 +0900795 && mApplicationInfo.isProduct()
796 && VndkProperties.product_vndk_version().isPresent()) {
Kiyoung Kimdd6861e2019-03-11 11:48:14 +0900797 isBundledApp = false;
798 }
799
Dimitry Ivanov638d8102017-02-22 15:39:42 -0800800 makePaths(mActivityThread, isBundledApp, mApplicationInfo, zipPaths, libPaths);
801
Dimitry Ivanoveb96b002016-05-10 10:51:40 -0700802 String libraryPermittedPath = mDataDir;
Jiyong Park29d9eba2018-05-04 12:44:38 +0900803
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700804 if (isBundledApp) {
Jiyong Park29d9eba2018-05-04 12:44:38 +0900805 // For bundled apps, add the base directory of the app (e.g.,
806 // /system/app/Foo/) to the permitted paths so that it can load libraries
807 // embedded in module apks under the directory. For now, GmsCore is relying
808 // on this, but this isn't specific to the app. Also note that, we don't
809 // need to do this for unbundled apps as entire /data is already set to
810 // the permitted paths for them.
811 libraryPermittedPath += File.pathSeparator
812 + Paths.get(getAppDir()).getParent().toString();
813
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700814 // This is necessary to grant bundled apps access to
815 // libraries located in subdirectories of /system/lib
Jiyong Parkfcad6962017-08-22 10:24:28 +0900816 libraryPermittedPath += File.pathSeparator + defaultSearchPaths;
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700817 }
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700818
819 final String librarySearchPath = TextUtils.join(File.pathSeparator, libPaths);
820
Narayan Kamath8995b002016-05-11 20:31:09 +0100821 // If we're not asked to include code, we construct a classloader that has
822 // no code path included. We still need to set up the library search paths
823 // and permitted path because NativeActivity relies on it (it attempts to
824 // call System.loadLibrary() on a classloader from a LoadedApk with
825 // mIncludeCode == false).
826 if (!mIncludeCode) {
David Brazdilfd6dcc22018-10-25 14:07:51 +0100827 if (mDefaultClassLoader == null) {
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100828 StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads();
David Brazdilfd6dcc22018-10-25 14:07:51 +0100829 mDefaultClassLoader = ApplicationLoaders.getDefault().getClassLoader(
Narayan Kamathf9419f02017-06-15 11:35:38 +0100830 "" /* codePath */, mApplicationInfo.targetSdkVersion, isBundledApp,
831 librarySearchPath, libraryPermittedPath, mBaseClassLoader,
832 null /* classLoaderName */);
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100833 setThreadPolicy(oldPolicy);
Jason Monk2544c692018-05-15 11:30:09 -0400834 mAppComponentFactory = AppComponentFactory.DEFAULT;
Narayan Kamath8995b002016-05-11 20:31:09 +0100835 }
836
David Brazdilfd6dcc22018-10-25 14:07:51 +0100837 if (mClassLoader == null) {
David Brazdil33bd3432019-02-27 20:15:18 +0000838 mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader,
839 new ApplicationInfo(mApplicationInfo));
David Brazdilfd6dcc22018-10-25 14:07:51 +0100840 }
841
Narayan Kamath8995b002016-05-11 20:31:09 +0100842 return;
843 }
844
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700845 /*
Narayan Kamath8995b002016-05-11 20:31:09 +0100846 * With all the combination done (if necessary, actually create the java class
847 * loader and set up JIT profiling support if necessary.
Andreas Gampea8a58ff2016-05-18 11:58:39 -0700848 *
849 * In many cases this is a single APK, so try to avoid the StringBuilder in TextUtils.
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700850 */
Andreas Gampea8a58ff2016-05-18 11:58:39 -0700851 final String zip = (zipPaths.size() == 1) ? zipPaths.get(0) :
852 TextUtils.join(File.pathSeparator, zipPaths);
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700853
Dianne Hackborn94846032017-03-31 17:55:23 -0700854 if (DEBUG) Slog.v(ActivityThread.TAG, "Class path: " + zip +
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700855 ", JNI path: " + librarySearchPath);
856
Calin Juravle430ef452016-04-22 17:43:07 +0100857 boolean needToSetupJitProfiles = false;
David Brazdilfd6dcc22018-10-25 14:07:51 +0100858 if (mDefaultClassLoader == null) {
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700859 // Temporarily disable logging of disk reads on the Looper thread
860 // as this is early and necessary.
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100861 StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads();
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700862
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000863 List<ClassLoader> sharedLibraries = createSharedLibrariesLoaders(
864 mApplicationInfo.sharedLibraryInfos, isBundledApp, librarySearchPath,
865 libraryPermittedPath);
866
867 mDefaultClassLoader = ApplicationLoaders.getDefault().getClassLoaderWithSharedLibraries(
868 zip, mApplicationInfo.targetSdkVersion, isBundledApp, librarySearchPath,
Narayan Kamathf9419f02017-06-15 11:35:38 +0100869 libraryPermittedPath, mBaseClassLoader,
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000870 mApplicationInfo.classLoaderName, sharedLibraries);
David Brazdilfd6dcc22018-10-25 14:07:51 +0100871 mAppComponentFactory = createAppFactory(mApplicationInfo, mDefaultClassLoader);
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700872
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100873 setThreadPolicy(oldPolicy);
Calin Juravle430ef452016-04-22 17:43:07 +0100874 // Setup the class loader paths for profiling.
875 needToSetupJitProfiles = true;
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700876 }
877
Patrick Baumann1bea2372018-03-13 14:26:58 -0700878 if (!libPaths.isEmpty() && SystemProperties.getBoolean(PROPERTY_NAME_APPEND_NATIVE, true)) {
Patrick Baumann5c5daa42018-05-09 11:12:49 -0700879 // Temporarily disable logging of disk reads on the Looper thread as this is necessary
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100880 StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads();
Patrick Baumann5c5daa42018-05-09 11:12:49 -0700881 try {
David Brazdilfd6dcc22018-10-25 14:07:51 +0100882 ApplicationLoaders.getDefault().addNative(mDefaultClassLoader, libPaths);
Patrick Baumann5c5daa42018-05-09 11:12:49 -0700883 } finally {
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100884 setThreadPolicy(oldPolicy);
Patrick Baumann5c5daa42018-05-09 11:12:49 -0700885 }
Patrick Baumann1bea2372018-03-13 14:26:58 -0700886 }
887
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700888 if (addedPaths != null && addedPaths.size() > 0) {
889 final String add = TextUtils.join(File.pathSeparator, addedPaths);
David Brazdilfd6dcc22018-10-25 14:07:51 +0100890 ApplicationLoaders.getDefault().addPath(mDefaultClassLoader, add);
Calin Juravle430ef452016-04-22 17:43:07 +0100891 // Setup the new code paths for profiling.
892 needToSetupJitProfiles = true;
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700893 }
Calin Juravle2a727d72016-04-15 19:33:46 +0100894
895 // Setup jit profile support.
Narayan Kamath2d4a2222016-04-25 19:16:56 +0100896 //
Calin Juravle2a727d72016-04-15 19:33:46 +0100897 // It is ok to call this multiple times if the application gets updated with new splits.
898 // The runtime only keeps track of unique code paths and can handle re-registration of
899 // the same code path. There's no need to pass `addedPaths` since any new code paths
900 // are already in `mApplicationInfo`.
Narayan Kamath2d4a2222016-04-25 19:16:56 +0100901 //
902 // It is NOT ok to call this function from the system_server (for any of the packages it
903 // loads code from) so we explicitly disallow it there.
Bo Liu6c504ae2019-04-05 14:54:52 -0400904 //
905 // It is not ok to call this in a zygote context where mActivityThread is null.
906 if (needToSetupJitProfiles && !ActivityThread.isSystem() && mActivityThread != null) {
Calin Juravle430ef452016-04-22 17:43:07 +0100907 setupJitProfileSupport();
Calin Juravle430ef452016-04-22 17:43:07 +0100908 }
David Brazdilfd6dcc22018-10-25 14:07:51 +0100909
910 // Call AppComponentFactory to select/create the main class loader of this app.
911 // Since this may call code in the app, mDefaultClassLoader must be fully set up
912 // before invoking the factory.
David Brazdil33bd3432019-02-27 20:15:18 +0000913 // Invoke with a copy of ApplicationInfo to protect against the app changing it.
David Brazdilfd6dcc22018-10-25 14:07:51 +0100914 if (mClassLoader == null) {
David Brazdil33bd3432019-02-27 20:15:18 +0000915 mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader,
916 new ApplicationInfo(mApplicationInfo));
David Brazdilfd6dcc22018-10-25 14:07:51 +0100917 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800918 }
919
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100920 @UnsupportedAppUsage
Todd Kennedy39bfee52016-02-24 10:28:21 -0800921 public ClassLoader getClassLoader() {
922 synchronized (this) {
923 if (mClassLoader == null) {
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700924 createOrUpdateClassLoaderLocked(null /*addedPaths*/);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800925 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700926 return mClassLoader;
927 }
928 }
929
Calin Juravle2a727d72016-04-15 19:33:46 +0100930 private void setupJitProfileSupport() {
931 if (!SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false)) {
932 return;
933 }
David Brazdil991ff902018-12-03 10:59:29 +0000934
935 // If we use profiles, setup the dex reporter to notify package manager
936 // of any relevant dex loads. The idle maintenance job will use the information
937 // reported to optimize the loaded dex files.
938 // Note that we only need one global reporter per app.
939 // Make sure we do this before invoking app code for the first time so that we
940 // can capture the complete application startup.
941 BaseDexClassLoader.setReporter(DexLoadReporter.getInstance());
942
Calin Juravle126f7802016-05-24 15:23:47 +0100943 // Only set up profile support if the loaded apk has the same uid as the
944 // current process.
945 // Currently, we do not support profiling across different apps.
946 // (e.g. application's uid might be different when the code is
947 // loaded by another app via createApplicationContext)
948 if (mApplicationInfo.uid != Process.myUid()) {
949 return;
950 }
951
Calin Juravle2a727d72016-04-15 19:33:46 +0100952 final List<String> codePaths = new ArrayList<>();
953 if ((mApplicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0) {
954 codePaths.add(mApplicationInfo.sourceDir);
955 }
956 if (mApplicationInfo.splitSourceDirs != null) {
957 Collections.addAll(codePaths, mApplicationInfo.splitSourceDirs);
958 }
959
960 if (codePaths.isEmpty()) {
961 // If there are no code paths there's no need to setup a profile file and register with
962 // the runtime,
963 return;
964 }
965
Calin Juravle6ae39fc2018-01-19 20:32:47 -0800966 for (int i = codePaths.size() - 1; i >= 0; i--) {
967 String splitName = i == 0 ? null : mApplicationInfo.splitNames[i - 1];
968 String profileFile = ArtManager.getCurrentProfilePath(
969 mPackageName, UserHandle.myUserId(), splitName);
970 VMRuntime.registerAppInfo(profileFile, new String[] {codePaths.get(i)});
971 }
Calin Juravlef5a7bfc2017-03-13 23:30:30 -0700972
973 // Register the app data directory with the reporter. It will
974 // help deciding whether or not a dex file is the primary apk or a
975 // secondary dex.
976 DexLoadReporter.getInstance().registerAppDataDir(mPackageName, mDataDir);
Calin Juravle2a727d72016-04-15 19:33:46 +0100977 }
978
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700979 /**
980 * Setup value for Thread.getContextClassLoader(). If the
981 * package will not run in in a VM with other packages, we set
982 * the Java context ClassLoader to the
983 * PackageInfo.getClassLoader value. However, if this VM can
984 * contain multiple packages, we intead set the Java context
985 * ClassLoader to a proxy that will warn about the use of Java
986 * context ClassLoaders and then fall through to use the
987 * system ClassLoader.
988 *
989 * <p> Note that this is similar to but not the same as the
990 * android.content.Context.getClassLoader(). While both
991 * context class loaders are typically set to the
992 * PathClassLoader used to load the package archive in the
993 * single application per VM case, a single Android process
994 * may contain several Contexts executing on one thread with
995 * their own logical ClassLoaders while the Java context
996 * ClassLoader is a thread local. This is why in the case when
997 * we have multiple packages per VM we do not set the Java
998 * context ClassLoader to an arbitrary but instead warn the
999 * user to set their own if we detect that they are using a
1000 * Java library that expects it to be set.
1001 */
1002 private void initializeJavaContextClassLoader() {
1003 IPackageManager pm = ActivityThread.getPackageManager();
1004 android.content.pm.PackageInfo pi;
1005 try {
Jeff Sharkeyc7bacab2016-02-09 15:56:11 -07001006 pi = pm.getPackageInfo(mPackageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
1007 UserHandle.myUserId());
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001008 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001009 throw e.rethrowFromSystemServer();
Dianne Hackborn208d9372013-02-25 13:17:54 -08001010 }
1011 if (pi == null) {
1012 throw new IllegalStateException("Unable to get package info for "
1013 + mPackageName + "; is package not installed?");
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001014 }
1015 /*
1016 * Two possible indications that this package could be
1017 * sharing its virtual machine with other packages:
1018 *
1019 * 1.) the sharedUserId attribute is set in the manifest,
1020 * indicating a request to share a VM with other
1021 * packages with the same sharedUserId.
1022 *
1023 * 2.) the application element of the manifest has an
1024 * attribute specifying a non-default process name,
1025 * indicating the desire to run in another packages VM.
1026 */
1027 boolean sharedUserIdSet = (pi.sharedUserId != null);
1028 boolean processNameNotDefault =
1029 (pi.applicationInfo != null &&
1030 !mPackageName.equals(pi.applicationInfo.processName));
1031 boolean sharable = (sharedUserIdSet || processNameNotDefault);
1032 ClassLoader contextClassLoader =
1033 (sharable)
1034 ? new WarningContextClassLoader()
1035 : mClassLoader;
1036 Thread.currentThread().setContextClassLoader(contextClassLoader);
1037 }
1038
1039 private static class WarningContextClassLoader extends ClassLoader {
1040
1041 private static boolean warned = false;
1042
1043 private void warn(String methodName) {
1044 if (warned) {
1045 return;
1046 }
1047 warned = true;
1048 Thread.currentThread().setContextClassLoader(getParent());
1049 Slog.w(ActivityThread.TAG, "ClassLoader." + methodName + ": " +
1050 "The class loader returned by " +
1051 "Thread.getContextClassLoader() may fail for processes " +
1052 "that host multiple applications. You should explicitly " +
1053 "specify a context class loader. For example: " +
1054 "Thread.setContextClassLoader(getClass().getClassLoader());");
1055 }
1056
1057 @Override public URL getResource(String resName) {
1058 warn("getResource");
1059 return getParent().getResource(resName);
1060 }
1061
1062 @Override public Enumeration<URL> getResources(String resName) throws IOException {
1063 warn("getResources");
1064 return getParent().getResources(resName);
1065 }
1066
1067 @Override public InputStream getResourceAsStream(String resName) {
1068 warn("getResourceAsStream");
1069 return getParent().getResourceAsStream(resName);
1070 }
1071
1072 @Override public Class<?> loadClass(String className) throws ClassNotFoundException {
1073 warn("loadClass");
1074 return getParent().loadClass(className);
1075 }
1076
1077 @Override public void setClassAssertionStatus(String cname, boolean enable) {
1078 warn("setClassAssertionStatus");
1079 getParent().setClassAssertionStatus(cname, enable);
1080 }
1081
1082 @Override public void setPackageAssertionStatus(String pname, boolean enable) {
1083 warn("setPackageAssertionStatus");
1084 getParent().setPackageAssertionStatus(pname, enable);
1085 }
1086
1087 @Override public void setDefaultAssertionStatus(boolean enable) {
1088 warn("setDefaultAssertionStatus");
1089 getParent().setDefaultAssertionStatus(enable);
1090 }
1091
1092 @Override public void clearAssertionStatus() {
1093 warn("clearAssertionStatus");
1094 getParent().clearAssertionStatus();
1095 }
1096 }
1097
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001098 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001099 public String getAppDir() {
1100 return mAppDir;
1101 }
1102
Brian Carlstromd893a892012-04-01 21:30:26 -07001103 public String getLibDir() {
1104 return mLibDir;
1105 }
1106
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001107 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001108 public String getResDir() {
1109 return mResDir;
1110 }
1111
Jeff Sharkey8a4c9722014-06-16 13:48:42 -07001112 public String[] getSplitAppDirs() {
1113 return mSplitAppDirs;
1114 }
1115
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001116 @UnsupportedAppUsage
Jeff Sharkey8a4c9722014-06-16 13:48:42 -07001117 public String[] getSplitResDirs() {
1118 return mSplitResDirs;
1119 }
1120
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001121 @UnsupportedAppUsage
MÃ¥rten Kongstad48d22322014-01-31 14:43:27 +01001122 public String[] getOverlayDirs() {
1123 return mOverlayDirs;
1124 }
1125
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001126 public String getDataDir() {
1127 return mDataDir;
1128 }
1129
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001130 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001131 public File getDataDirFile() {
1132 return mDataDirFile;
1133 }
1134
Jeff Sharkey8a372a02016-03-16 16:25:45 -06001135 public File getDeviceProtectedDataDirFile() {
1136 return mDeviceProtectedDataDirFile;
Jeff Sharkey15447792015-11-05 16:18:51 -08001137 }
1138
Jeff Sharkey8a372a02016-03-16 16:25:45 -06001139 public File getCredentialProtectedDataDirFile() {
1140 return mCredentialProtectedDataDirFile;
Jeff Sharkey15447792015-11-05 16:18:51 -08001141 }
1142
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001143 @UnsupportedAppUsage
Adam Lesinski4e862812016-11-21 16:02:24 -08001144 public AssetManager getAssets() {
1145 return getResources().getAssets();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001146 }
1147
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001148 @UnsupportedAppUsage
Adam Lesinski4e862812016-11-21 16:02:24 -08001149 public Resources getResources() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001150 if (mResources == null) {
Adam Lesinski4e862812016-11-21 16:02:24 -08001151 final String[] splitPaths;
1152 try {
1153 splitPaths = getSplitPaths(null);
Adam Lesinski1665d0f2017-03-10 14:46:57 -08001154 } catch (NameNotFoundException e) {
Adam Lesinski4e862812016-11-21 16:02:24 -08001155 // This should never fail.
1156 throw new AssertionError("null split not found");
1157 }
1158
Todd Kennedy233a0b12018-01-29 20:30:24 +00001159 mResources = ResourcesManager.getInstance().getResources(null, mResDir,
1160 splitPaths, mOverlayDirs, mApplicationInfo.sharedLibraryFiles,
1161 Display.DEFAULT_DISPLAY, null, getCompatibilityInfo(),
Ryan Mitchell4579c0a2020-01-08 16:29:11 -08001162 getClassLoader(), null);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001163 }
1164 return mResources;
1165 }
1166
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001167 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001168 public Application makeApplication(boolean forceDefaultAppClass,
1169 Instrumentation instrumentation) {
1170 if (mApplication != null) {
1171 return mApplication;
1172 }
1173
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001174 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");
1175
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001176 Application app = null;
1177
1178 String appClass = mApplicationInfo.className;
1179 if (forceDefaultAppClass || (appClass == null)) {
1180 appClass = "android.app.Application";
1181 }
1182
1183 try {
Ryan Mitchell73285142020-01-16 12:17:06 -08001184 final java.lang.ClassLoader cl = getClassLoader();
Narayan Kamath8091edb2014-10-15 11:38:44 +01001185 if (!mPackageName.equals("android")) {
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001186 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
1187 "initializeJavaContextClassLoader");
Narayan Kamath8091edb2014-10-15 11:38:44 +01001188 initializeJavaContextClassLoader();
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001189 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Narayan Kamath8091edb2014-10-15 11:38:44 +01001190 }
Ryan Mitchell73285142020-01-16 12:17:06 -08001191
1192 // Rewrite the R 'constants' for all library apks.
1193 SparseArray<String> packageIdentifiers = getAssets().getAssignedPackageIdentifiers(
1194 false, false);
1195 for (int i = 0, n = packageIdentifiers.size(); i < n; i++) {
1196 final int id = packageIdentifiers.keyAt(i);
1197 if (id == 0x01 || id == 0x7f) {
1198 continue;
1199 }
1200
1201 rewriteRValues(cl, packageIdentifiers.valueAt(i), id);
1202 }
1203
Jeff Browndefd4a62014-03-10 21:24:37 -07001204 ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001205 app = mActivityThread.mInstrumentation.newApplication(
1206 cl, appClass, appContext);
1207 appContext.setOuterContext(app);
1208 } catch (Exception e) {
1209 if (!mActivityThread.mInstrumentation.onException(app, e)) {
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001210 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001211 throw new RuntimeException(
1212 "Unable to instantiate application " + appClass
1213 + ": " + e.toString(), e);
1214 }
1215 }
1216 mActivityThread.mAllApplications.add(app);
1217 mApplication = app;
1218
1219 if (instrumentation != null) {
1220 try {
1221 instrumentation.callApplicationOnCreate(app);
1222 } catch (Exception e) {
1223 if (!instrumentation.onException(app, e)) {
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001224 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001225 throw new RuntimeException(
1226 "Unable to create application " + app.getClass().getName()
1227 + ": " + e.toString(), e);
1228 }
1229 }
1230 }
Adam Lesinskide898ff2014-01-29 18:20:45 -08001231
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001232 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1233
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001234 return app;
1235 }
1236
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001237 @UnsupportedAppUsage
Adam Lesinskide898ff2014-01-29 18:20:45 -08001238 private void rewriteRValues(ClassLoader cl, String packageName, int id) {
Adam Lesinski2cb761e2014-08-15 13:59:02 -07001239 final Class<?> rClazz;
Adam Lesinskide898ff2014-01-29 18:20:45 -08001240 try {
Adam Lesinski2cb761e2014-08-15 13:59:02 -07001241 rClazz = cl.loadClass(packageName + ".R");
1242 } catch (ClassNotFoundException e) {
1243 // This is not necessarily an error, as some packages do not ship with resources
1244 // (or they do not need rewriting).
Adam Lesinski1e4663852014-08-15 14:47:28 -07001245 Log.i(TAG, "No resource references to update in package " + packageName);
Adam Lesinski2cb761e2014-08-15 13:59:02 -07001246 return;
1247 }
1248
Adam Lesinski1e4663852014-08-15 14:47:28 -07001249 final Method callback;
Adam Lesinski2cb761e2014-08-15 13:59:02 -07001250 try {
Adam Lesinski1e4663852014-08-15 14:47:28 -07001251 callback = rClazz.getMethod("onResourcesLoaded", int.class);
1252 } catch (NoSuchMethodException e) {
1253 // No rewriting to be done.
1254 return;
Adam Lesinskide898ff2014-01-29 18:20:45 -08001255 }
Adam Lesinski1e4663852014-08-15 14:47:28 -07001256
1257 Throwable cause;
1258 try {
1259 callback.invoke(null, id);
1260 return;
1261 } catch (IllegalAccessException e) {
1262 cause = e;
1263 } catch (InvocationTargetException e) {
1264 cause = e.getCause();
1265 }
1266
1267 throw new RuntimeException("Failed to rewrite resource references for " + packageName,
1268 cause);
Adam Lesinskide898ff2014-01-29 18:20:45 -08001269 }
1270
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001271 public void removeContextRegistrations(Context context,
1272 String who, String what) {
Jeff Sharkeyd7026f12012-03-01 20:50:32 -08001273 final boolean reportRegistrationLeaks = StrictMode.vmRegistrationLeaksEnabled();
Adam Lesinski23d40c42014-11-20 11:58:21 -08001274 synchronized (mReceivers) {
1275 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> rmap =
1276 mReceivers.remove(context);
1277 if (rmap != null) {
1278 for (int i = 0; i < rmap.size(); i++) {
1279 LoadedApk.ReceiverDispatcher rd = rmap.valueAt(i);
1280 IntentReceiverLeaked leak = new IntentReceiverLeaked(
1281 what + " " + who + " has leaked IntentReceiver "
1282 + rd.getIntentReceiver() + " that was " +
1283 "originally registered here. Are you missing a " +
1284 "call to unregisterReceiver()?");
1285 leak.setStackTrace(rd.getLocation().getStackTrace());
1286 Slog.e(ActivityThread.TAG, leak.getMessage(), leak);
1287 if (reportRegistrationLeaks) {
1288 StrictMode.onIntentReceiverLeaked(leak);
1289 }
1290 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001291 ActivityManager.getService().unregisterReceiver(
Adam Lesinski23d40c42014-11-20 11:58:21 -08001292 rd.getIIntentReceiver());
1293 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001294 throw e.rethrowFromSystemServer();
Adam Lesinski23d40c42014-11-20 11:58:21 -08001295 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001296 }
1297 }
Adam Lesinski23d40c42014-11-20 11:58:21 -08001298 mUnregisteredReceivers.remove(context);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001299 }
Adam Lesinski23d40c42014-11-20 11:58:21 -08001300
1301 synchronized (mServices) {
1302 //Slog.i(TAG, "Receiver registrations: " + mReceivers);
1303 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> smap =
1304 mServices.remove(context);
1305 if (smap != null) {
1306 for (int i = 0; i < smap.size(); i++) {
1307 LoadedApk.ServiceDispatcher sd = smap.valueAt(i);
1308 ServiceConnectionLeaked leak = new ServiceConnectionLeaked(
1309 what + " " + who + " has leaked ServiceConnection "
1310 + sd.getServiceConnection() + " that was originally bound here");
1311 leak.setStackTrace(sd.getLocation().getStackTrace());
1312 Slog.e(ActivityThread.TAG, leak.getMessage(), leak);
1313 if (reportRegistrationLeaks) {
1314 StrictMode.onServiceConnectionLeaked(leak);
1315 }
1316 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001317 ActivityManager.getService().unbindService(
Adam Lesinski23d40c42014-11-20 11:58:21 -08001318 sd.getIServiceConnection());
1319 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001320 throw e.rethrowFromSystemServer();
Adam Lesinski23d40c42014-11-20 11:58:21 -08001321 }
1322 sd.doForget();
Jeff Sharkeyd7026f12012-03-01 20:50:32 -08001323 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001324 }
Adam Lesinski23d40c42014-11-20 11:58:21 -08001325 mUnboundServices.remove(context);
1326 //Slog.i(TAG, "Service registrations: " + mServices);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001327 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001328 }
1329
1330 public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r,
1331 Context context, Handler handler,
1332 Instrumentation instrumentation, boolean registered) {
1333 synchronized (mReceivers) {
1334 LoadedApk.ReceiverDispatcher rd = null;
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001335 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001336 if (registered) {
1337 map = mReceivers.get(context);
1338 if (map != null) {
1339 rd = map.get(r);
1340 }
1341 }
1342 if (rd == null) {
1343 rd = new ReceiverDispatcher(r, context, handler,
1344 instrumentation, registered);
1345 if (registered) {
1346 if (map == null) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001347 map = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001348 mReceivers.put(context, map);
1349 }
1350 map.put(r, rd);
1351 }
1352 } else {
1353 rd.validate(context, handler);
1354 }
Dianne Hackbornc2d9c8e2011-01-24 21:59:21 -08001355 rd.mForgotten = false;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001356 return rd.getIIntentReceiver();
1357 }
1358 }
1359
1360 public IIntentReceiver forgetReceiverDispatcher(Context context,
1361 BroadcastReceiver r) {
1362 synchronized (mReceivers) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001363 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = mReceivers.get(context);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001364 LoadedApk.ReceiverDispatcher rd = null;
1365 if (map != null) {
1366 rd = map.get(r);
1367 if (rd != null) {
1368 map.remove(r);
1369 if (map.size() == 0) {
1370 mReceivers.remove(context);
1371 }
1372 if (r.getDebugUnregister()) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001373 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> holder
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001374 = mUnregisteredReceivers.get(context);
1375 if (holder == null) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001376 holder = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001377 mUnregisteredReceivers.put(context, holder);
1378 }
1379 RuntimeException ex = new IllegalArgumentException(
1380 "Originally unregistered here:");
1381 ex.fillInStackTrace();
1382 rd.setUnregisterLocation(ex);
1383 holder.put(r, rd);
1384 }
Dianne Hackbornc2d9c8e2011-01-24 21:59:21 -08001385 rd.mForgotten = true;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001386 return rd.getIIntentReceiver();
1387 }
1388 }
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001389 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> holder
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001390 = mUnregisteredReceivers.get(context);
1391 if (holder != null) {
1392 rd = holder.get(r);
1393 if (rd != null) {
1394 RuntimeException ex = rd.getUnregisterLocation();
1395 throw new IllegalArgumentException(
1396 "Unregistering Receiver " + r
1397 + " that was already unregistered", ex);
1398 }
1399 }
1400 if (context == null) {
1401 throw new IllegalStateException("Unbinding Receiver " + r
1402 + " from Context that is no longer in use: " + context);
1403 } else {
1404 throw new IllegalArgumentException("Receiver not registered: " + r);
1405 }
1406
1407 }
1408 }
1409
1410 static final class ReceiverDispatcher {
1411
1412 final static class InnerReceiver extends IIntentReceiver.Stub {
1413 final WeakReference<LoadedApk.ReceiverDispatcher> mDispatcher;
1414 final LoadedApk.ReceiverDispatcher mStrongRef;
1415
1416 InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) {
1417 mDispatcher = new WeakReference<LoadedApk.ReceiverDispatcher>(rd);
1418 mStrongRef = strong ? rd : null;
1419 }
Jeff Sharkeyd136e512016-03-09 22:30:56 -07001420
1421 @Override
Dianne Hackborn20e80982012-08-31 19:00:44 -07001422 public void performReceive(Intent intent, int resultCode, String data,
1423 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
Dianne Hackborn26756162016-05-17 13:40:44 -07001424 final LoadedApk.ReceiverDispatcher rd;
1425 if (intent == null) {
1426 Log.wtf(TAG, "Null intent received");
1427 rd = null;
1428 } else {
1429 rd = mDispatcher.get();
1430 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001431 if (ActivityThread.DEBUG_BROADCAST) {
1432 int seq = intent.getIntExtra("seq", -1);
Dianne Hackborn26756162016-05-17 13:40:44 -07001433 Slog.i(ActivityThread.TAG, "Receiving broadcast " + intent.getAction()
1434 + " seq=" + seq + " to " + (rd != null ? rd.mReceiver : null));
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001435 }
1436 if (rd != null) {
1437 rd.performReceive(intent, resultCode, data, extras,
Dianne Hackborn20e80982012-08-31 19:00:44 -07001438 ordered, sticky, sendingUser);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001439 } else {
1440 // The activity manager dispatched a broadcast to a registered
1441 // receiver in this process, but before it could be delivered the
1442 // receiver was unregistered. Acknowledge the broadcast on its
1443 // behalf so that the system's broadcast sequence can continue.
1444 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1445 "Finishing broadcast to unregistered receiver");
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001446 IActivityManager mgr = ActivityManager.getService();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001447 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001448 if (extras != null) {
1449 extras.setAllowFds(false);
1450 }
riddle_hsu1f5ac4d2015-01-03 15:38:21 +08001451 mgr.finishReceiver(this, resultCode, data, extras, false, intent.getFlags());
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001452 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001453 throw e.rethrowFromSystemServer();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001454 }
1455 }
1456 }
1457 }
1458
1459 final IIntentReceiver.Stub mIIntentReceiver;
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001460 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001461 final BroadcastReceiver mReceiver;
Mathew Inwood8c854f82018-09-14 12:35:36 +01001462 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001463 final Context mContext;
1464 final Handler mActivityThread;
1465 final Instrumentation mInstrumentation;
1466 final boolean mRegistered;
1467 final IntentReceiverLeaked mLocation;
1468 RuntimeException mUnregisterLocation;
Dianne Hackbornc2d9c8e2011-01-24 21:59:21 -08001469 boolean mForgotten;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001470
Makoto Onuki08408b92017-05-09 13:48:53 -07001471 final class Args extends BroadcastReceiver.PendingResult {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001472 private Intent mCurIntent;
Dianne Hackborne829fef2010-10-26 17:44:01 -07001473 private final boolean mOrdered;
Dianne Hackborn17c77532016-06-22 16:49:14 -07001474 private boolean mDispatched;
Makoto Onuki350ed672019-04-30 14:34:08 -07001475 private boolean mRunCalled;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001476
Dianne Hackborne829fef2010-10-26 17:44:01 -07001477 public Args(Intent intent, int resultCode, String resultData, Bundle resultExtras,
Dianne Hackborn20e80982012-08-31 19:00:44 -07001478 boolean ordered, boolean sticky, int sendingUser) {
Dianne Hackborne829fef2010-10-26 17:44:01 -07001479 super(resultCode, resultData, resultExtras,
riddle_hsu1f5ac4d2015-01-03 15:38:21 +08001480 mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED, ordered,
1481 sticky, mIIntentReceiver.asBinder(), sendingUser, intent.getFlags());
Dianne Hackborne829fef2010-10-26 17:44:01 -07001482 mCurIntent = intent;
1483 mOrdered = ordered;
1484 }
Dianne Hackborn17c77532016-06-22 16:49:14 -07001485
Makoto Onuki08408b92017-05-09 13:48:53 -07001486 public final Runnable getRunnable() {
1487 return () -> {
1488 final BroadcastReceiver receiver = mReceiver;
1489 final boolean ordered = mOrdered;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001490
Makoto Onuki08408b92017-05-09 13:48:53 -07001491 if (ActivityThread.DEBUG_BROADCAST) {
1492 int seq = mCurIntent.getIntExtra("seq", -1);
1493 Slog.i(ActivityThread.TAG, "Dispatching broadcast " + mCurIntent.getAction()
1494 + " seq=" + seq + " to " + mReceiver);
1495 Slog.i(ActivityThread.TAG, " mRegistered=" + mRegistered
1496 + " mOrderedHint=" + ordered);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001497 }
Makoto Onuki08408b92017-05-09 13:48:53 -07001498
1499 final IActivityManager mgr = ActivityManager.getService();
1500 final Intent intent = mCurIntent;
1501 if (intent == null) {
1502 Log.wtf(TAG, "Null intent being dispatched, mDispatched=" + mDispatched
Makoto Onuki350ed672019-04-30 14:34:08 -07001503 + (mRunCalled ? ", run() has already been called" : ""));
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001504 }
Makoto Onuki08408b92017-05-09 13:48:53 -07001505
1506 mCurIntent = null;
1507 mDispatched = true;
Makoto Onuki350ed672019-04-30 14:34:08 -07001508 mRunCalled = true;
Makoto Onuki08408b92017-05-09 13:48:53 -07001509 if (receiver == null || intent == null || mForgotten) {
1510 if (mRegistered && ordered) {
1511 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1512 "Finishing null broadcast to " + mReceiver);
1513 sendFinished(mgr);
1514 }
1515 return;
1516 }
1517
1518 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveReg");
1519 try {
1520 ClassLoader cl = mReceiver.getClass().getClassLoader();
1521 intent.setExtrasClassLoader(cl);
1522 intent.prepareToEnterProcess();
1523 setExtrasClassLoader(cl);
1524 receiver.setPendingResult(this);
1525 receiver.onReceive(mContext, intent);
1526 } catch (Exception e) {
1527 if (mRegistered && ordered) {
1528 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1529 "Finishing failed broadcast to " + mReceiver);
1530 sendFinished(mgr);
1531 }
1532 if (mInstrumentation == null ||
1533 !mInstrumentation.onException(mReceiver, e)) {
1534 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1535 throw new RuntimeException(
1536 "Error receiving broadcast " + intent
1537 + " in " + mReceiver, e);
1538 }
1539 }
1540
1541 if (receiver.getPendingResult() != null) {
1542 finish();
1543 }
1544 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1545 };
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001546 }
1547 }
1548
1549 ReceiverDispatcher(BroadcastReceiver receiver, Context context,
1550 Handler activityThread, Instrumentation instrumentation,
1551 boolean registered) {
1552 if (activityThread == null) {
1553 throw new NullPointerException("Handler must not be null");
1554 }
1555
1556 mIIntentReceiver = new InnerReceiver(this, !registered);
1557 mReceiver = receiver;
1558 mContext = context;
1559 mActivityThread = activityThread;
1560 mInstrumentation = instrumentation;
1561 mRegistered = registered;
1562 mLocation = new IntentReceiverLeaked(null);
1563 mLocation.fillInStackTrace();
1564 }
1565
1566 void validate(Context context, Handler activityThread) {
1567 if (mContext != context) {
1568 throw new IllegalStateException(
1569 "Receiver " + mReceiver +
1570 " registered with differing Context (was " +
1571 mContext + " now " + context + ")");
1572 }
1573 if (mActivityThread != activityThread) {
1574 throw new IllegalStateException(
1575 "Receiver " + mReceiver +
1576 " registered with differing handler (was " +
1577 mActivityThread + " now " + activityThread + ")");
1578 }
1579 }
1580
1581 IntentReceiverLeaked getLocation() {
1582 return mLocation;
1583 }
1584
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001585 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001586 BroadcastReceiver getIntentReceiver() {
1587 return mReceiver;
1588 }
1589
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001590 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001591 IIntentReceiver getIIntentReceiver() {
1592 return mIIntentReceiver;
1593 }
1594
1595 void setUnregisterLocation(RuntimeException ex) {
1596 mUnregisterLocation = ex;
1597 }
1598
1599 RuntimeException getUnregisterLocation() {
1600 return mUnregisterLocation;
1601 }
1602
Dianne Hackborn20e80982012-08-31 19:00:44 -07001603 public void performReceive(Intent intent, int resultCode, String data,
1604 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
Dianne Hackborn41bfaf82016-06-08 16:33:29 -07001605 final Args args = new Args(intent, resultCode, data, extras, ordered,
Dianne Hackborn20e80982012-08-31 19:00:44 -07001606 sticky, sendingUser);
Dianne Hackborn41bfaf82016-06-08 16:33:29 -07001607 if (intent == null) {
1608 Log.wtf(TAG, "Null intent received");
1609 } else {
1610 if (ActivityThread.DEBUG_BROADCAST) {
1611 int seq = intent.getIntExtra("seq", -1);
1612 Slog.i(ActivityThread.TAG, "Enqueueing broadcast " + intent.getAction()
1613 + " seq=" + seq + " to " + mReceiver);
1614 }
1615 }
Makoto Onuki08408b92017-05-09 13:48:53 -07001616 if (intent == null || !mActivityThread.post(args.getRunnable())) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001617 if (mRegistered && ordered) {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001618 IActivityManager mgr = ActivityManager.getService();
Dianne Hackborne829fef2010-10-26 17:44:01 -07001619 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1620 "Finishing sync broadcast to " + mReceiver);
1621 args.sendFinished(mgr);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001622 }
1623 }
1624 }
1625
1626 }
1627
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001628 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001629 public final IServiceConnection getServiceDispatcher(ServiceConnection c,
1630 Context context, Handler handler, int flags) {
Bo Liu58a57662019-03-06 20:21:45 +00001631 return getServiceDispatcherCommon(c, context, handler, null, flags);
1632 }
1633
1634 public final IServiceConnection getServiceDispatcher(ServiceConnection c,
1635 Context context, Executor executor, int flags) {
1636 return getServiceDispatcherCommon(c, context, null, executor, flags);
1637 }
1638
1639 private IServiceConnection getServiceDispatcherCommon(ServiceConnection c,
1640 Context context, Handler handler, Executor executor, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001641 synchronized (mServices) {
1642 LoadedApk.ServiceDispatcher sd = null;
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001643 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001644 if (map != null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001645 if (DEBUG) Slog.d(TAG, "Returning existing dispatcher " + sd + " for conn " + c);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001646 sd = map.get(c);
1647 }
1648 if (sd == null) {
Bo Liu58a57662019-03-06 20:21:45 +00001649 if (executor != null) {
1650 sd = new ServiceDispatcher(c, context, executor, flags);
1651 } else {
1652 sd = new ServiceDispatcher(c, context, handler, flags);
1653 }
Dianne Hackborn94846032017-03-31 17:55:23 -07001654 if (DEBUG) Slog.d(TAG, "Creating new dispatcher " + sd + " for conn " + c);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001655 if (map == null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001656 map = new ArrayMap<>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001657 mServices.put(context, map);
1658 }
1659 map.put(c, sd);
1660 } else {
Bo Liu58a57662019-03-06 20:21:45 +00001661 sd.validate(context, handler, executor);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001662 }
1663 return sd.getIServiceConnection();
1664 }
1665 }
1666
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08001667 @UnsupportedAppUsage
1668 public IServiceConnection lookupServiceDispatcher(ServiceConnection c,
1669 Context context) {
1670 synchronized (mServices) {
1671 LoadedApk.ServiceDispatcher sd = null;
1672 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
1673 if (map != null) {
1674 sd = map.get(c);
1675 }
1676 return sd != null ? sd.getIServiceConnection() : null;
1677 }
1678 }
1679
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001680 public final IServiceConnection forgetServiceDispatcher(Context context,
1681 ServiceConnection c) {
1682 synchronized (mServices) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001683 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001684 = mServices.get(context);
1685 LoadedApk.ServiceDispatcher sd = null;
1686 if (map != null) {
1687 sd = map.get(c);
1688 if (sd != null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001689 if (DEBUG) Slog.d(TAG, "Removing dispatcher " + sd + " for conn " + c);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001690 map.remove(c);
1691 sd.doForget();
1692 if (map.size() == 0) {
1693 mServices.remove(context);
1694 }
1695 if ((sd.getFlags()&Context.BIND_DEBUG_UNBIND) != 0) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001696 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> holder
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001697 = mUnboundServices.get(context);
1698 if (holder == null) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001699 holder = new ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001700 mUnboundServices.put(context, holder);
1701 }
1702 RuntimeException ex = new IllegalArgumentException(
1703 "Originally unbound here:");
1704 ex.fillInStackTrace();
1705 sd.setUnbindLocation(ex);
1706 holder.put(c, sd);
1707 }
1708 return sd.getIServiceConnection();
1709 }
1710 }
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001711 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> holder
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001712 = mUnboundServices.get(context);
1713 if (holder != null) {
1714 sd = holder.get(c);
1715 if (sd != null) {
1716 RuntimeException ex = sd.getUnbindLocation();
1717 throw new IllegalArgumentException(
1718 "Unbinding Service " + c
1719 + " that was already unbound", ex);
1720 }
1721 }
1722 if (context == null) {
1723 throw new IllegalStateException("Unbinding Service " + c
1724 + " from Context that is no longer in use: " + context);
1725 } else {
1726 throw new IllegalArgumentException("Service not registered: " + c);
1727 }
1728 }
1729 }
1730
1731 static final class ServiceDispatcher {
1732 private final ServiceDispatcher.InnerConnection mIServiceConnection;
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001733 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001734 private final ServiceConnection mConnection;
Mathew Inwood8c854f82018-09-14 12:35:36 +01001735 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001736 private final Context mContext;
1737 private final Handler mActivityThread;
Bo Liu58a57662019-03-06 20:21:45 +00001738 private final Executor mActivityExecutor;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001739 private final ServiceConnectionLeaked mLocation;
1740 private final int mFlags;
1741
1742 private RuntimeException mUnbindLocation;
1743
Dianne Hackborn5a6ef732011-11-11 12:31:52 -08001744 private boolean mForgotten;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001745
1746 private static class ConnectionInfo {
1747 IBinder binder;
1748 IBinder.DeathRecipient deathMonitor;
1749 }
1750
1751 private static class InnerConnection extends IServiceConnection.Stub {
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001752 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001753 final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;
1754
1755 InnerConnection(LoadedApk.ServiceDispatcher sd) {
1756 mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
1757 }
1758
Dianne Hackborn94846032017-03-31 17:55:23 -07001759 public void connected(ComponentName name, IBinder service, boolean dead)
1760 throws RemoteException {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001761 LoadedApk.ServiceDispatcher sd = mDispatcher.get();
1762 if (sd != null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001763 sd.connected(name, service, dead);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001764 }
1765 }
1766 }
1767
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001768 private final ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo> mActiveConnections
1769 = new ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001770
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001771 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001772 ServiceDispatcher(ServiceConnection conn,
1773 Context context, Handler activityThread, int flags) {
1774 mIServiceConnection = new InnerConnection(this);
1775 mConnection = conn;
1776 mContext = context;
1777 mActivityThread = activityThread;
Bo Liu58a57662019-03-06 20:21:45 +00001778 mActivityExecutor = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001779 mLocation = new ServiceConnectionLeaked(null);
1780 mLocation.fillInStackTrace();
1781 mFlags = flags;
1782 }
1783
Bo Liu58a57662019-03-06 20:21:45 +00001784 ServiceDispatcher(ServiceConnection conn,
1785 Context context, Executor activityExecutor, int flags) {
1786 mIServiceConnection = new InnerConnection(this);
1787 mConnection = conn;
1788 mContext = context;
1789 mActivityThread = null;
1790 mActivityExecutor = activityExecutor;
1791 mLocation = new ServiceConnectionLeaked(null);
1792 mLocation.fillInStackTrace();
1793 mFlags = flags;
1794 }
1795
1796 void validate(Context context, Handler activityThread, Executor activityExecutor) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001797 if (mContext != context) {
1798 throw new RuntimeException(
1799 "ServiceConnection " + mConnection +
1800 " registered with differing Context (was " +
1801 mContext + " now " + context + ")");
1802 }
1803 if (mActivityThread != activityThread) {
1804 throw new RuntimeException(
1805 "ServiceConnection " + mConnection +
1806 " registered with differing handler (was " +
1807 mActivityThread + " now " + activityThread + ")");
1808 }
Bo Liu58a57662019-03-06 20:21:45 +00001809 if (mActivityExecutor != activityExecutor) {
1810 throw new RuntimeException(
1811 "ServiceConnection " + mConnection +
1812 " registered with differing executor (was " +
1813 mActivityExecutor + " now " + activityExecutor + ")");
1814 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001815 }
1816
1817 void doForget() {
1818 synchronized(this) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001819 for (int i=0; i<mActiveConnections.size(); i++) {
1820 ServiceDispatcher.ConnectionInfo ci = mActiveConnections.valueAt(i);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001821 ci.binder.unlinkToDeath(ci.deathMonitor, 0);
1822 }
1823 mActiveConnections.clear();
Dianne Hackborn5a6ef732011-11-11 12:31:52 -08001824 mForgotten = true;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001825 }
1826 }
1827
1828 ServiceConnectionLeaked getLocation() {
1829 return mLocation;
1830 }
1831
1832 ServiceConnection getServiceConnection() {
1833 return mConnection;
1834 }
1835
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001836 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001837 IServiceConnection getIServiceConnection() {
1838 return mIServiceConnection;
1839 }
1840
1841 int getFlags() {
1842 return mFlags;
1843 }
1844
1845 void setUnbindLocation(RuntimeException ex) {
1846 mUnbindLocation = ex;
1847 }
1848
1849 RuntimeException getUnbindLocation() {
1850 return mUnbindLocation;
1851 }
1852
Dianne Hackborn94846032017-03-31 17:55:23 -07001853 public void connected(ComponentName name, IBinder service, boolean dead) {
Bo Liu58a57662019-03-06 20:21:45 +00001854 if (mActivityExecutor != null) {
1855 mActivityExecutor.execute(new RunConnection(name, service, 0, dead));
1856 } else if (mActivityThread != null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001857 mActivityThread.post(new RunConnection(name, service, 0, dead));
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001858 } else {
Dianne Hackborn94846032017-03-31 17:55:23 -07001859 doConnected(name, service, dead);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001860 }
1861 }
1862
1863 public void death(ComponentName name, IBinder service) {
Bo Liu58a57662019-03-06 20:21:45 +00001864 if (mActivityExecutor != null) {
1865 mActivityExecutor.execute(new RunConnection(name, service, 1, false));
1866 } else if (mActivityThread != null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001867 mActivityThread.post(new RunConnection(name, service, 1, false));
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001868 } else {
1869 doDeath(name, service);
1870 }
1871 }
1872
Dianne Hackborn94846032017-03-31 17:55:23 -07001873 public void doConnected(ComponentName name, IBinder service, boolean dead) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001874 ServiceDispatcher.ConnectionInfo old;
1875 ServiceDispatcher.ConnectionInfo info;
1876
1877 synchronized (this) {
Dianne Hackborn5a6ef732011-11-11 12:31:52 -08001878 if (mForgotten) {
1879 // We unbound before receiving the connection; ignore
1880 // any connection received.
1881 return;
1882 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001883 old = mActiveConnections.get(name);
1884 if (old != null && old.binder == service) {
1885 // Huh, already have this one. Oh well!
1886 return;
1887 }
1888
1889 if (service != null) {
1890 // A new service is being connected... set it all up.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001891 info = new ConnectionInfo();
1892 info.binder = service;
1893 info.deathMonitor = new DeathMonitor(name, service);
1894 try {
1895 service.linkToDeath(info.deathMonitor, 0);
1896 mActiveConnections.put(name, info);
1897 } catch (RemoteException e) {
1898 // This service was dead before we got it... just
1899 // don't do anything with it.
1900 mActiveConnections.remove(name);
1901 return;
1902 }
1903
1904 } else {
1905 // The named service is being disconnected... clean up.
1906 mActiveConnections.remove(name);
1907 }
1908
1909 if (old != null) {
1910 old.binder.unlinkToDeath(old.deathMonitor, 0);
1911 }
1912 }
1913
Adrian Roosa9b43182016-07-21 13:20:38 -07001914 // If there was an old service, it is now disconnected.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001915 if (old != null) {
1916 mConnection.onServiceDisconnected(name);
1917 }
Dianne Hackborn94846032017-03-31 17:55:23 -07001918 if (dead) {
Dianne Hackbornac265342017-04-19 14:53:18 -07001919 mConnection.onBindingDied(name);
Dianne Hackborn94846032017-03-31 17:55:23 -07001920 }
Christopher Tate5d73b6d2017-10-06 16:15:34 -07001921 // If there is a new viable service, it is now connected.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001922 if (service != null) {
1923 mConnection.onServiceConnected(name, service);
Christopher Tate5d73b6d2017-10-06 16:15:34 -07001924 } else {
1925 // The binding machinery worked, but the remote returned null from onBind().
1926 mConnection.onNullBinding(name);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001927 }
1928 }
1929
1930 public void doDeath(ComponentName name, IBinder service) {
Adrian Roosa9b43182016-07-21 13:20:38 -07001931 synchronized (this) {
1932 ConnectionInfo old = mActiveConnections.get(name);
1933 if (old == null || old.binder != service) {
1934 // Death for someone different than who we last
1935 // reported... just ignore it.
1936 return;
1937 }
1938 mActiveConnections.remove(name);
1939 old.binder.unlinkToDeath(old.deathMonitor, 0);
1940 }
1941
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001942 mConnection.onServiceDisconnected(name);
1943 }
1944
1945 private final class RunConnection implements Runnable {
Dianne Hackborn94846032017-03-31 17:55:23 -07001946 RunConnection(ComponentName name, IBinder service, int command, boolean dead) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001947 mName = name;
1948 mService = service;
1949 mCommand = command;
Dianne Hackborn94846032017-03-31 17:55:23 -07001950 mDead = dead;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001951 }
1952
1953 public void run() {
1954 if (mCommand == 0) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001955 doConnected(mName, mService, mDead);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001956 } else if (mCommand == 1) {
1957 doDeath(mName, mService);
1958 }
1959 }
1960
1961 final ComponentName mName;
1962 final IBinder mService;
1963 final int mCommand;
Dianne Hackborn94846032017-03-31 17:55:23 -07001964 final boolean mDead;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001965 }
1966
1967 private final class DeathMonitor implements IBinder.DeathRecipient
1968 {
1969 DeathMonitor(ComponentName name, IBinder service) {
1970 mName = name;
1971 mService = service;
1972 }
1973
1974 public void binderDied() {
1975 death(mName, mService);
1976 }
1977
1978 final ComponentName mName;
1979 final IBinder mService;
1980 }
1981 }
1982}