blob: f0d0e98b841f6da86e3b41859292312618dbffa4 [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(),
368 getClassLoader());
Todd Kennedy39bfee52016-02-24 10:28:21 -0800369 }
370 }
David Brazdilfd6dcc22018-10-25 14:07:51 +0100371 mAppComponentFactory = createAppFactory(aInfo, mDefaultClassLoader);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800372 }
373
374 private void setApplicationInfo(ApplicationInfo aInfo) {
375 final int myUid = Process.myUid();
376 aInfo = adjustNativeLibraryPaths(aInfo);
377 mApplicationInfo = aInfo;
378 mAppDir = aInfo.sourceDir;
379 mResDir = aInfo.uid == myUid ? aInfo.sourceDir : aInfo.publicSourceDir;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800380 mOverlayDirs = aInfo.resourceDirs;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800381 mDataDir = aInfo.dataDir;
382 mLibDir = aInfo.nativeLibraryDir;
383 mDataDirFile = FileUtils.newFileOrNull(aInfo.dataDir);
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600384 mDeviceProtectedDataDirFile = FileUtils.newFileOrNull(aInfo.deviceProtectedDataDir);
385 mCredentialProtectedDataDirFile = FileUtils.newFileOrNull(aInfo.credentialProtectedDataDir);
Adam Lesinski4e862812016-11-21 16:02:24 -0800386
387 mSplitNames = aInfo.splitNames;
388 mSplitAppDirs = aInfo.splitSourceDirs;
389 mSplitResDirs = aInfo.uid == myUid ? aInfo.splitSourceDirs : aInfo.splitPublicSourceDirs;
Narayan Kamathf9419f02017-06-15 11:35:38 +0100390 mSplitClassLoaderNames = aInfo.splitClassLoaderNames;
Adam Lesinski4e862812016-11-21 16:02:24 -0800391
392 if (aInfo.requestsIsolatedSplitLoading() && !ArrayUtils.isEmpty(mSplitNames)) {
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800393 mSplitLoader = new SplitDependencyLoaderImpl(aInfo.splitDependencies);
Adam Lesinski4e862812016-11-21 16:02:24 -0800394 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800395 }
396
Dimitry Ivanov638d8102017-02-22 15:39:42 -0800397 public static void makePaths(ActivityThread activityThread,
398 ApplicationInfo aInfo,
399 List<String> outZipPaths) {
400 makePaths(activityThread, false, aInfo, outZipPaths, null);
401 }
402
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000403 private static void appendSharedLibrariesLibPathsIfNeeded(
404 List<SharedLibraryInfo> sharedLibraries, ApplicationInfo aInfo,
405 Set<String> outSeenPaths,
406 List<String> outLibPaths) {
407 if (sharedLibraries == null) {
408 return;
409 }
410 for (SharedLibraryInfo lib : sharedLibraries) {
411 List<String> paths = lib.getAllCodePaths();
412 outSeenPaths.addAll(paths);
413 for (String path : paths) {
414 appendApkLibPathIfNeeded(path, aInfo, outLibPaths);
415 }
416 appendSharedLibrariesLibPathsIfNeeded(
417 lib.getDependencies(), aInfo, outSeenPaths, outLibPaths);
418 }
419 }
420
Dimitry Ivanov638d8102017-02-22 15:39:42 -0800421 public static void makePaths(ActivityThread activityThread,
422 boolean isBundledApp,
423 ApplicationInfo aInfo,
424 List<String> outZipPaths,
425 List<String> outLibPaths) {
Todd Kennedy39bfee52016-02-24 10:28:21 -0800426 final String appDir = aInfo.sourceDir;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800427 final String libDir = aInfo.nativeLibraryDir;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800428
429 outZipPaths.clear();
430 outZipPaths.add(appDir);
Adam Lesinski4e862812016-11-21 16:02:24 -0800431
432 // Do not load all available splits if the app requested isolated split loading.
433 if (aInfo.splitSourceDirs != null && !aInfo.requestsIsolatedSplitLoading()) {
434 Collections.addAll(outZipPaths, aInfo.splitSourceDirs);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800435 }
436
437 if (outLibPaths != null) {
438 outLibPaths.clear();
439 }
440
441 /*
442 * The following is a bit of a hack to inject
443 * instrumentation into the system: If the app
444 * being started matches one of the instrumentation names,
445 * then we combine both the "instrumentation" and
446 * "instrumented" app into the path, along with the
447 * concatenation of both apps' shared library lists.
448 */
449
Todd Kennedy39bfee52016-02-24 10:28:21 -0800450 String[] instrumentationLibs = null;
Torne (Richard Coles)3b6ca992016-10-10 15:11:36 +0100451 // activityThread will be null when called from the WebView zygote; just assume
452 // no instrumentation applies in this case.
453 if (activityThread != null) {
454 String instrumentationPackageName = activityThread.mInstrumentationPackageName;
455 String instrumentationAppDir = activityThread.mInstrumentationAppDir;
456 String[] instrumentationSplitAppDirs = activityThread.mInstrumentationSplitAppDirs;
457 String instrumentationLibDir = activityThread.mInstrumentationLibDir;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800458
Torne (Richard Coles)3b6ca992016-10-10 15:11:36 +0100459 String instrumentedAppDir = activityThread.mInstrumentedAppDir;
460 String[] instrumentedSplitAppDirs = activityThread.mInstrumentedSplitAppDirs;
461 String instrumentedLibDir = activityThread.mInstrumentedLibDir;
462
463 if (appDir.equals(instrumentationAppDir)
464 || appDir.equals(instrumentedAppDir)) {
465 outZipPaths.clear();
466 outZipPaths.add(instrumentationAppDir);
Jason O'Brien6f2978c92020-01-08 11:03:37 -0600467 if (!instrumentationAppDir.equals(instrumentedAppDir)) {
468 outZipPaths.add(instrumentedAppDir);
469 }
Adam Lesinski4e862812016-11-21 16:02:24 -0800470
471 // Only add splits if the app did not request isolated split loading.
472 if (!aInfo.requestsIsolatedSplitLoading()) {
473 if (instrumentationSplitAppDirs != null) {
474 Collections.addAll(outZipPaths, instrumentationSplitAppDirs);
475 }
476
477 if (!instrumentationAppDir.equals(instrumentedAppDir)) {
Adam Lesinski4e862812016-11-21 16:02:24 -0800478 if (instrumentedSplitAppDirs != null) {
479 Collections.addAll(outZipPaths, instrumentedSplitAppDirs);
480 }
Torne (Richard Coles)3b6ca992016-10-10 15:11:36 +0100481 }
Jeff Haoc7b94822016-03-16 15:56:07 -0700482 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800483
Torne (Richard Coles)3b6ca992016-10-10 15:11:36 +0100484 if (outLibPaths != null) {
485 outLibPaths.add(instrumentationLibDir);
486 if (!instrumentationLibDir.equals(instrumentedLibDir)) {
487 outLibPaths.add(instrumentedLibDir);
488 }
489 }
490
491 if (!instrumentedAppDir.equals(instrumentationAppDir)) {
492 instrumentationLibs = getLibrariesFor(instrumentationPackageName);
493 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800494 }
495 }
496
497 if (outLibPaths != null) {
498 if (outLibPaths.isEmpty()) {
499 outLibPaths.add(libDir);
500 }
501
502 // Add path to libraries in apk for current abi. Do this now because more entries
503 // will be added to zipPaths that shouldn't be part of the library path.
504 if (aInfo.primaryCpuAbi != null) {
Alex Light20ed24f2016-04-20 14:07:43 -0700505 // Add fake libs into the library search path if we target prior to N.
Adam Lesinski4e862812016-11-21 16:02:24 -0800506 if (aInfo.targetSdkVersion < Build.VERSION_CODES.N) {
Alex Light20ed24f2016-04-20 14:07:43 -0700507 outLibPaths.add("/system/fake-libs" +
508 (VMRuntime.is64BitAbi(aInfo.primaryCpuAbi) ? "64" : ""));
509 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800510 for (String apk : outZipPaths) {
511 outLibPaths.add(apk + "!/lib/" + aInfo.primaryCpuAbi);
512 }
513 }
514
Dimitry Ivanov638d8102017-02-22 15:39:42 -0800515 if (isBundledApp) {
Todd Kennedy39bfee52016-02-24 10:28:21 -0800516 // Add path to system libraries to libPaths;
517 // Access to system libs should be limited
518 // to bundled applications; this is why updated
519 // system apps are not included.
520 outLibPaths.add(System.getProperty("java.library.path"));
521 }
522 }
523
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000524 // Add the shared libraries native paths. The dex files in shared libraries will
525 // be resolved through shared library loaders, which are setup later.
526 Set<String> outSeenPaths = new LinkedHashSet<>();
527 appendSharedLibrariesLibPathsIfNeeded(
528 aInfo.sharedLibraryInfos, aInfo, outSeenPaths, outLibPaths);
529
530 // ApplicationInfo.sharedLibraryFiles is a public API, so anyone can change it.
531 // We prepend shared libraries that the package manager hasn't seen, maintaining their
532 // original order where possible.
533 if (aInfo.sharedLibraryFiles != null) {
Jeff Hao090892f2017-04-24 17:37:31 -0700534 int index = 0;
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000535 for (String lib : aInfo.sharedLibraryFiles) {
536 if (!outSeenPaths.contains(lib) && !outZipPaths.contains(lib)) {
Jeff Hao090892f2017-04-24 17:37:31 -0700537 outZipPaths.add(index, lib);
538 index++;
Svetoslav Ganov40610e32017-06-20 19:35:51 -0700539 appendApkLibPathIfNeeded(lib, aInfo, outLibPaths);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800540 }
541 }
542 }
543
544 if (instrumentationLibs != null) {
545 for (String lib : instrumentationLibs) {
546 if (!outZipPaths.contains(lib)) {
547 outZipPaths.add(0, lib);
Svetoslav Ganov40610e32017-06-20 19:35:51 -0700548 appendApkLibPathIfNeeded(lib, aInfo, outLibPaths);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800549 }
550 }
551 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800552 }
553
Svetoslav Ganov40610e32017-06-20 19:35:51 -0700554 /**
555 * This method appends a path to the appropriate native library folder of a
556 * library if this library is hosted in an APK. This allows support for native
557 * shared libraries. The library API is determined based on the application
558 * ABI.
559 *
560 * @param path Path to the library.
561 * @param applicationInfo The application depending on the library.
562 * @param outLibPaths List to which to add the native lib path if needed.
563 */
564 private static void appendApkLibPathIfNeeded(@NonNull String path,
565 @NonNull ApplicationInfo applicationInfo, @Nullable List<String> outLibPaths) {
566 // Looking at the suffix is a little hacky but a safe and simple solution.
567 // We will be revisiting code in the next release and clean this up.
568 if (outLibPaths != null && applicationInfo.primaryCpuAbi != null && path.endsWith(".apk")) {
569 if (applicationInfo.targetSdkVersion >= Build.VERSION_CODES.O) {
570 outLibPaths.add(path + "!/lib/" + applicationInfo.primaryCpuAbi);
571 }
572 }
573 }
574
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800575 /*
576 * All indices received by the super class should be shifted by 1 when accessing mSplitNames,
577 * etc. The super class assumes the base APK is index 0, while the PackageManager APIs don't
578 * include the base APK in the list of splits.
579 */
580 private class SplitDependencyLoaderImpl extends SplitDependencyLoader<NameNotFoundException> {
Adam Lesinski4e862812016-11-21 16:02:24 -0800581 private final String[][] mCachedResourcePaths;
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800582 private final ClassLoader[] mCachedClassLoaders;
Adam Lesinski4e862812016-11-21 16:02:24 -0800583
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800584 SplitDependencyLoaderImpl(@NonNull SparseArray<int[]> dependencies) {
Adam Lesinski4e862812016-11-21 16:02:24 -0800585 super(dependencies);
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800586 mCachedResourcePaths = new String[mSplitNames.length + 1][];
587 mCachedClassLoaders = new ClassLoader[mSplitNames.length + 1];
Adam Lesinski4e862812016-11-21 16:02:24 -0800588 }
589
590 @Override
591 protected boolean isSplitCached(int splitIdx) {
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800592 return mCachedClassLoaders[splitIdx] != null;
Adam Lesinski4e862812016-11-21 16:02:24 -0800593 }
594
595 @Override
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800596 protected void constructSplit(int splitIdx, @NonNull int[] configSplitIndices,
597 int parentSplitIdx) throws NameNotFoundException {
Adam Lesinski4e862812016-11-21 16:02:24 -0800598 final ArrayList<String> splitPaths = new ArrayList<>();
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800599 if (splitIdx == 0) {
Adam Lesinski4e862812016-11-21 16:02:24 -0800600 createOrUpdateClassLoaderLocked(null);
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800601 mCachedClassLoaders[0] = mClassLoader;
602
603 // Never add the base resources here, they always get added no matter what.
604 for (int configSplitIdx : configSplitIndices) {
605 splitPaths.add(mSplitResDirs[configSplitIdx - 1]);
606 }
607 mCachedResourcePaths[0] = splitPaths.toArray(new String[splitPaths.size()]);
Adam Lesinski4e862812016-11-21 16:02:24 -0800608 return;
609 }
610
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800611 // Since we handled the special base case above, parentSplitIdx is always valid.
612 final ClassLoader parent = mCachedClassLoaders[parentSplitIdx];
613 mCachedClassLoaders[splitIdx] = ApplicationLoaders.getDefault().getClassLoader(
Narayan Kamathf9419f02017-06-15 11:35:38 +0100614 mSplitAppDirs[splitIdx - 1], getTargetSdkVersion(), false, null, null, parent,
615 mSplitClassLoaderNames[splitIdx - 1]);
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800616
617 Collections.addAll(splitPaths, mCachedResourcePaths[parentSplitIdx]);
618 splitPaths.add(mSplitResDirs[splitIdx - 1]);
619 for (int configSplitIdx : configSplitIndices) {
620 splitPaths.add(mSplitResDirs[configSplitIdx - 1]);
Adam Lesinski4e862812016-11-21 16:02:24 -0800621 }
Adam Lesinski4e862812016-11-21 16:02:24 -0800622 mCachedResourcePaths[splitIdx] = splitPaths.toArray(new String[splitPaths.size()]);
623 }
624
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800625 private int ensureSplitLoaded(String splitName) throws NameNotFoundException {
626 int idx = 0;
627 if (splitName != null) {
Adam Lesinski4e862812016-11-21 16:02:24 -0800628 idx = Arrays.binarySearch(mSplitNames, splitName);
629 if (idx < 0) {
630 throw new PackageManager.NameNotFoundException(
631 "Split name '" + splitName + "' is not installed");
632 }
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800633 idx += 1;
Adam Lesinski4e862812016-11-21 16:02:24 -0800634 }
Adam Lesinski4e862812016-11-21 16:02:24 -0800635 loadDependenciesForSplit(idx);
636 return idx;
637 }
638
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800639 ClassLoader getClassLoaderForSplit(String splitName) throws NameNotFoundException {
640 return mCachedClassLoaders[ensureSplitLoaded(splitName)];
Adam Lesinski4e862812016-11-21 16:02:24 -0800641 }
642
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800643 String[] getSplitPathsForSplit(String splitName) throws NameNotFoundException {
644 return mCachedResourcePaths[ensureSplitLoaded(splitName)];
Adam Lesinski4e862812016-11-21 16:02:24 -0800645 }
646 }
647
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800648 private SplitDependencyLoaderImpl mSplitLoader;
Adam Lesinski4e862812016-11-21 16:02:24 -0800649
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800650 ClassLoader getSplitClassLoader(String splitName) throws NameNotFoundException {
Adam Lesinski4e862812016-11-21 16:02:24 -0800651 if (mSplitLoader == null) {
652 return mClassLoader;
653 }
654 return mSplitLoader.getClassLoaderForSplit(splitName);
655 }
656
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800657 String[] getSplitPaths(String splitName) throws NameNotFoundException {
Adam Lesinski4e862812016-11-21 16:02:24 -0800658 if (mSplitLoader == null) {
659 return mSplitResDirs;
660 }
661 return mSplitLoader.getSplitPathsForSplit(splitName);
662 }
663
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000664 /**
665 * Create a class loader for the {@code sharedLibrary}. Shared libraries are canonicalized,
666 * so if we already created a class loader with that shared library, we return it.
667 *
668 * Implementation notes: the canonicalization of shared libraries is something dex2oat
669 * also does.
670 */
671 ClassLoader createSharedLibraryLoader(SharedLibraryInfo sharedLibrary,
672 boolean isBundledApp, String librarySearchPath, String libraryPermittedPath) {
673 List<String> paths = sharedLibrary.getAllCodePaths();
674 List<ClassLoader> sharedLibraries = createSharedLibrariesLoaders(
675 sharedLibrary.getDependencies(), isBundledApp, librarySearchPath,
676 libraryPermittedPath);
677 final String jars = (paths.size() == 1) ? paths.get(0) :
678 TextUtils.join(File.pathSeparator, paths);
679
680 // Shared libraries get a null parent: this has the side effect of having canonicalized
681 // shared libraries using ApplicationLoaders cache, which is the behavior we want.
Steven Morelandbdc27022019-03-29 21:23:48 +0000682 return ApplicationLoaders.getDefault().getSharedLibraryClassLoaderWithSharedLibraries(jars,
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000683 mApplicationInfo.targetSdkVersion, isBundledApp, librarySearchPath,
684 libraryPermittedPath, /* parent */ null,
685 /* classLoaderName */ null, sharedLibraries);
686 }
687
688 private List<ClassLoader> createSharedLibrariesLoaders(List<SharedLibraryInfo> sharedLibraries,
689 boolean isBundledApp, String librarySearchPath, String libraryPermittedPath) {
690 if (sharedLibraries == null) {
691 return null;
692 }
693 List<ClassLoader> loaders = new ArrayList<>();
694 for (SharedLibraryInfo info : sharedLibraries) {
695 loaders.add(createSharedLibraryLoader(
696 info, isBundledApp, librarySearchPath, libraryPermittedPath));
697 }
698 return loaders;
699 }
700
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100701 private StrictMode.ThreadPolicy allowThreadDiskReads() {
702 if (mActivityThread == null) {
703 // When LoadedApk is used without an ActivityThread (usually in a
704 // zygote context), don't call into StrictMode, as it initializes
705 // the binder subsystem, which we don't want.
706 return null;
707 }
708
709 return StrictMode.allowThreadDiskReads();
710 }
711
712 private void setThreadPolicy(StrictMode.ThreadPolicy policy) {
713 if (mActivityThread != null && policy != null) {
714 StrictMode.setThreadPolicy(policy);
715 }
716 }
717
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700718 private void createOrUpdateClassLoaderLocked(List<String> addedPaths) {
719 if (mPackageName.equals("android")) {
Calin Juravle430ef452016-04-22 17:43:07 +0100720 // Note: This branch is taken for system server and we don't need to setup
721 // jit profiling support.
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700722 if (mClassLoader != null) {
723 // nothing to update
724 return;
Dimitry Ivanovb9c90262016-02-19 14:09:20 -0800725 }
726
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700727 if (mBaseClassLoader != null) {
David Brazdilfd6dcc22018-10-25 14:07:51 +0100728 mDefaultClassLoader = mBaseClassLoader;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800729 } else {
David Brazdilfd6dcc22018-10-25 14:07:51 +0100730 mDefaultClassLoader = ClassLoader.getSystemClassLoader();
Todd Kennedy39bfee52016-02-24 10:28:21 -0800731 }
David Brazdilfd6dcc22018-10-25 14:07:51 +0100732 mAppComponentFactory = createAppFactory(mApplicationInfo, mDefaultClassLoader);
David Brazdil33bd3432019-02-27 20:15:18 +0000733 mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader,
734 new ApplicationInfo(mApplicationInfo));
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700735 return;
736 }
737
738 // Avoid the binder call when the package is the current application package.
739 // The activity manager will perform ensure that dexopt is performed before
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100740 // spinning up the process. Similarly, don't call into binder when we don't
741 // have an ActivityThread object.
742 if (mActivityThread != null
743 && !Objects.equals(mPackageName, ActivityThread.currentPackageName())
744 && mIncludeCode) {
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700745 try {
Brian Carlstromca82e612016-04-19 23:16:08 -0700746 ActivityThread.getPackageManager().notifyPackageUse(mPackageName,
747 PackageManager.NOTIFY_PACKAGE_USE_CROSS_PACKAGE);
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700748 } catch (RemoteException re) {
749 throw re.rethrowFromSystemServer();
Todd Kennedy39bfee52016-02-24 10:28:21 -0800750 }
751 }
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700752
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700753 if (mRegisterPackage) {
754 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -0800755 ActivityManager.getService().addPackageDependency(mPackageName);
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700756 } catch (RemoteException e) {
757 throw e.rethrowFromSystemServer();
758 }
759 }
760
Andreas Gampea8a58ff2016-05-18 11:58:39 -0700761 // Lists for the elements of zip/code and native libraries.
762 //
763 // Both lists are usually not empty. We expect on average one APK for the zip component,
764 // but shared libraries and splits are not uncommon. We expect at least three elements
765 // for native libraries (app-based, system, vendor). As such, give both some breathing
766 // space and initialize to a small value (instead of incurring growth code).
767 final List<String> zipPaths = new ArrayList<>(10);
768 final List<String> libPaths = new ArrayList<>(10);
Narayan Kamath8995b002016-05-11 20:31:09 +0100769
Jiyong Parkfcad6962017-08-22 10:24:28 +0900770 boolean isBundledApp = mApplicationInfo.isSystemApp()
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700771 && !mApplicationInfo.isUpdatedSystemApp();
Dimitry Ivanovbf3b5f72016-05-03 11:34:58 -0700772
Jiyong Parkfcad6962017-08-22 10:24:28 +0900773 // Vendor apks are treated as bundled only when /vendor/lib is in the default search
774 // paths. If not, they are treated as unbundled; access to system libs is limited.
775 // Having /vendor/lib in the default search paths means that all system processes
776 // are allowed to use any vendor library, which in turn means that system is dependent
777 // on vendor partition. In the contrary, not having /vendor/lib in the default search
778 // paths mean that the two partitions are separated and thus we can treat vendor apks
779 // as unbundled.
780 final String defaultSearchPaths = System.getProperty("java.library.path");
781 final boolean treatVendorApkAsUnbundled = !defaultSearchPaths.contains("/vendor/lib");
Jiyong Park63495c22017-09-15 07:48:06 +0900782 if (mApplicationInfo.getCodePath() != null
Jiyong Park002fdbd2017-02-13 20:50:31 +0900783 && mApplicationInfo.isVendor() && treatVendorApkAsUnbundled) {
Jiyong Parkfcad6962017-08-22 10:24:28 +0900784 isBundledApp = false;
785 }
786
Kiyoung Kimdd6861e2019-03-11 11:48:14 +0900787 // Similar to vendor apks, we should add /product/lib for apks from product partition
Kiyoung Kim22557fe2019-03-28 13:38:12 +0900788 // when product apps are marked as unbundled. We cannot use the same way from vendor
789 // to check if lib path exists because there is possibility that /product/lib would not
Justin Yun1ef374f2019-12-17 15:15:34 +0900790 // exist from legacy device while product apks are bundled. To make this clear, we use
791 // "ro.product.vndk.version" property. If the property is defined, we regard all product
792 // apks as unbundled.
Kiyoung Kimdd6861e2019-03-11 11:48:14 +0900793 if (mApplicationInfo.getCodePath() != null
Justin Yun1ef374f2019-12-17 15:15:34 +0900794 && mApplicationInfo.isProduct()
795 && VndkProperties.product_vndk_version().isPresent()) {
Kiyoung Kimdd6861e2019-03-11 11:48:14 +0900796 isBundledApp = false;
797 }
798
Dimitry Ivanov638d8102017-02-22 15:39:42 -0800799 makePaths(mActivityThread, isBundledApp, mApplicationInfo, zipPaths, libPaths);
800
Dimitry Ivanoveb96b002016-05-10 10:51:40 -0700801 String libraryPermittedPath = mDataDir;
Jiyong Park29d9eba2018-05-04 12:44:38 +0900802
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700803 if (isBundledApp) {
Jiyong Park29d9eba2018-05-04 12:44:38 +0900804 // For bundled apps, add the base directory of the app (e.g.,
805 // /system/app/Foo/) to the permitted paths so that it can load libraries
806 // embedded in module apks under the directory. For now, GmsCore is relying
807 // on this, but this isn't specific to the app. Also note that, we don't
808 // need to do this for unbundled apps as entire /data is already set to
809 // the permitted paths for them.
810 libraryPermittedPath += File.pathSeparator
811 + Paths.get(getAppDir()).getParent().toString();
812
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700813 // This is necessary to grant bundled apps access to
814 // libraries located in subdirectories of /system/lib
Jiyong Parkfcad6962017-08-22 10:24:28 +0900815 libraryPermittedPath += File.pathSeparator + defaultSearchPaths;
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700816 }
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700817
818 final String librarySearchPath = TextUtils.join(File.pathSeparator, libPaths);
819
Narayan Kamath8995b002016-05-11 20:31:09 +0100820 // If we're not asked to include code, we construct a classloader that has
821 // no code path included. We still need to set up the library search paths
822 // and permitted path because NativeActivity relies on it (it attempts to
823 // call System.loadLibrary() on a classloader from a LoadedApk with
824 // mIncludeCode == false).
825 if (!mIncludeCode) {
David Brazdilfd6dcc22018-10-25 14:07:51 +0100826 if (mDefaultClassLoader == null) {
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100827 StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads();
David Brazdilfd6dcc22018-10-25 14:07:51 +0100828 mDefaultClassLoader = ApplicationLoaders.getDefault().getClassLoader(
Narayan Kamathf9419f02017-06-15 11:35:38 +0100829 "" /* codePath */, mApplicationInfo.targetSdkVersion, isBundledApp,
830 librarySearchPath, libraryPermittedPath, mBaseClassLoader,
831 null /* classLoaderName */);
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100832 setThreadPolicy(oldPolicy);
Jason Monk2544c692018-05-15 11:30:09 -0400833 mAppComponentFactory = AppComponentFactory.DEFAULT;
Narayan Kamath8995b002016-05-11 20:31:09 +0100834 }
835
David Brazdilfd6dcc22018-10-25 14:07:51 +0100836 if (mClassLoader == null) {
David Brazdil33bd3432019-02-27 20:15:18 +0000837 mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader,
838 new ApplicationInfo(mApplicationInfo));
David Brazdilfd6dcc22018-10-25 14:07:51 +0100839 }
840
Narayan Kamath8995b002016-05-11 20:31:09 +0100841 return;
842 }
843
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700844 /*
Narayan Kamath8995b002016-05-11 20:31:09 +0100845 * With all the combination done (if necessary, actually create the java class
846 * loader and set up JIT profiling support if necessary.
Andreas Gampea8a58ff2016-05-18 11:58:39 -0700847 *
848 * In many cases this is a single APK, so try to avoid the StringBuilder in TextUtils.
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700849 */
Andreas Gampea8a58ff2016-05-18 11:58:39 -0700850 final String zip = (zipPaths.size() == 1) ? zipPaths.get(0) :
851 TextUtils.join(File.pathSeparator, zipPaths);
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700852
Dianne Hackborn94846032017-03-31 17:55:23 -0700853 if (DEBUG) Slog.v(ActivityThread.TAG, "Class path: " + zip +
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700854 ", JNI path: " + librarySearchPath);
855
Calin Juravle430ef452016-04-22 17:43:07 +0100856 boolean needToSetupJitProfiles = false;
David Brazdilfd6dcc22018-10-25 14:07:51 +0100857 if (mDefaultClassLoader == null) {
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700858 // Temporarily disable logging of disk reads on the Looper thread
859 // as this is early and necessary.
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100860 StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads();
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700861
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000862 List<ClassLoader> sharedLibraries = createSharedLibrariesLoaders(
863 mApplicationInfo.sharedLibraryInfos, isBundledApp, librarySearchPath,
864 libraryPermittedPath);
865
866 mDefaultClassLoader = ApplicationLoaders.getDefault().getClassLoaderWithSharedLibraries(
867 zip, mApplicationInfo.targetSdkVersion, isBundledApp, librarySearchPath,
Narayan Kamathf9419f02017-06-15 11:35:38 +0100868 libraryPermittedPath, mBaseClassLoader,
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000869 mApplicationInfo.classLoaderName, sharedLibraries);
David Brazdilfd6dcc22018-10-25 14:07:51 +0100870 mAppComponentFactory = createAppFactory(mApplicationInfo, mDefaultClassLoader);
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700871
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100872 setThreadPolicy(oldPolicy);
Calin Juravle430ef452016-04-22 17:43:07 +0100873 // Setup the class loader paths for profiling.
874 needToSetupJitProfiles = true;
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700875 }
876
Patrick Baumann1bea2372018-03-13 14:26:58 -0700877 if (!libPaths.isEmpty() && SystemProperties.getBoolean(PROPERTY_NAME_APPEND_NATIVE, true)) {
Patrick Baumann5c5daa42018-05-09 11:12:49 -0700878 // Temporarily disable logging of disk reads on the Looper thread as this is necessary
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100879 StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads();
Patrick Baumann5c5daa42018-05-09 11:12:49 -0700880 try {
David Brazdilfd6dcc22018-10-25 14:07:51 +0100881 ApplicationLoaders.getDefault().addNative(mDefaultClassLoader, libPaths);
Patrick Baumann5c5daa42018-05-09 11:12:49 -0700882 } finally {
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100883 setThreadPolicy(oldPolicy);
Patrick Baumann5c5daa42018-05-09 11:12:49 -0700884 }
Patrick Baumann1bea2372018-03-13 14:26:58 -0700885 }
886
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700887 if (addedPaths != null && addedPaths.size() > 0) {
888 final String add = TextUtils.join(File.pathSeparator, addedPaths);
David Brazdilfd6dcc22018-10-25 14:07:51 +0100889 ApplicationLoaders.getDefault().addPath(mDefaultClassLoader, add);
Calin Juravle430ef452016-04-22 17:43:07 +0100890 // Setup the new code paths for profiling.
891 needToSetupJitProfiles = true;
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700892 }
Calin Juravle2a727d72016-04-15 19:33:46 +0100893
894 // Setup jit profile support.
Narayan Kamath2d4a2222016-04-25 19:16:56 +0100895 //
Calin Juravle2a727d72016-04-15 19:33:46 +0100896 // It is ok to call this multiple times if the application gets updated with new splits.
897 // The runtime only keeps track of unique code paths and can handle re-registration of
898 // the same code path. There's no need to pass `addedPaths` since any new code paths
899 // are already in `mApplicationInfo`.
Narayan Kamath2d4a2222016-04-25 19:16:56 +0100900 //
901 // It is NOT ok to call this function from the system_server (for any of the packages it
902 // loads code from) so we explicitly disallow it there.
Bo Liu6c504ae2019-04-05 14:54:52 -0400903 //
904 // It is not ok to call this in a zygote context where mActivityThread is null.
905 if (needToSetupJitProfiles && !ActivityThread.isSystem() && mActivityThread != null) {
Calin Juravle430ef452016-04-22 17:43:07 +0100906 setupJitProfileSupport();
Calin Juravle430ef452016-04-22 17:43:07 +0100907 }
David Brazdilfd6dcc22018-10-25 14:07:51 +0100908
909 // Call AppComponentFactory to select/create the main class loader of this app.
910 // Since this may call code in the app, mDefaultClassLoader must be fully set up
911 // before invoking the factory.
David Brazdil33bd3432019-02-27 20:15:18 +0000912 // Invoke with a copy of ApplicationInfo to protect against the app changing it.
David Brazdilfd6dcc22018-10-25 14:07:51 +0100913 if (mClassLoader == null) {
David Brazdil33bd3432019-02-27 20:15:18 +0000914 mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader,
915 new ApplicationInfo(mApplicationInfo));
David Brazdilfd6dcc22018-10-25 14:07:51 +0100916 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800917 }
918
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100919 @UnsupportedAppUsage
Todd Kennedy39bfee52016-02-24 10:28:21 -0800920 public ClassLoader getClassLoader() {
921 synchronized (this) {
922 if (mClassLoader == null) {
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700923 createOrUpdateClassLoaderLocked(null /*addedPaths*/);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800924 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700925 return mClassLoader;
926 }
927 }
928
Calin Juravle2a727d72016-04-15 19:33:46 +0100929 private void setupJitProfileSupport() {
930 if (!SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false)) {
931 return;
932 }
David Brazdil991ff902018-12-03 10:59:29 +0000933
934 // If we use profiles, setup the dex reporter to notify package manager
935 // of any relevant dex loads. The idle maintenance job will use the information
936 // reported to optimize the loaded dex files.
937 // Note that we only need one global reporter per app.
938 // Make sure we do this before invoking app code for the first time so that we
939 // can capture the complete application startup.
940 BaseDexClassLoader.setReporter(DexLoadReporter.getInstance());
941
Calin Juravle126f7802016-05-24 15:23:47 +0100942 // Only set up profile support if the loaded apk has the same uid as the
943 // current process.
944 // Currently, we do not support profiling across different apps.
945 // (e.g. application's uid might be different when the code is
946 // loaded by another app via createApplicationContext)
947 if (mApplicationInfo.uid != Process.myUid()) {
948 return;
949 }
950
Calin Juravle2a727d72016-04-15 19:33:46 +0100951 final List<String> codePaths = new ArrayList<>();
952 if ((mApplicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0) {
953 codePaths.add(mApplicationInfo.sourceDir);
954 }
955 if (mApplicationInfo.splitSourceDirs != null) {
956 Collections.addAll(codePaths, mApplicationInfo.splitSourceDirs);
957 }
958
959 if (codePaths.isEmpty()) {
960 // If there are no code paths there's no need to setup a profile file and register with
961 // the runtime,
962 return;
963 }
964
Calin Juravle6ae39fc2018-01-19 20:32:47 -0800965 for (int i = codePaths.size() - 1; i >= 0; i--) {
966 String splitName = i == 0 ? null : mApplicationInfo.splitNames[i - 1];
967 String profileFile = ArtManager.getCurrentProfilePath(
968 mPackageName, UserHandle.myUserId(), splitName);
969 VMRuntime.registerAppInfo(profileFile, new String[] {codePaths.get(i)});
970 }
Calin Juravlef5a7bfc2017-03-13 23:30:30 -0700971
972 // Register the app data directory with the reporter. It will
973 // help deciding whether or not a dex file is the primary apk or a
974 // secondary dex.
975 DexLoadReporter.getInstance().registerAppDataDir(mPackageName, mDataDir);
Calin Juravle2a727d72016-04-15 19:33:46 +0100976 }
977
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700978 /**
979 * Setup value for Thread.getContextClassLoader(). If the
980 * package will not run in in a VM with other packages, we set
981 * the Java context ClassLoader to the
982 * PackageInfo.getClassLoader value. However, if this VM can
983 * contain multiple packages, we intead set the Java context
984 * ClassLoader to a proxy that will warn about the use of Java
985 * context ClassLoaders and then fall through to use the
986 * system ClassLoader.
987 *
988 * <p> Note that this is similar to but not the same as the
989 * android.content.Context.getClassLoader(). While both
990 * context class loaders are typically set to the
991 * PathClassLoader used to load the package archive in the
992 * single application per VM case, a single Android process
993 * may contain several Contexts executing on one thread with
994 * their own logical ClassLoaders while the Java context
995 * ClassLoader is a thread local. This is why in the case when
996 * we have multiple packages per VM we do not set the Java
997 * context ClassLoader to an arbitrary but instead warn the
998 * user to set their own if we detect that they are using a
999 * Java library that expects it to be set.
1000 */
1001 private void initializeJavaContextClassLoader() {
1002 IPackageManager pm = ActivityThread.getPackageManager();
1003 android.content.pm.PackageInfo pi;
1004 try {
Jeff Sharkeyc7bacab2016-02-09 15:56:11 -07001005 pi = pm.getPackageInfo(mPackageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
1006 UserHandle.myUserId());
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001007 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001008 throw e.rethrowFromSystemServer();
Dianne Hackborn208d9372013-02-25 13:17:54 -08001009 }
1010 if (pi == null) {
1011 throw new IllegalStateException("Unable to get package info for "
1012 + mPackageName + "; is package not installed?");
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001013 }
1014 /*
1015 * Two possible indications that this package could be
1016 * sharing its virtual machine with other packages:
1017 *
1018 * 1.) the sharedUserId attribute is set in the manifest,
1019 * indicating a request to share a VM with other
1020 * packages with the same sharedUserId.
1021 *
1022 * 2.) the application element of the manifest has an
1023 * attribute specifying a non-default process name,
1024 * indicating the desire to run in another packages VM.
1025 */
1026 boolean sharedUserIdSet = (pi.sharedUserId != null);
1027 boolean processNameNotDefault =
1028 (pi.applicationInfo != null &&
1029 !mPackageName.equals(pi.applicationInfo.processName));
1030 boolean sharable = (sharedUserIdSet || processNameNotDefault);
1031 ClassLoader contextClassLoader =
1032 (sharable)
1033 ? new WarningContextClassLoader()
1034 : mClassLoader;
1035 Thread.currentThread().setContextClassLoader(contextClassLoader);
1036 }
1037
1038 private static class WarningContextClassLoader extends ClassLoader {
1039
1040 private static boolean warned = false;
1041
1042 private void warn(String methodName) {
1043 if (warned) {
1044 return;
1045 }
1046 warned = true;
1047 Thread.currentThread().setContextClassLoader(getParent());
1048 Slog.w(ActivityThread.TAG, "ClassLoader." + methodName + ": " +
1049 "The class loader returned by " +
1050 "Thread.getContextClassLoader() may fail for processes " +
1051 "that host multiple applications. You should explicitly " +
1052 "specify a context class loader. For example: " +
1053 "Thread.setContextClassLoader(getClass().getClassLoader());");
1054 }
1055
1056 @Override public URL getResource(String resName) {
1057 warn("getResource");
1058 return getParent().getResource(resName);
1059 }
1060
1061 @Override public Enumeration<URL> getResources(String resName) throws IOException {
1062 warn("getResources");
1063 return getParent().getResources(resName);
1064 }
1065
1066 @Override public InputStream getResourceAsStream(String resName) {
1067 warn("getResourceAsStream");
1068 return getParent().getResourceAsStream(resName);
1069 }
1070
1071 @Override public Class<?> loadClass(String className) throws ClassNotFoundException {
1072 warn("loadClass");
1073 return getParent().loadClass(className);
1074 }
1075
1076 @Override public void setClassAssertionStatus(String cname, boolean enable) {
1077 warn("setClassAssertionStatus");
1078 getParent().setClassAssertionStatus(cname, enable);
1079 }
1080
1081 @Override public void setPackageAssertionStatus(String pname, boolean enable) {
1082 warn("setPackageAssertionStatus");
1083 getParent().setPackageAssertionStatus(pname, enable);
1084 }
1085
1086 @Override public void setDefaultAssertionStatus(boolean enable) {
1087 warn("setDefaultAssertionStatus");
1088 getParent().setDefaultAssertionStatus(enable);
1089 }
1090
1091 @Override public void clearAssertionStatus() {
1092 warn("clearAssertionStatus");
1093 getParent().clearAssertionStatus();
1094 }
1095 }
1096
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001097 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001098 public String getAppDir() {
1099 return mAppDir;
1100 }
1101
Brian Carlstromd893a892012-04-01 21:30:26 -07001102 public String getLibDir() {
1103 return mLibDir;
1104 }
1105
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001106 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001107 public String getResDir() {
1108 return mResDir;
1109 }
1110
Jeff Sharkey8a4c9722014-06-16 13:48:42 -07001111 public String[] getSplitAppDirs() {
1112 return mSplitAppDirs;
1113 }
1114
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001115 @UnsupportedAppUsage
Jeff Sharkey8a4c9722014-06-16 13:48:42 -07001116 public String[] getSplitResDirs() {
1117 return mSplitResDirs;
1118 }
1119
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001120 @UnsupportedAppUsage
MÃ¥rten Kongstad48d22322014-01-31 14:43:27 +01001121 public String[] getOverlayDirs() {
1122 return mOverlayDirs;
1123 }
1124
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001125 public String getDataDir() {
1126 return mDataDir;
1127 }
1128
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001129 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001130 public File getDataDirFile() {
1131 return mDataDirFile;
1132 }
1133
Jeff Sharkey8a372a02016-03-16 16:25:45 -06001134 public File getDeviceProtectedDataDirFile() {
1135 return mDeviceProtectedDataDirFile;
Jeff Sharkey15447792015-11-05 16:18:51 -08001136 }
1137
Jeff Sharkey8a372a02016-03-16 16:25:45 -06001138 public File getCredentialProtectedDataDirFile() {
1139 return mCredentialProtectedDataDirFile;
Jeff Sharkey15447792015-11-05 16:18:51 -08001140 }
1141
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001142 @UnsupportedAppUsage
Adam Lesinski4e862812016-11-21 16:02:24 -08001143 public AssetManager getAssets() {
1144 return getResources().getAssets();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001145 }
1146
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001147 @UnsupportedAppUsage
Adam Lesinski4e862812016-11-21 16:02:24 -08001148 public Resources getResources() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001149 if (mResources == null) {
Adam Lesinski4e862812016-11-21 16:02:24 -08001150 final String[] splitPaths;
1151 try {
1152 splitPaths = getSplitPaths(null);
Adam Lesinski1665d0f2017-03-10 14:46:57 -08001153 } catch (NameNotFoundException e) {
Adam Lesinski4e862812016-11-21 16:02:24 -08001154 // This should never fail.
1155 throw new AssertionError("null split not found");
1156 }
1157
Todd Kennedy233a0b12018-01-29 20:30:24 +00001158 mResources = ResourcesManager.getInstance().getResources(null, mResDir,
1159 splitPaths, mOverlayDirs, mApplicationInfo.sharedLibraryFiles,
1160 Display.DEFAULT_DISPLAY, null, getCompatibilityInfo(),
Adam Lesinski4e862812016-11-21 16:02:24 -08001161 getClassLoader());
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001162 }
1163 return mResources;
1164 }
1165
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001166 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001167 public Application makeApplication(boolean forceDefaultAppClass,
1168 Instrumentation instrumentation) {
1169 if (mApplication != null) {
1170 return mApplication;
1171 }
1172
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001173 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");
1174
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001175 Application app = null;
1176
1177 String appClass = mApplicationInfo.className;
1178 if (forceDefaultAppClass || (appClass == null)) {
1179 appClass = "android.app.Application";
1180 }
1181
1182 try {
Ryan Mitchell73285142020-01-16 12:17:06 -08001183 final java.lang.ClassLoader cl = getClassLoader();
Narayan Kamath8091edb2014-10-15 11:38:44 +01001184 if (!mPackageName.equals("android")) {
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001185 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
1186 "initializeJavaContextClassLoader");
Narayan Kamath8091edb2014-10-15 11:38:44 +01001187 initializeJavaContextClassLoader();
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001188 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Narayan Kamath8091edb2014-10-15 11:38:44 +01001189 }
Ryan Mitchell73285142020-01-16 12:17:06 -08001190
1191 // Rewrite the R 'constants' for all library apks.
1192 SparseArray<String> packageIdentifiers = getAssets().getAssignedPackageIdentifiers(
1193 false, false);
1194 for (int i = 0, n = packageIdentifiers.size(); i < n; i++) {
1195 final int id = packageIdentifiers.keyAt(i);
1196 if (id == 0x01 || id == 0x7f) {
1197 continue;
1198 }
1199
1200 rewriteRValues(cl, packageIdentifiers.valueAt(i), id);
1201 }
1202
Jeff Browndefd4a62014-03-10 21:24:37 -07001203 ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001204 app = mActivityThread.mInstrumentation.newApplication(
1205 cl, appClass, appContext);
1206 appContext.setOuterContext(app);
1207 } catch (Exception e) {
1208 if (!mActivityThread.mInstrumentation.onException(app, e)) {
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001209 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001210 throw new RuntimeException(
1211 "Unable to instantiate application " + appClass
1212 + ": " + e.toString(), e);
1213 }
1214 }
1215 mActivityThread.mAllApplications.add(app);
1216 mApplication = app;
1217
1218 if (instrumentation != null) {
1219 try {
1220 instrumentation.callApplicationOnCreate(app);
1221 } catch (Exception e) {
1222 if (!instrumentation.onException(app, e)) {
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001223 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001224 throw new RuntimeException(
1225 "Unable to create application " + app.getClass().getName()
1226 + ": " + e.toString(), e);
1227 }
1228 }
1229 }
Adam Lesinskide898ff2014-01-29 18:20:45 -08001230
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001231 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1232
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001233 return app;
1234 }
1235
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001236 @UnsupportedAppUsage
Adam Lesinskide898ff2014-01-29 18:20:45 -08001237 private void rewriteRValues(ClassLoader cl, String packageName, int id) {
Adam Lesinski2cb761e2014-08-15 13:59:02 -07001238 final Class<?> rClazz;
Adam Lesinskide898ff2014-01-29 18:20:45 -08001239 try {
Adam Lesinski2cb761e2014-08-15 13:59:02 -07001240 rClazz = cl.loadClass(packageName + ".R");
1241 } catch (ClassNotFoundException e) {
1242 // This is not necessarily an error, as some packages do not ship with resources
1243 // (or they do not need rewriting).
Adam Lesinski1e4663852014-08-15 14:47:28 -07001244 Log.i(TAG, "No resource references to update in package " + packageName);
Adam Lesinski2cb761e2014-08-15 13:59:02 -07001245 return;
1246 }
1247
Adam Lesinski1e4663852014-08-15 14:47:28 -07001248 final Method callback;
Adam Lesinski2cb761e2014-08-15 13:59:02 -07001249 try {
Adam Lesinski1e4663852014-08-15 14:47:28 -07001250 callback = rClazz.getMethod("onResourcesLoaded", int.class);
1251 } catch (NoSuchMethodException e) {
1252 // No rewriting to be done.
1253 return;
Adam Lesinskide898ff2014-01-29 18:20:45 -08001254 }
Adam Lesinski1e4663852014-08-15 14:47:28 -07001255
1256 Throwable cause;
1257 try {
1258 callback.invoke(null, id);
1259 return;
1260 } catch (IllegalAccessException e) {
1261 cause = e;
1262 } catch (InvocationTargetException e) {
1263 cause = e.getCause();
1264 }
1265
1266 throw new RuntimeException("Failed to rewrite resource references for " + packageName,
1267 cause);
Adam Lesinskide898ff2014-01-29 18:20:45 -08001268 }
1269
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001270 public void removeContextRegistrations(Context context,
1271 String who, String what) {
Jeff Sharkeyd7026f12012-03-01 20:50:32 -08001272 final boolean reportRegistrationLeaks = StrictMode.vmRegistrationLeaksEnabled();
Adam Lesinski23d40c42014-11-20 11:58:21 -08001273 synchronized (mReceivers) {
1274 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> rmap =
1275 mReceivers.remove(context);
1276 if (rmap != null) {
1277 for (int i = 0; i < rmap.size(); i++) {
1278 LoadedApk.ReceiverDispatcher rd = rmap.valueAt(i);
1279 IntentReceiverLeaked leak = new IntentReceiverLeaked(
1280 what + " " + who + " has leaked IntentReceiver "
1281 + rd.getIntentReceiver() + " that was " +
1282 "originally registered here. Are you missing a " +
1283 "call to unregisterReceiver()?");
1284 leak.setStackTrace(rd.getLocation().getStackTrace());
1285 Slog.e(ActivityThread.TAG, leak.getMessage(), leak);
1286 if (reportRegistrationLeaks) {
1287 StrictMode.onIntentReceiverLeaked(leak);
1288 }
1289 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001290 ActivityManager.getService().unregisterReceiver(
Adam Lesinski23d40c42014-11-20 11:58:21 -08001291 rd.getIIntentReceiver());
1292 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001293 throw e.rethrowFromSystemServer();
Adam Lesinski23d40c42014-11-20 11:58:21 -08001294 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001295 }
1296 }
Adam Lesinski23d40c42014-11-20 11:58:21 -08001297 mUnregisteredReceivers.remove(context);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001298 }
Adam Lesinski23d40c42014-11-20 11:58:21 -08001299
1300 synchronized (mServices) {
1301 //Slog.i(TAG, "Receiver registrations: " + mReceivers);
1302 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> smap =
1303 mServices.remove(context);
1304 if (smap != null) {
1305 for (int i = 0; i < smap.size(); i++) {
1306 LoadedApk.ServiceDispatcher sd = smap.valueAt(i);
1307 ServiceConnectionLeaked leak = new ServiceConnectionLeaked(
1308 what + " " + who + " has leaked ServiceConnection "
1309 + sd.getServiceConnection() + " that was originally bound here");
1310 leak.setStackTrace(sd.getLocation().getStackTrace());
1311 Slog.e(ActivityThread.TAG, leak.getMessage(), leak);
1312 if (reportRegistrationLeaks) {
1313 StrictMode.onServiceConnectionLeaked(leak);
1314 }
1315 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001316 ActivityManager.getService().unbindService(
Adam Lesinski23d40c42014-11-20 11:58:21 -08001317 sd.getIServiceConnection());
1318 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001319 throw e.rethrowFromSystemServer();
Adam Lesinski23d40c42014-11-20 11:58:21 -08001320 }
1321 sd.doForget();
Jeff Sharkeyd7026f12012-03-01 20:50:32 -08001322 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001323 }
Adam Lesinski23d40c42014-11-20 11:58:21 -08001324 mUnboundServices.remove(context);
1325 //Slog.i(TAG, "Service registrations: " + mServices);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001326 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001327 }
1328
1329 public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r,
1330 Context context, Handler handler,
1331 Instrumentation instrumentation, boolean registered) {
1332 synchronized (mReceivers) {
1333 LoadedApk.ReceiverDispatcher rd = null;
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001334 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001335 if (registered) {
1336 map = mReceivers.get(context);
1337 if (map != null) {
1338 rd = map.get(r);
1339 }
1340 }
1341 if (rd == null) {
1342 rd = new ReceiverDispatcher(r, context, handler,
1343 instrumentation, registered);
1344 if (registered) {
1345 if (map == null) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001346 map = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001347 mReceivers.put(context, map);
1348 }
1349 map.put(r, rd);
1350 }
1351 } else {
1352 rd.validate(context, handler);
1353 }
Dianne Hackbornc2d9c8e2011-01-24 21:59:21 -08001354 rd.mForgotten = false;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001355 return rd.getIIntentReceiver();
1356 }
1357 }
1358
1359 public IIntentReceiver forgetReceiverDispatcher(Context context,
1360 BroadcastReceiver r) {
1361 synchronized (mReceivers) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001362 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = mReceivers.get(context);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001363 LoadedApk.ReceiverDispatcher rd = null;
1364 if (map != null) {
1365 rd = map.get(r);
1366 if (rd != null) {
1367 map.remove(r);
1368 if (map.size() == 0) {
1369 mReceivers.remove(context);
1370 }
1371 if (r.getDebugUnregister()) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001372 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> holder
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001373 = mUnregisteredReceivers.get(context);
1374 if (holder == null) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001375 holder = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001376 mUnregisteredReceivers.put(context, holder);
1377 }
1378 RuntimeException ex = new IllegalArgumentException(
1379 "Originally unregistered here:");
1380 ex.fillInStackTrace();
1381 rd.setUnregisterLocation(ex);
1382 holder.put(r, rd);
1383 }
Dianne Hackbornc2d9c8e2011-01-24 21:59:21 -08001384 rd.mForgotten = true;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001385 return rd.getIIntentReceiver();
1386 }
1387 }
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001388 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> holder
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001389 = mUnregisteredReceivers.get(context);
1390 if (holder != null) {
1391 rd = holder.get(r);
1392 if (rd != null) {
1393 RuntimeException ex = rd.getUnregisterLocation();
1394 throw new IllegalArgumentException(
1395 "Unregistering Receiver " + r
1396 + " that was already unregistered", ex);
1397 }
1398 }
1399 if (context == null) {
1400 throw new IllegalStateException("Unbinding Receiver " + r
1401 + " from Context that is no longer in use: " + context);
1402 } else {
1403 throw new IllegalArgumentException("Receiver not registered: " + r);
1404 }
1405
1406 }
1407 }
1408
1409 static final class ReceiverDispatcher {
1410
1411 final static class InnerReceiver extends IIntentReceiver.Stub {
1412 final WeakReference<LoadedApk.ReceiverDispatcher> mDispatcher;
1413 final LoadedApk.ReceiverDispatcher mStrongRef;
1414
1415 InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) {
1416 mDispatcher = new WeakReference<LoadedApk.ReceiverDispatcher>(rd);
1417 mStrongRef = strong ? rd : null;
1418 }
Jeff Sharkeyd136e512016-03-09 22:30:56 -07001419
1420 @Override
Dianne Hackborn20e80982012-08-31 19:00:44 -07001421 public void performReceive(Intent intent, int resultCode, String data,
1422 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
Dianne Hackborn26756162016-05-17 13:40:44 -07001423 final LoadedApk.ReceiverDispatcher rd;
1424 if (intent == null) {
1425 Log.wtf(TAG, "Null intent received");
1426 rd = null;
1427 } else {
1428 rd = mDispatcher.get();
1429 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001430 if (ActivityThread.DEBUG_BROADCAST) {
1431 int seq = intent.getIntExtra("seq", -1);
Dianne Hackborn26756162016-05-17 13:40:44 -07001432 Slog.i(ActivityThread.TAG, "Receiving broadcast " + intent.getAction()
1433 + " seq=" + seq + " to " + (rd != null ? rd.mReceiver : null));
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001434 }
1435 if (rd != null) {
1436 rd.performReceive(intent, resultCode, data, extras,
Dianne Hackborn20e80982012-08-31 19:00:44 -07001437 ordered, sticky, sendingUser);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001438 } else {
1439 // The activity manager dispatched a broadcast to a registered
1440 // receiver in this process, but before it could be delivered the
1441 // receiver was unregistered. Acknowledge the broadcast on its
1442 // behalf so that the system's broadcast sequence can continue.
1443 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1444 "Finishing broadcast to unregistered receiver");
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001445 IActivityManager mgr = ActivityManager.getService();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001446 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001447 if (extras != null) {
1448 extras.setAllowFds(false);
1449 }
riddle_hsu1f5ac4d2015-01-03 15:38:21 +08001450 mgr.finishReceiver(this, resultCode, data, extras, false, intent.getFlags());
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001451 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001452 throw e.rethrowFromSystemServer();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001453 }
1454 }
1455 }
1456 }
1457
1458 final IIntentReceiver.Stub mIIntentReceiver;
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001459 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001460 final BroadcastReceiver mReceiver;
Mathew Inwood8c854f82018-09-14 12:35:36 +01001461 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001462 final Context mContext;
1463 final Handler mActivityThread;
1464 final Instrumentation mInstrumentation;
1465 final boolean mRegistered;
1466 final IntentReceiverLeaked mLocation;
1467 RuntimeException mUnregisterLocation;
Dianne Hackbornc2d9c8e2011-01-24 21:59:21 -08001468 boolean mForgotten;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001469
Makoto Onuki08408b92017-05-09 13:48:53 -07001470 final class Args extends BroadcastReceiver.PendingResult {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001471 private Intent mCurIntent;
Dianne Hackborne829fef2010-10-26 17:44:01 -07001472 private final boolean mOrdered;
Dianne Hackborn17c77532016-06-22 16:49:14 -07001473 private boolean mDispatched;
Makoto Onuki350ed672019-04-30 14:34:08 -07001474 private boolean mRunCalled;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001475
Dianne Hackborne829fef2010-10-26 17:44:01 -07001476 public Args(Intent intent, int resultCode, String resultData, Bundle resultExtras,
Dianne Hackborn20e80982012-08-31 19:00:44 -07001477 boolean ordered, boolean sticky, int sendingUser) {
Dianne Hackborne829fef2010-10-26 17:44:01 -07001478 super(resultCode, resultData, resultExtras,
riddle_hsu1f5ac4d2015-01-03 15:38:21 +08001479 mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED, ordered,
1480 sticky, mIIntentReceiver.asBinder(), sendingUser, intent.getFlags());
Dianne Hackborne829fef2010-10-26 17:44:01 -07001481 mCurIntent = intent;
1482 mOrdered = ordered;
1483 }
Dianne Hackborn17c77532016-06-22 16:49:14 -07001484
Makoto Onuki08408b92017-05-09 13:48:53 -07001485 public final Runnable getRunnable() {
1486 return () -> {
1487 final BroadcastReceiver receiver = mReceiver;
1488 final boolean ordered = mOrdered;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001489
Makoto Onuki08408b92017-05-09 13:48:53 -07001490 if (ActivityThread.DEBUG_BROADCAST) {
1491 int seq = mCurIntent.getIntExtra("seq", -1);
1492 Slog.i(ActivityThread.TAG, "Dispatching broadcast " + mCurIntent.getAction()
1493 + " seq=" + seq + " to " + mReceiver);
1494 Slog.i(ActivityThread.TAG, " mRegistered=" + mRegistered
1495 + " mOrderedHint=" + ordered);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001496 }
Makoto Onuki08408b92017-05-09 13:48:53 -07001497
1498 final IActivityManager mgr = ActivityManager.getService();
1499 final Intent intent = mCurIntent;
1500 if (intent == null) {
1501 Log.wtf(TAG, "Null intent being dispatched, mDispatched=" + mDispatched
Makoto Onuki350ed672019-04-30 14:34:08 -07001502 + (mRunCalled ? ", run() has already been called" : ""));
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001503 }
Makoto Onuki08408b92017-05-09 13:48:53 -07001504
1505 mCurIntent = null;
1506 mDispatched = true;
Makoto Onuki350ed672019-04-30 14:34:08 -07001507 mRunCalled = true;
Makoto Onuki08408b92017-05-09 13:48:53 -07001508 if (receiver == null || intent == null || mForgotten) {
1509 if (mRegistered && ordered) {
1510 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1511 "Finishing null broadcast to " + mReceiver);
1512 sendFinished(mgr);
1513 }
1514 return;
1515 }
1516
1517 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveReg");
1518 try {
1519 ClassLoader cl = mReceiver.getClass().getClassLoader();
1520 intent.setExtrasClassLoader(cl);
1521 intent.prepareToEnterProcess();
1522 setExtrasClassLoader(cl);
1523 receiver.setPendingResult(this);
1524 receiver.onReceive(mContext, intent);
1525 } catch (Exception e) {
1526 if (mRegistered && ordered) {
1527 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1528 "Finishing failed broadcast to " + mReceiver);
1529 sendFinished(mgr);
1530 }
1531 if (mInstrumentation == null ||
1532 !mInstrumentation.onException(mReceiver, e)) {
1533 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1534 throw new RuntimeException(
1535 "Error receiving broadcast " + intent
1536 + " in " + mReceiver, e);
1537 }
1538 }
1539
1540 if (receiver.getPendingResult() != null) {
1541 finish();
1542 }
1543 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1544 };
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001545 }
1546 }
1547
1548 ReceiverDispatcher(BroadcastReceiver receiver, Context context,
1549 Handler activityThread, Instrumentation instrumentation,
1550 boolean registered) {
1551 if (activityThread == null) {
1552 throw new NullPointerException("Handler must not be null");
1553 }
1554
1555 mIIntentReceiver = new InnerReceiver(this, !registered);
1556 mReceiver = receiver;
1557 mContext = context;
1558 mActivityThread = activityThread;
1559 mInstrumentation = instrumentation;
1560 mRegistered = registered;
1561 mLocation = new IntentReceiverLeaked(null);
1562 mLocation.fillInStackTrace();
1563 }
1564
1565 void validate(Context context, Handler activityThread) {
1566 if (mContext != context) {
1567 throw new IllegalStateException(
1568 "Receiver " + mReceiver +
1569 " registered with differing Context (was " +
1570 mContext + " now " + context + ")");
1571 }
1572 if (mActivityThread != activityThread) {
1573 throw new IllegalStateException(
1574 "Receiver " + mReceiver +
1575 " registered with differing handler (was " +
1576 mActivityThread + " now " + activityThread + ")");
1577 }
1578 }
1579
1580 IntentReceiverLeaked getLocation() {
1581 return mLocation;
1582 }
1583
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001584 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001585 BroadcastReceiver getIntentReceiver() {
1586 return mReceiver;
1587 }
1588
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001589 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001590 IIntentReceiver getIIntentReceiver() {
1591 return mIIntentReceiver;
1592 }
1593
1594 void setUnregisterLocation(RuntimeException ex) {
1595 mUnregisterLocation = ex;
1596 }
1597
1598 RuntimeException getUnregisterLocation() {
1599 return mUnregisterLocation;
1600 }
1601
Dianne Hackborn20e80982012-08-31 19:00:44 -07001602 public void performReceive(Intent intent, int resultCode, String data,
1603 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
Dianne Hackborn41bfaf82016-06-08 16:33:29 -07001604 final Args args = new Args(intent, resultCode, data, extras, ordered,
Dianne Hackborn20e80982012-08-31 19:00:44 -07001605 sticky, sendingUser);
Dianne Hackborn41bfaf82016-06-08 16:33:29 -07001606 if (intent == null) {
1607 Log.wtf(TAG, "Null intent received");
1608 } else {
1609 if (ActivityThread.DEBUG_BROADCAST) {
1610 int seq = intent.getIntExtra("seq", -1);
1611 Slog.i(ActivityThread.TAG, "Enqueueing broadcast " + intent.getAction()
1612 + " seq=" + seq + " to " + mReceiver);
1613 }
1614 }
Makoto Onuki08408b92017-05-09 13:48:53 -07001615 if (intent == null || !mActivityThread.post(args.getRunnable())) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001616 if (mRegistered && ordered) {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001617 IActivityManager mgr = ActivityManager.getService();
Dianne Hackborne829fef2010-10-26 17:44:01 -07001618 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1619 "Finishing sync broadcast to " + mReceiver);
1620 args.sendFinished(mgr);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001621 }
1622 }
1623 }
1624
1625 }
1626
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001627 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001628 public final IServiceConnection getServiceDispatcher(ServiceConnection c,
1629 Context context, Handler handler, int flags) {
Bo Liu58a57662019-03-06 20:21:45 +00001630 return getServiceDispatcherCommon(c, context, handler, null, flags);
1631 }
1632
1633 public final IServiceConnection getServiceDispatcher(ServiceConnection c,
1634 Context context, Executor executor, int flags) {
1635 return getServiceDispatcherCommon(c, context, null, executor, flags);
1636 }
1637
1638 private IServiceConnection getServiceDispatcherCommon(ServiceConnection c,
1639 Context context, Handler handler, Executor executor, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001640 synchronized (mServices) {
1641 LoadedApk.ServiceDispatcher sd = null;
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001642 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001643 if (map != null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001644 if (DEBUG) Slog.d(TAG, "Returning existing dispatcher " + sd + " for conn " + c);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001645 sd = map.get(c);
1646 }
1647 if (sd == null) {
Bo Liu58a57662019-03-06 20:21:45 +00001648 if (executor != null) {
1649 sd = new ServiceDispatcher(c, context, executor, flags);
1650 } else {
1651 sd = new ServiceDispatcher(c, context, handler, flags);
1652 }
Dianne Hackborn94846032017-03-31 17:55:23 -07001653 if (DEBUG) Slog.d(TAG, "Creating new dispatcher " + sd + " for conn " + c);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001654 if (map == null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001655 map = new ArrayMap<>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001656 mServices.put(context, map);
1657 }
1658 map.put(c, sd);
1659 } else {
Bo Liu58a57662019-03-06 20:21:45 +00001660 sd.validate(context, handler, executor);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001661 }
1662 return sd.getIServiceConnection();
1663 }
1664 }
1665
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08001666 @UnsupportedAppUsage
1667 public IServiceConnection lookupServiceDispatcher(ServiceConnection c,
1668 Context context) {
1669 synchronized (mServices) {
1670 LoadedApk.ServiceDispatcher sd = null;
1671 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
1672 if (map != null) {
1673 sd = map.get(c);
1674 }
1675 return sd != null ? sd.getIServiceConnection() : null;
1676 }
1677 }
1678
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001679 public final IServiceConnection forgetServiceDispatcher(Context context,
1680 ServiceConnection c) {
1681 synchronized (mServices) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001682 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001683 = mServices.get(context);
1684 LoadedApk.ServiceDispatcher sd = null;
1685 if (map != null) {
1686 sd = map.get(c);
1687 if (sd != null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001688 if (DEBUG) Slog.d(TAG, "Removing dispatcher " + sd + " for conn " + c);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001689 map.remove(c);
1690 sd.doForget();
1691 if (map.size() == 0) {
1692 mServices.remove(context);
1693 }
1694 if ((sd.getFlags()&Context.BIND_DEBUG_UNBIND) != 0) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001695 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> holder
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001696 = mUnboundServices.get(context);
1697 if (holder == null) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001698 holder = new ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001699 mUnboundServices.put(context, holder);
1700 }
1701 RuntimeException ex = new IllegalArgumentException(
1702 "Originally unbound here:");
1703 ex.fillInStackTrace();
1704 sd.setUnbindLocation(ex);
1705 holder.put(c, sd);
1706 }
1707 return sd.getIServiceConnection();
1708 }
1709 }
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001710 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> holder
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001711 = mUnboundServices.get(context);
1712 if (holder != null) {
1713 sd = holder.get(c);
1714 if (sd != null) {
1715 RuntimeException ex = sd.getUnbindLocation();
1716 throw new IllegalArgumentException(
1717 "Unbinding Service " + c
1718 + " that was already unbound", ex);
1719 }
1720 }
1721 if (context == null) {
1722 throw new IllegalStateException("Unbinding Service " + c
1723 + " from Context that is no longer in use: " + context);
1724 } else {
1725 throw new IllegalArgumentException("Service not registered: " + c);
1726 }
1727 }
1728 }
1729
1730 static final class ServiceDispatcher {
1731 private final ServiceDispatcher.InnerConnection mIServiceConnection;
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001732 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001733 private final ServiceConnection mConnection;
Mathew Inwood8c854f82018-09-14 12:35:36 +01001734 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001735 private final Context mContext;
1736 private final Handler mActivityThread;
Bo Liu58a57662019-03-06 20:21:45 +00001737 private final Executor mActivityExecutor;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001738 private final ServiceConnectionLeaked mLocation;
1739 private final int mFlags;
1740
1741 private RuntimeException mUnbindLocation;
1742
Dianne Hackborn5a6ef732011-11-11 12:31:52 -08001743 private boolean mForgotten;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001744
1745 private static class ConnectionInfo {
1746 IBinder binder;
1747 IBinder.DeathRecipient deathMonitor;
1748 }
1749
1750 private static class InnerConnection extends IServiceConnection.Stub {
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001751 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001752 final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;
1753
1754 InnerConnection(LoadedApk.ServiceDispatcher sd) {
1755 mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
1756 }
1757
Dianne Hackborn94846032017-03-31 17:55:23 -07001758 public void connected(ComponentName name, IBinder service, boolean dead)
1759 throws RemoteException {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001760 LoadedApk.ServiceDispatcher sd = mDispatcher.get();
1761 if (sd != null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001762 sd.connected(name, service, dead);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001763 }
1764 }
1765 }
1766
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001767 private final ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo> mActiveConnections
1768 = new ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001769
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001770 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001771 ServiceDispatcher(ServiceConnection conn,
1772 Context context, Handler activityThread, int flags) {
1773 mIServiceConnection = new InnerConnection(this);
1774 mConnection = conn;
1775 mContext = context;
1776 mActivityThread = activityThread;
Bo Liu58a57662019-03-06 20:21:45 +00001777 mActivityExecutor = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001778 mLocation = new ServiceConnectionLeaked(null);
1779 mLocation.fillInStackTrace();
1780 mFlags = flags;
1781 }
1782
Bo Liu58a57662019-03-06 20:21:45 +00001783 ServiceDispatcher(ServiceConnection conn,
1784 Context context, Executor activityExecutor, int flags) {
1785 mIServiceConnection = new InnerConnection(this);
1786 mConnection = conn;
1787 mContext = context;
1788 mActivityThread = null;
1789 mActivityExecutor = activityExecutor;
1790 mLocation = new ServiceConnectionLeaked(null);
1791 mLocation.fillInStackTrace();
1792 mFlags = flags;
1793 }
1794
1795 void validate(Context context, Handler activityThread, Executor activityExecutor) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001796 if (mContext != context) {
1797 throw new RuntimeException(
1798 "ServiceConnection " + mConnection +
1799 " registered with differing Context (was " +
1800 mContext + " now " + context + ")");
1801 }
1802 if (mActivityThread != activityThread) {
1803 throw new RuntimeException(
1804 "ServiceConnection " + mConnection +
1805 " registered with differing handler (was " +
1806 mActivityThread + " now " + activityThread + ")");
1807 }
Bo Liu58a57662019-03-06 20:21:45 +00001808 if (mActivityExecutor != activityExecutor) {
1809 throw new RuntimeException(
1810 "ServiceConnection " + mConnection +
1811 " registered with differing executor (was " +
1812 mActivityExecutor + " now " + activityExecutor + ")");
1813 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001814 }
1815
1816 void doForget() {
1817 synchronized(this) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001818 for (int i=0; i<mActiveConnections.size(); i++) {
1819 ServiceDispatcher.ConnectionInfo ci = mActiveConnections.valueAt(i);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001820 ci.binder.unlinkToDeath(ci.deathMonitor, 0);
1821 }
1822 mActiveConnections.clear();
Dianne Hackborn5a6ef732011-11-11 12:31:52 -08001823 mForgotten = true;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001824 }
1825 }
1826
1827 ServiceConnectionLeaked getLocation() {
1828 return mLocation;
1829 }
1830
1831 ServiceConnection getServiceConnection() {
1832 return mConnection;
1833 }
1834
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001835 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001836 IServiceConnection getIServiceConnection() {
1837 return mIServiceConnection;
1838 }
1839
1840 int getFlags() {
1841 return mFlags;
1842 }
1843
1844 void setUnbindLocation(RuntimeException ex) {
1845 mUnbindLocation = ex;
1846 }
1847
1848 RuntimeException getUnbindLocation() {
1849 return mUnbindLocation;
1850 }
1851
Dianne Hackborn94846032017-03-31 17:55:23 -07001852 public void connected(ComponentName name, IBinder service, boolean dead) {
Bo Liu58a57662019-03-06 20:21:45 +00001853 if (mActivityExecutor != null) {
1854 mActivityExecutor.execute(new RunConnection(name, service, 0, dead));
1855 } else if (mActivityThread != null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001856 mActivityThread.post(new RunConnection(name, service, 0, dead));
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001857 } else {
Dianne Hackborn94846032017-03-31 17:55:23 -07001858 doConnected(name, service, dead);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001859 }
1860 }
1861
1862 public void death(ComponentName name, IBinder service) {
Bo Liu58a57662019-03-06 20:21:45 +00001863 if (mActivityExecutor != null) {
1864 mActivityExecutor.execute(new RunConnection(name, service, 1, false));
1865 } else if (mActivityThread != null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001866 mActivityThread.post(new RunConnection(name, service, 1, false));
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001867 } else {
1868 doDeath(name, service);
1869 }
1870 }
1871
Dianne Hackborn94846032017-03-31 17:55:23 -07001872 public void doConnected(ComponentName name, IBinder service, boolean dead) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001873 ServiceDispatcher.ConnectionInfo old;
1874 ServiceDispatcher.ConnectionInfo info;
1875
1876 synchronized (this) {
Dianne Hackborn5a6ef732011-11-11 12:31:52 -08001877 if (mForgotten) {
1878 // We unbound before receiving the connection; ignore
1879 // any connection received.
1880 return;
1881 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001882 old = mActiveConnections.get(name);
1883 if (old != null && old.binder == service) {
1884 // Huh, already have this one. Oh well!
1885 return;
1886 }
1887
1888 if (service != null) {
1889 // A new service is being connected... set it all up.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001890 info = new ConnectionInfo();
1891 info.binder = service;
1892 info.deathMonitor = new DeathMonitor(name, service);
1893 try {
1894 service.linkToDeath(info.deathMonitor, 0);
1895 mActiveConnections.put(name, info);
1896 } catch (RemoteException e) {
1897 // This service was dead before we got it... just
1898 // don't do anything with it.
1899 mActiveConnections.remove(name);
1900 return;
1901 }
1902
1903 } else {
1904 // The named service is being disconnected... clean up.
1905 mActiveConnections.remove(name);
1906 }
1907
1908 if (old != null) {
1909 old.binder.unlinkToDeath(old.deathMonitor, 0);
1910 }
1911 }
1912
Adrian Roosa9b43182016-07-21 13:20:38 -07001913 // If there was an old service, it is now disconnected.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001914 if (old != null) {
1915 mConnection.onServiceDisconnected(name);
1916 }
Dianne Hackborn94846032017-03-31 17:55:23 -07001917 if (dead) {
Dianne Hackbornac265342017-04-19 14:53:18 -07001918 mConnection.onBindingDied(name);
Dianne Hackborn94846032017-03-31 17:55:23 -07001919 }
Christopher Tate5d73b6d2017-10-06 16:15:34 -07001920 // If there is a new viable service, it is now connected.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001921 if (service != null) {
1922 mConnection.onServiceConnected(name, service);
Christopher Tate5d73b6d2017-10-06 16:15:34 -07001923 } else {
1924 // The binding machinery worked, but the remote returned null from onBind().
1925 mConnection.onNullBinding(name);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001926 }
1927 }
1928
1929 public void doDeath(ComponentName name, IBinder service) {
Adrian Roosa9b43182016-07-21 13:20:38 -07001930 synchronized (this) {
1931 ConnectionInfo old = mActiveConnections.get(name);
1932 if (old == null || old.binder != service) {
1933 // Death for someone different than who we last
1934 // reported... just ignore it.
1935 return;
1936 }
1937 mActiveConnections.remove(name);
1938 old.binder.unlinkToDeath(old.deathMonitor, 0);
1939 }
1940
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001941 mConnection.onServiceDisconnected(name);
1942 }
1943
1944 private final class RunConnection implements Runnable {
Dianne Hackborn94846032017-03-31 17:55:23 -07001945 RunConnection(ComponentName name, IBinder service, int command, boolean dead) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001946 mName = name;
1947 mService = service;
1948 mCommand = command;
Dianne Hackborn94846032017-03-31 17:55:23 -07001949 mDead = dead;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001950 }
1951
1952 public void run() {
1953 if (mCommand == 0) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001954 doConnected(mName, mService, mDead);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001955 } else if (mCommand == 1) {
1956 doDeath(mName, mService);
1957 }
1958 }
1959
1960 final ComponentName mName;
1961 final IBinder mService;
1962 final int mCommand;
Dianne Hackborn94846032017-03-31 17:55:23 -07001963 final boolean mDead;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001964 }
1965
1966 private final class DeathMonitor implements IBinder.DeathRecipient
1967 {
1968 DeathMonitor(ComponentName name, IBinder service) {
1969 mName = name;
1970 mService = service;
1971 }
1972
1973 public void binderDied() {
1974 death(mName, mService);
1975 }
1976
1977 final ComponentName mName;
1978 final IBinder mService;
1979 }
1980 }
1981}