blob: 5c4c0052cfbbd1d678297a2a527e5955a1f77317 [file] [log] [blame]
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.app;
18
Adam Lesinskid33ef562017-01-19 14:49:59 -080019import android.annotation.NonNull;
20import android.annotation.Nullable;
Mathew Inwood61e8ae62018-08-14 14:17:44 +010021import android.annotation.UnsupportedAppUsage;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070022import android.content.BroadcastReceiver;
23import android.content.ComponentName;
24import android.content.Context;
25import android.content.IIntentReceiver;
26import android.content.Intent;
27import android.content.ServiceConnection;
28import android.content.pm.ApplicationInfo;
29import android.content.pm.IPackageManager;
30import android.content.pm.PackageManager;
Adam Lesinski1665d0f2017-03-10 14:46:57 -080031import android.content.pm.PackageManager.NameNotFoundException;
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +000032import android.content.pm.SharedLibraryInfo;
Calin Juravle6ae39fc2018-01-19 20:32:47 -080033import android.content.pm.dex.ArtManager;
Adam Lesinski1665d0f2017-03-10 14:46:57 -080034import android.content.pm.split.SplitDependencyLoader;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070035import android.content.res.AssetManager;
36import android.content.res.CompatibilityInfo;
37import android.content.res.Resources;
Adam Lesinski4e862812016-11-21 16:02:24 -080038import android.os.Build;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070039import android.os.Bundle;
Jeff Sharkey15447792015-11-05 16:18:51 -080040import android.os.FileUtils;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070041import android.os.Handler;
42import android.os.IBinder;
43import android.os.Process;
44import android.os.RemoteException;
Brad Fitzpatrick624d50f2010-11-09 14:25:12 -080045import android.os.StrictMode;
Jeff Sharkey8a372a02016-03-16 16:25:45 -060046import android.os.SystemProperties;
Dianne Hackborn1ded0b12012-04-26 14:14:50 -070047import android.os.Trace;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070048import android.os.UserHandle;
Jeff Sharkey8a372a02016-03-16 16:25:45 -060049import android.text.TextUtils;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070050import android.util.AndroidRuntimeException;
Jeff Sharkey8a372a02016-03-16 16:25:45 -060051import android.util.ArrayMap;
Adam Lesinski2cb761e2014-08-15 13:59:02 -070052import android.util.Log;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070053import android.util.Slog;
Adam Lesinskide898ff2014-01-29 18:20:45 -080054import android.util.SparseArray;
Jeff Browna492c3a2012-08-23 19:48:44 -070055import android.view.Display;
Jeff Sharkey8a372a02016-03-16 16:25:45 -060056import android.view.DisplayAdjustments;
Calin Juravle6ae39fc2018-01-19 20:32:47 -080057
Adam Lesinski4e862812016-11-21 16:02:24 -080058import com.android.internal.util.ArrayUtils;
Calin Juravle6ae39fc2018-01-19 20:32:47 -080059
David Brazdil991ff902018-12-03 10:59:29 +000060import dalvik.system.BaseDexClassLoader;
Narayan Kamath7dba6eb2014-07-16 08:53:30 +010061import dalvik.system.VMRuntime;
Calin Juravle6ae39fc2018-01-19 20:32:47 -080062
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070063import java.io.File;
64import java.io.IOException;
65import java.io.InputStream;
66import java.lang.ref.WeakReference;
Adam Lesinski1e4663852014-08-15 14:47:28 -070067import java.lang.reflect.InvocationTargetException;
68import java.lang.reflect.Method;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070069import java.net.URL;
Jiyong Park29d9eba2018-05-04 12:44:38 +090070import java.nio.file.Paths;
Jeff Sharkey8a4c9722014-06-16 13:48:42 -070071import java.util.ArrayList;
Adam Lesinski4e862812016-11-21 16:02:24 -080072import java.util.Arrays;
Jeff Sharkey8a4c9722014-06-16 13:48:42 -070073import java.util.Collections;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070074import java.util.Enumeration;
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +000075import java.util.LinkedHashSet;
Jeff Sharkey8a372a02016-03-16 16:25:45 -060076import java.util.List;
Narayan Kamath20531682014-07-14 13:18:43 +010077import java.util.Objects;
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +000078import java.util.Set;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070079
80final class IntentReceiverLeaked extends AndroidRuntimeException {
Mathew Inwood61e8ae62018-08-14 14:17:44 +010081 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070082 public IntentReceiverLeaked(String msg) {
83 super(msg);
84 }
85}
86
87final class ServiceConnectionLeaked extends AndroidRuntimeException {
Mathew Inwood61e8ae62018-08-14 14:17:44 +010088 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070089 public ServiceConnectionLeaked(String msg) {
90 super(msg);
91 }
92}
93
94/**
95 * Local state maintained about a currently loaded .apk.
96 * @hide
97 */
Dianne Hackborn5fd21692011-06-07 14:09:47 -070098public final class LoadedApk {
Dianne Hackborn94846032017-03-31 17:55:23 -070099 static final String TAG = "LoadedApk";
100 static final boolean DEBUG = false;
Patrick Baumann1bea2372018-03-13 14:26:58 -0700101 private static final String PROPERTY_NAME_APPEND_NATIVE = "pi.append_native_lib_paths";
Amith Yamasani742a6712011-05-04 14:49:28 -0700102
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100103 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700104 private final ActivityThread mActivityThread;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100105 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700106 final String mPackageName;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100107 @UnsupportedAppUsage
Todd Kennedy39bfee52016-02-24 10:28:21 -0800108 private ApplicationInfo mApplicationInfo;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100109 @UnsupportedAppUsage
Todd Kennedy39bfee52016-02-24 10:28:21 -0800110 private String mAppDir;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100111 @UnsupportedAppUsage
Todd Kennedy39bfee52016-02-24 10:28:21 -0800112 private String mResDir;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800113 private String[] mOverlayDirs;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100114 @UnsupportedAppUsage
Todd Kennedy39bfee52016-02-24 10:28:21 -0800115 private String mDataDir;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100116 @UnsupportedAppUsage
Todd Kennedy39bfee52016-02-24 10:28:21 -0800117 private String mLibDir;
Mathew Inwood8c854f82018-09-14 12:35:36 +0100118 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Todd Kennedy39bfee52016-02-24 10:28:21 -0800119 private File mDataDirFile;
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600120 private File mDeviceProtectedDataDirFile;
121 private File mCredentialProtectedDataDirFile;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100122 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700123 private final ClassLoader mBaseClassLoader;
David Brazdilfd6dcc22018-10-25 14:07:51 +0100124 private ClassLoader mDefaultClassLoader;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700125 private final boolean mSecurityViolation;
126 private final boolean mIncludeCode;
Dianne Hackbornfee756f2014-07-16 17:31:10 -0700127 private final boolean mRegisterPackage;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100128 @UnsupportedAppUsage
Craig Mautner48d0d182013-06-11 07:53:06 -0700129 private final DisplayAdjustments mDisplayAdjustments = new DisplayAdjustments();
Todd Kennedy39bfee52016-02-24 10:28:21 -0800130 /** WARNING: This may change. Don't hold external references to it. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100131 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700132 Resources mResources;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100133 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700134 private ClassLoader mClassLoader;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100135 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700136 private Application mApplication;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700137
Adam Lesinski4e862812016-11-21 16:02:24 -0800138 private String[] mSplitNames;
139 private String[] mSplitAppDirs;
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100140 @UnsupportedAppUsage
Adam Lesinski4e862812016-11-21 16:02:24 -0800141 private String[] mSplitResDirs;
Narayan Kamathf9419f02017-06-15 11:35:38 +0100142 private String[] mSplitClassLoaderNames;
Adam Lesinski4e862812016-11-21 16:02:24 -0800143
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100144 @UnsupportedAppUsage
Dianne Hackbornadd005c2013-07-17 18:43:12 -0700145 private final ArrayMap<Context, ArrayMap<BroadcastReceiver, ReceiverDispatcher>> mReceivers
Adam Lesinski4e862812016-11-21 16:02:24 -0800146 = new ArrayMap<>();
Dianne Hackbornadd005c2013-07-17 18:43:12 -0700147 private final ArrayMap<Context, ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>> mUnregisteredReceivers
Adam Lesinski4e862812016-11-21 16:02:24 -0800148 = new ArrayMap<>();
Mathew Inwood8c854f82018-09-14 12:35:36 +0100149 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Dianne Hackbornadd005c2013-07-17 18:43:12 -0700150 private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mServices
Adam Lesinski4e862812016-11-21 16:02:24 -0800151 = new ArrayMap<>();
Dianne Hackbornadd005c2013-07-17 18:43:12 -0700152 private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mUnboundServices
Adam Lesinski4e862812016-11-21 16:02:24 -0800153 = new ArrayMap<>();
Jason Monka80bfb52017-11-16 17:15:37 -0500154 private AppComponentFactory mAppComponentFactory;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700155
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700156 Application getApplication() {
157 return mApplication;
158 }
159
Dianne Hackborn2f0b1752011-05-31 17:59:49 -0700160 /**
161 * Create information about a new .apk
162 *
163 * NOTE: This constructor is called with ActivityThread's lock held,
164 * so MUST NOT call back out to the activity manager.
165 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700166 public LoadedApk(ActivityThread activityThread, ApplicationInfo aInfo,
Jeff Browndefd4a62014-03-10 21:24:37 -0700167 CompatibilityInfo compatInfo, ClassLoader baseLoader,
Dianne Hackbornfee756f2014-07-16 17:31:10 -0700168 boolean securityViolation, boolean includeCode, boolean registerPackage) {
Narayan Kamath7dba6eb2014-07-16 08:53:30 +0100169
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700170 mActivityThread = activityThread;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800171 setApplicationInfo(aInfo);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700172 mPackageName = aInfo.packageName;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700173 mBaseClassLoader = baseLoader;
174 mSecurityViolation = securityViolation;
175 mIncludeCode = includeCode;
Dianne Hackbornfee756f2014-07-16 17:31:10 -0700176 mRegisterPackage = registerPackage;
Craig Mautner48d0d182013-06-11 07:53:06 -0700177 mDisplayAdjustments.setCompatibilityInfo(compatInfo);
Jason Monka80bfb52017-11-16 17:15:37 -0500178 mAppComponentFactory = createAppFactory(mApplicationInfo, mBaseClassLoader);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700179 }
180
Narayan Kamath7dba6eb2014-07-16 08:53:30 +0100181 private static ApplicationInfo adjustNativeLibraryPaths(ApplicationInfo info) {
182 // If we're dealing with a multi-arch application that has both
183 // 32 and 64 bit shared libraries, we might need to choose the secondary
184 // depending on what the current runtime's instruction set is.
185 if (info.primaryCpuAbi != null && info.secondaryCpuAbi != null) {
186 final String runtimeIsa = VMRuntime.getRuntime().vmInstructionSet();
jgu214741cd92014-12-17 17:23:29 -0500187
188 // Get the instruction set that the libraries of secondary Abi is supported.
189 // In presence of a native bridge this might be different than the one secondary Abi used.
190 String secondaryIsa = VMRuntime.getInstructionSet(info.secondaryCpuAbi);
191 final String secondaryDexCodeIsa = SystemProperties.get("ro.dalvik.vm.isa." + secondaryIsa);
192 secondaryIsa = secondaryDexCodeIsa.isEmpty() ? secondaryIsa : secondaryDexCodeIsa;
Narayan Kamath7dba6eb2014-07-16 08:53:30 +0100193
194 // If the runtimeIsa is the same as the primary isa, then we do nothing.
195 // Everything will be set up correctly because info.nativeLibraryDir will
196 // correspond to the right ISA.
197 if (runtimeIsa.equals(secondaryIsa)) {
198 final ApplicationInfo modified = new ApplicationInfo(info);
199 modified.nativeLibraryDir = modified.secondaryNativeLibraryDir;
Dmitriy Ivanove56b3f62015-06-05 22:00:13 -0700200 modified.primaryCpuAbi = modified.secondaryCpuAbi;
Narayan Kamath7dba6eb2014-07-16 08:53:30 +0100201 return modified;
202 }
203 }
204
205 return info;
206 }
207
Jeff Browndefd4a62014-03-10 21:24:37 -0700208 /**
209 * Create information about the system package.
210 * Must call {@link #installSystemApplicationInfo} later.
211 */
212 LoadedApk(ActivityThread activityThread) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700213 mActivityThread = activityThread;
Jeff Browndefd4a62014-03-10 21:24:37 -0700214 mApplicationInfo = new ApplicationInfo();
215 mApplicationInfo.packageName = "android";
216 mPackageName = "android";
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700217 mAppDir = null;
218 mResDir = null;
Jeff Sharkey8a4c9722014-06-16 13:48:42 -0700219 mSplitAppDirs = null;
220 mSplitResDirs = null;
Narayan Kamathf9419f02017-06-15 11:35:38 +0100221 mSplitClassLoaderNames = null;
MÃ¥rten Kongstad48d22322014-01-31 14:43:27 +0100222 mOverlayDirs = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700223 mDataDir = null;
224 mDataDirFile = null;
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600225 mDeviceProtectedDataDirFile = null;
226 mCredentialProtectedDataDirFile = null;
Kenny Root85387d72010-08-26 10:13:11 -0700227 mLibDir = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700228 mBaseClassLoader = null;
229 mSecurityViolation = false;
230 mIncludeCode = true;
Dianne Hackbornfee756f2014-07-16 17:31:10 -0700231 mRegisterPackage = false;
Jeff Browndefd4a62014-03-10 21:24:37 -0700232 mResources = Resources.getSystem();
David Brazdilfd6dcc22018-10-25 14:07:51 +0100233 mDefaultClassLoader = ClassLoader.getSystemClassLoader();
234 mAppComponentFactory = createAppFactory(mApplicationInfo, mDefaultClassLoader);
235 mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader);
Jeff Browndefd4a62014-03-10 21:24:37 -0700236 }
237
238 /**
239 * Sets application info about the system package.
240 */
Narayan Kamath29564cd2014-08-07 10:57:40 +0100241 void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
Jeff Browndefd4a62014-03-10 21:24:37 -0700242 assert info.packageName.equals("android");
243 mApplicationInfo = info;
David Brazdilfd6dcc22018-10-25 14:07:51 +0100244 mDefaultClassLoader = classLoader;
245 mAppComponentFactory = createAppFactory(info, mDefaultClassLoader);
246 mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader);
Jason Monka80bfb52017-11-16 17:15:37 -0500247 }
248
249 private AppComponentFactory createAppFactory(ApplicationInfo appInfo, ClassLoader cl) {
Jason Monk6ee51bb2018-03-02 11:20:31 -0500250 if (appInfo.appComponentFactory != null && cl != null) {
Jason Monka80bfb52017-11-16 17:15:37 -0500251 try {
David Brazdilfd6dcc22018-10-25 14:07:51 +0100252 AppComponentFactory factory = (AppComponentFactory) cl.loadClass(
253 appInfo.appComponentFactory).newInstance();
254 // Pass a copy of ApplicationInfo to the factory. Copying protects the framework
255 // from apps which would override the factory and change ApplicationInfo contents.
256 // ApplicationInfo is used to set up the default class loader.
257 factory.setApplicationInfo(new ApplicationInfo(appInfo));
258 return factory;
Jason Monka80bfb52017-11-16 17:15:37 -0500259 } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
260 Slog.e(TAG, "Unable to instantiate appComponentFactory", e);
261 }
262 }
263 return AppComponentFactory.DEFAULT;
264 }
265
266 public AppComponentFactory getAppFactory() {
267 return mAppComponentFactory;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700268 }
269
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100270 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700271 public String getPackageName() {
272 return mPackageName;
273 }
274
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100275 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700276 public ApplicationInfo getApplicationInfo() {
277 return mApplicationInfo;
278 }
279
Jeff Sharkey369f5092016-02-29 11:16:21 -0700280 public int getTargetSdkVersion() {
281 return mApplicationInfo.targetSdkVersion;
282 }
283
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700284 public boolean isSecurityViolation() {
285 return mSecurityViolation;
286 }
287
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100288 @UnsupportedAppUsage
Craig Mautner48d0d182013-06-11 07:53:06 -0700289 public CompatibilityInfo getCompatibilityInfo() {
290 return mDisplayAdjustments.getCompatibilityInfo();
291 }
292
293 public void setCompatibilityInfo(CompatibilityInfo compatInfo) {
294 mDisplayAdjustments.setCompatibilityInfo(compatInfo);
295 }
296
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700297 /**
298 * Gets the array of shared libraries that are listed as
299 * used by the given package.
300 *
301 * @param packageName the name of the package (note: not its
302 * file name)
303 * @return null-ok; the array of shared libraries, each one
304 * a fully-qualified path
305 */
306 private static String[] getLibrariesFor(String packageName) {
307 ApplicationInfo ai = null;
308 try {
309 ai = ActivityThread.getPackageManager().getApplicationInfo(packageName,
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700310 PackageManager.GET_SHARED_LIBRARY_FILES, UserHandle.myUserId());
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700311 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700312 throw e.rethrowFromSystemServer();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700313 }
314
315 if (ai == null) {
316 return null;
317 }
318
319 return ai.sharedLibraryFiles;
320 }
321
Adam Lesinskid33ef562017-01-19 14:49:59 -0800322 /**
323 * Update the ApplicationInfo for an app. If oldPaths is null, all the paths are considered
324 * new.
325 * @param aInfo The new ApplicationInfo to use for this LoadedApk
326 * @param oldPaths The code paths for the old ApplicationInfo object. null means no paths can
327 * be reused.
328 */
329 public void updateApplicationInfo(@NonNull ApplicationInfo aInfo,
330 @Nullable List<String> oldPaths) {
Todd Kennedy39bfee52016-02-24 10:28:21 -0800331 setApplicationInfo(aInfo);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700332
Todd Kennedy39bfee52016-02-24 10:28:21 -0800333 final List<String> newPaths = new ArrayList<>();
Dimitry Ivanov638d8102017-02-22 15:39:42 -0800334 makePaths(mActivityThread, aInfo, newPaths);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800335 final List<String> addedPaths = new ArrayList<>(newPaths.size());
336
337 if (oldPaths != null) {
338 for (String path : newPaths) {
339 final String apkName = path.substring(path.lastIndexOf(File.separator));
340 boolean match = false;
341 for (String oldPath : oldPaths) {
Adam Lesinskia5ca6242017-03-01 15:45:12 -0800342 final String oldApkName = oldPath.substring(oldPath.lastIndexOf(File.separator));
Todd Kennedy39bfee52016-02-24 10:28:21 -0800343 if (apkName.equals(oldApkName)) {
344 match = true;
345 break;
346 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700347 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800348 if (!match) {
349 addedPaths.add(path);
350 }
351 }
352 } else {
353 addedPaths.addAll(newPaths);
354 }
355 synchronized (this) {
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700356 createOrUpdateClassLoaderLocked(addedPaths);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800357 if (mResources != null) {
Adam Lesinski4e862812016-11-21 16:02:24 -0800358 final String[] splitPaths;
359 try {
360 splitPaths = getSplitPaths(null);
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800361 } catch (NameNotFoundException e) {
Adam Lesinski4e862812016-11-21 16:02:24 -0800362 // This should NEVER fail.
363 throw new AssertionError("null split not found");
364 }
365
366 mResources = ResourcesManager.getInstance().getResources(null, mResDir,
Adam Lesinski0e618832017-02-07 11:40:12 -0800367 splitPaths, mOverlayDirs, mApplicationInfo.sharedLibraryFiles,
Adam Lesinski4e862812016-11-21 16:02:24 -0800368 Display.DEFAULT_DISPLAY, null, getCompatibilityInfo(),
369 getClassLoader());
Todd Kennedy39bfee52016-02-24 10:28:21 -0800370 }
371 }
David Brazdilfd6dcc22018-10-25 14:07:51 +0100372 mAppComponentFactory = createAppFactory(aInfo, mDefaultClassLoader);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800373 }
374
375 private void setApplicationInfo(ApplicationInfo aInfo) {
376 final int myUid = Process.myUid();
377 aInfo = adjustNativeLibraryPaths(aInfo);
378 mApplicationInfo = aInfo;
379 mAppDir = aInfo.sourceDir;
380 mResDir = aInfo.uid == myUid ? aInfo.sourceDir : aInfo.publicSourceDir;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800381 mOverlayDirs = aInfo.resourceDirs;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800382 mDataDir = aInfo.dataDir;
383 mLibDir = aInfo.nativeLibraryDir;
384 mDataDirFile = FileUtils.newFileOrNull(aInfo.dataDir);
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600385 mDeviceProtectedDataDirFile = FileUtils.newFileOrNull(aInfo.deviceProtectedDataDir);
386 mCredentialProtectedDataDirFile = FileUtils.newFileOrNull(aInfo.credentialProtectedDataDir);
Adam Lesinski4e862812016-11-21 16:02:24 -0800387
388 mSplitNames = aInfo.splitNames;
389 mSplitAppDirs = aInfo.splitSourceDirs;
390 mSplitResDirs = aInfo.uid == myUid ? aInfo.splitSourceDirs : aInfo.splitPublicSourceDirs;
Narayan Kamathf9419f02017-06-15 11:35:38 +0100391 mSplitClassLoaderNames = aInfo.splitClassLoaderNames;
Adam Lesinski4e862812016-11-21 16:02:24 -0800392
393 if (aInfo.requestsIsolatedSplitLoading() && !ArrayUtils.isEmpty(mSplitNames)) {
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800394 mSplitLoader = new SplitDependencyLoaderImpl(aInfo.splitDependencies);
Adam Lesinski4e862812016-11-21 16:02:24 -0800395 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800396 }
397
Dimitry Ivanov638d8102017-02-22 15:39:42 -0800398 public static void makePaths(ActivityThread activityThread,
399 ApplicationInfo aInfo,
400 List<String> outZipPaths) {
401 makePaths(activityThread, false, aInfo, outZipPaths, null);
402 }
403
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000404 private static void appendSharedLibrariesLibPathsIfNeeded(
405 List<SharedLibraryInfo> sharedLibraries, ApplicationInfo aInfo,
406 Set<String> outSeenPaths,
407 List<String> outLibPaths) {
408 if (sharedLibraries == null) {
409 return;
410 }
411 for (SharedLibraryInfo lib : sharedLibraries) {
412 List<String> paths = lib.getAllCodePaths();
413 outSeenPaths.addAll(paths);
414 for (String path : paths) {
415 appendApkLibPathIfNeeded(path, aInfo, outLibPaths);
416 }
417 appendSharedLibrariesLibPathsIfNeeded(
418 lib.getDependencies(), aInfo, outSeenPaths, outLibPaths);
419 }
420 }
421
Dimitry Ivanov638d8102017-02-22 15:39:42 -0800422 public static void makePaths(ActivityThread activityThread,
423 boolean isBundledApp,
424 ApplicationInfo aInfo,
425 List<String> outZipPaths,
426 List<String> outLibPaths) {
Todd Kennedy39bfee52016-02-24 10:28:21 -0800427 final String appDir = aInfo.sourceDir;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800428 final String libDir = aInfo.nativeLibraryDir;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800429
430 outZipPaths.clear();
431 outZipPaths.add(appDir);
Adam Lesinski4e862812016-11-21 16:02:24 -0800432
433 // Do not load all available splits if the app requested isolated split loading.
434 if (aInfo.splitSourceDirs != null && !aInfo.requestsIsolatedSplitLoading()) {
435 Collections.addAll(outZipPaths, aInfo.splitSourceDirs);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800436 }
437
438 if (outLibPaths != null) {
439 outLibPaths.clear();
440 }
441
442 /*
443 * The following is a bit of a hack to inject
444 * instrumentation into the system: If the app
445 * being started matches one of the instrumentation names,
446 * then we combine both the "instrumentation" and
447 * "instrumented" app into the path, along with the
448 * concatenation of both apps' shared library lists.
449 */
450
Todd Kennedy39bfee52016-02-24 10:28:21 -0800451 String[] instrumentationLibs = null;
Torne (Richard Coles)3b6ca992016-10-10 15:11:36 +0100452 // activityThread will be null when called from the WebView zygote; just assume
453 // no instrumentation applies in this case.
454 if (activityThread != null) {
455 String instrumentationPackageName = activityThread.mInstrumentationPackageName;
456 String instrumentationAppDir = activityThread.mInstrumentationAppDir;
457 String[] instrumentationSplitAppDirs = activityThread.mInstrumentationSplitAppDirs;
458 String instrumentationLibDir = activityThread.mInstrumentationLibDir;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800459
Torne (Richard Coles)3b6ca992016-10-10 15:11:36 +0100460 String instrumentedAppDir = activityThread.mInstrumentedAppDir;
461 String[] instrumentedSplitAppDirs = activityThread.mInstrumentedSplitAppDirs;
462 String instrumentedLibDir = activityThread.mInstrumentedLibDir;
463
464 if (appDir.equals(instrumentationAppDir)
465 || appDir.equals(instrumentedAppDir)) {
466 outZipPaths.clear();
467 outZipPaths.add(instrumentationAppDir);
Adam Lesinski4e862812016-11-21 16:02:24 -0800468
469 // Only add splits if the app did not request isolated split loading.
470 if (!aInfo.requestsIsolatedSplitLoading()) {
471 if (instrumentationSplitAppDirs != null) {
472 Collections.addAll(outZipPaths, instrumentationSplitAppDirs);
473 }
474
475 if (!instrumentationAppDir.equals(instrumentedAppDir)) {
476 outZipPaths.add(instrumentedAppDir);
477 if (instrumentedSplitAppDirs != null) {
478 Collections.addAll(outZipPaths, instrumentedSplitAppDirs);
479 }
Torne (Richard Coles)3b6ca992016-10-10 15:11:36 +0100480 }
Jeff Haoc7b94822016-03-16 15:56:07 -0700481 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800482
Torne (Richard Coles)3b6ca992016-10-10 15:11:36 +0100483 if (outLibPaths != null) {
484 outLibPaths.add(instrumentationLibDir);
485 if (!instrumentationLibDir.equals(instrumentedLibDir)) {
486 outLibPaths.add(instrumentedLibDir);
487 }
488 }
489
490 if (!instrumentedAppDir.equals(instrumentationAppDir)) {
491 instrumentationLibs = getLibrariesFor(instrumentationPackageName);
492 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800493 }
494 }
495
496 if (outLibPaths != null) {
497 if (outLibPaths.isEmpty()) {
498 outLibPaths.add(libDir);
499 }
500
501 // Add path to libraries in apk for current abi. Do this now because more entries
502 // will be added to zipPaths that shouldn't be part of the library path.
503 if (aInfo.primaryCpuAbi != null) {
Alex Light20ed24f2016-04-20 14:07:43 -0700504 // Add fake libs into the library search path if we target prior to N.
Adam Lesinski4e862812016-11-21 16:02:24 -0800505 if (aInfo.targetSdkVersion < Build.VERSION_CODES.N) {
Alex Light20ed24f2016-04-20 14:07:43 -0700506 outLibPaths.add("/system/fake-libs" +
507 (VMRuntime.is64BitAbi(aInfo.primaryCpuAbi) ? "64" : ""));
508 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800509 for (String apk : outZipPaths) {
510 outLibPaths.add(apk + "!/lib/" + aInfo.primaryCpuAbi);
511 }
512 }
513
Dimitry Ivanov638d8102017-02-22 15:39:42 -0800514 if (isBundledApp) {
Todd Kennedy39bfee52016-02-24 10:28:21 -0800515 // Add path to system libraries to libPaths;
516 // Access to system libs should be limited
517 // to bundled applications; this is why updated
518 // system apps are not included.
519 outLibPaths.add(System.getProperty("java.library.path"));
520 }
521 }
522
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000523 // Add the shared libraries native paths. The dex files in shared libraries will
524 // be resolved through shared library loaders, which are setup later.
525 Set<String> outSeenPaths = new LinkedHashSet<>();
526 appendSharedLibrariesLibPathsIfNeeded(
527 aInfo.sharedLibraryInfos, aInfo, outSeenPaths, outLibPaths);
528
529 // ApplicationInfo.sharedLibraryFiles is a public API, so anyone can change it.
530 // We prepend shared libraries that the package manager hasn't seen, maintaining their
531 // original order where possible.
532 if (aInfo.sharedLibraryFiles != null) {
Jeff Hao090892f2017-04-24 17:37:31 -0700533 int index = 0;
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000534 for (String lib : aInfo.sharedLibraryFiles) {
535 if (!outSeenPaths.contains(lib) && !outZipPaths.contains(lib)) {
Jeff Hao090892f2017-04-24 17:37:31 -0700536 outZipPaths.add(index, lib);
537 index++;
Svetoslav Ganov40610e32017-06-20 19:35:51 -0700538 appendApkLibPathIfNeeded(lib, aInfo, outLibPaths);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800539 }
540 }
541 }
542
543 if (instrumentationLibs != null) {
544 for (String lib : instrumentationLibs) {
545 if (!outZipPaths.contains(lib)) {
546 outZipPaths.add(0, lib);
Svetoslav Ganov40610e32017-06-20 19:35:51 -0700547 appendApkLibPathIfNeeded(lib, aInfo, outLibPaths);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800548 }
549 }
550 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800551 }
552
Svetoslav Ganov40610e32017-06-20 19:35:51 -0700553 /**
554 * This method appends a path to the appropriate native library folder of a
555 * library if this library is hosted in an APK. This allows support for native
556 * shared libraries. The library API is determined based on the application
557 * ABI.
558 *
559 * @param path Path to the library.
560 * @param applicationInfo The application depending on the library.
561 * @param outLibPaths List to which to add the native lib path if needed.
562 */
563 private static void appendApkLibPathIfNeeded(@NonNull String path,
564 @NonNull ApplicationInfo applicationInfo, @Nullable List<String> outLibPaths) {
565 // Looking at the suffix is a little hacky but a safe and simple solution.
566 // We will be revisiting code in the next release and clean this up.
567 if (outLibPaths != null && applicationInfo.primaryCpuAbi != null && path.endsWith(".apk")) {
568 if (applicationInfo.targetSdkVersion >= Build.VERSION_CODES.O) {
569 outLibPaths.add(path + "!/lib/" + applicationInfo.primaryCpuAbi);
570 }
571 }
572 }
573
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800574 /*
575 * All indices received by the super class should be shifted by 1 when accessing mSplitNames,
576 * etc. The super class assumes the base APK is index 0, while the PackageManager APIs don't
577 * include the base APK in the list of splits.
578 */
579 private class SplitDependencyLoaderImpl extends SplitDependencyLoader<NameNotFoundException> {
Adam Lesinski4e862812016-11-21 16:02:24 -0800580 private final String[][] mCachedResourcePaths;
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800581 private final ClassLoader[] mCachedClassLoaders;
Adam Lesinski4e862812016-11-21 16:02:24 -0800582
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800583 SplitDependencyLoaderImpl(@NonNull SparseArray<int[]> dependencies) {
Adam Lesinski4e862812016-11-21 16:02:24 -0800584 super(dependencies);
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800585 mCachedResourcePaths = new String[mSplitNames.length + 1][];
586 mCachedClassLoaders = new ClassLoader[mSplitNames.length + 1];
Adam Lesinski4e862812016-11-21 16:02:24 -0800587 }
588
589 @Override
590 protected boolean isSplitCached(int splitIdx) {
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800591 return mCachedClassLoaders[splitIdx] != null;
Adam Lesinski4e862812016-11-21 16:02:24 -0800592 }
593
594 @Override
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800595 protected void constructSplit(int splitIdx, @NonNull int[] configSplitIndices,
596 int parentSplitIdx) throws NameNotFoundException {
Adam Lesinski4e862812016-11-21 16:02:24 -0800597 final ArrayList<String> splitPaths = new ArrayList<>();
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800598 if (splitIdx == 0) {
Adam Lesinski4e862812016-11-21 16:02:24 -0800599 createOrUpdateClassLoaderLocked(null);
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800600 mCachedClassLoaders[0] = mClassLoader;
601
602 // Never add the base resources here, they always get added no matter what.
603 for (int configSplitIdx : configSplitIndices) {
604 splitPaths.add(mSplitResDirs[configSplitIdx - 1]);
605 }
606 mCachedResourcePaths[0] = splitPaths.toArray(new String[splitPaths.size()]);
Adam Lesinski4e862812016-11-21 16:02:24 -0800607 return;
608 }
609
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800610 // Since we handled the special base case above, parentSplitIdx is always valid.
611 final ClassLoader parent = mCachedClassLoaders[parentSplitIdx];
612 mCachedClassLoaders[splitIdx] = ApplicationLoaders.getDefault().getClassLoader(
Narayan Kamathf9419f02017-06-15 11:35:38 +0100613 mSplitAppDirs[splitIdx - 1], getTargetSdkVersion(), false, null, null, parent,
614 mSplitClassLoaderNames[splitIdx - 1]);
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800615
616 Collections.addAll(splitPaths, mCachedResourcePaths[parentSplitIdx]);
617 splitPaths.add(mSplitResDirs[splitIdx - 1]);
618 for (int configSplitIdx : configSplitIndices) {
619 splitPaths.add(mSplitResDirs[configSplitIdx - 1]);
Adam Lesinski4e862812016-11-21 16:02:24 -0800620 }
Adam Lesinski4e862812016-11-21 16:02:24 -0800621 mCachedResourcePaths[splitIdx] = splitPaths.toArray(new String[splitPaths.size()]);
622 }
623
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800624 private int ensureSplitLoaded(String splitName) throws NameNotFoundException {
625 int idx = 0;
626 if (splitName != null) {
Adam Lesinski4e862812016-11-21 16:02:24 -0800627 idx = Arrays.binarySearch(mSplitNames, splitName);
628 if (idx < 0) {
629 throw new PackageManager.NameNotFoundException(
630 "Split name '" + splitName + "' is not installed");
631 }
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800632 idx += 1;
Adam Lesinski4e862812016-11-21 16:02:24 -0800633 }
Adam Lesinski4e862812016-11-21 16:02:24 -0800634 loadDependenciesForSplit(idx);
635 return idx;
636 }
637
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800638 ClassLoader getClassLoaderForSplit(String splitName) throws NameNotFoundException {
639 return mCachedClassLoaders[ensureSplitLoaded(splitName)];
Adam Lesinski4e862812016-11-21 16:02:24 -0800640 }
641
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800642 String[] getSplitPathsForSplit(String splitName) throws NameNotFoundException {
643 return mCachedResourcePaths[ensureSplitLoaded(splitName)];
Adam Lesinski4e862812016-11-21 16:02:24 -0800644 }
645 }
646
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800647 private SplitDependencyLoaderImpl mSplitLoader;
Adam Lesinski4e862812016-11-21 16:02:24 -0800648
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800649 ClassLoader getSplitClassLoader(String splitName) throws NameNotFoundException {
Adam Lesinski4e862812016-11-21 16:02:24 -0800650 if (mSplitLoader == null) {
651 return mClassLoader;
652 }
653 return mSplitLoader.getClassLoaderForSplit(splitName);
654 }
655
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800656 String[] getSplitPaths(String splitName) throws NameNotFoundException {
Adam Lesinski4e862812016-11-21 16:02:24 -0800657 if (mSplitLoader == null) {
658 return mSplitResDirs;
659 }
660 return mSplitLoader.getSplitPathsForSplit(splitName);
661 }
662
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000663 /**
664 * Create a class loader for the {@code sharedLibrary}. Shared libraries are canonicalized,
665 * so if we already created a class loader with that shared library, we return it.
666 *
667 * Implementation notes: the canonicalization of shared libraries is something dex2oat
668 * also does.
669 */
670 ClassLoader createSharedLibraryLoader(SharedLibraryInfo sharedLibrary,
671 boolean isBundledApp, String librarySearchPath, String libraryPermittedPath) {
672 List<String> paths = sharedLibrary.getAllCodePaths();
673 List<ClassLoader> sharedLibraries = createSharedLibrariesLoaders(
674 sharedLibrary.getDependencies(), isBundledApp, librarySearchPath,
675 libraryPermittedPath);
676 final String jars = (paths.size() == 1) ? paths.get(0) :
677 TextUtils.join(File.pathSeparator, paths);
678
679 // Shared libraries get a null parent: this has the side effect of having canonicalized
680 // shared libraries using ApplicationLoaders cache, which is the behavior we want.
681 return ApplicationLoaders.getDefault().getClassLoaderWithSharedLibraries(jars,
682 mApplicationInfo.targetSdkVersion, isBundledApp, librarySearchPath,
683 libraryPermittedPath, /* parent */ null,
684 /* classLoaderName */ null, sharedLibraries);
685 }
686
687 private List<ClassLoader> createSharedLibrariesLoaders(List<SharedLibraryInfo> sharedLibraries,
688 boolean isBundledApp, String librarySearchPath, String libraryPermittedPath) {
689 if (sharedLibraries == null) {
690 return null;
691 }
692 List<ClassLoader> loaders = new ArrayList<>();
693 for (SharedLibraryInfo info : sharedLibraries) {
694 loaders.add(createSharedLibraryLoader(
695 info, isBundledApp, librarySearchPath, libraryPermittedPath));
696 }
697 return loaders;
698 }
699
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100700 private StrictMode.ThreadPolicy allowThreadDiskReads() {
701 if (mActivityThread == null) {
702 // When LoadedApk is used without an ActivityThread (usually in a
703 // zygote context), don't call into StrictMode, as it initializes
704 // the binder subsystem, which we don't want.
705 return null;
706 }
707
708 return StrictMode.allowThreadDiskReads();
709 }
710
711 private void setThreadPolicy(StrictMode.ThreadPolicy policy) {
712 if (mActivityThread != null && policy != null) {
713 StrictMode.setThreadPolicy(policy);
714 }
715 }
716
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700717 private void createOrUpdateClassLoaderLocked(List<String> addedPaths) {
718 if (mPackageName.equals("android")) {
Calin Juravle430ef452016-04-22 17:43:07 +0100719 // Note: This branch is taken for system server and we don't need to setup
720 // jit profiling support.
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700721 if (mClassLoader != null) {
722 // nothing to update
723 return;
Dimitry Ivanovb9c90262016-02-19 14:09:20 -0800724 }
725
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700726 if (mBaseClassLoader != null) {
David Brazdilfd6dcc22018-10-25 14:07:51 +0100727 mDefaultClassLoader = mBaseClassLoader;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800728 } else {
David Brazdilfd6dcc22018-10-25 14:07:51 +0100729 mDefaultClassLoader = ClassLoader.getSystemClassLoader();
Todd Kennedy39bfee52016-02-24 10:28:21 -0800730 }
David Brazdilfd6dcc22018-10-25 14:07:51 +0100731 mAppComponentFactory = createAppFactory(mApplicationInfo, mDefaultClassLoader);
732 mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader);
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700733
734 return;
735 }
736
737 // Avoid the binder call when the package is the current application package.
738 // The activity manager will perform ensure that dexopt is performed before
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100739 // spinning up the process. Similarly, don't call into binder when we don't
740 // have an ActivityThread object.
741 if (mActivityThread != null
742 && !Objects.equals(mPackageName, ActivityThread.currentPackageName())
743 && mIncludeCode) {
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700744 try {
Brian Carlstromca82e612016-04-19 23:16:08 -0700745 ActivityThread.getPackageManager().notifyPackageUse(mPackageName,
746 PackageManager.NOTIFY_PACKAGE_USE_CROSS_PACKAGE);
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700747 } catch (RemoteException re) {
748 throw re.rethrowFromSystemServer();
Todd Kennedy39bfee52016-02-24 10:28:21 -0800749 }
750 }
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700751
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700752 if (mRegisterPackage) {
753 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -0800754 ActivityManager.getService().addPackageDependency(mPackageName);
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700755 } catch (RemoteException e) {
756 throw e.rethrowFromSystemServer();
757 }
758 }
759
Andreas Gampea8a58ff2016-05-18 11:58:39 -0700760 // Lists for the elements of zip/code and native libraries.
761 //
762 // Both lists are usually not empty. We expect on average one APK for the zip component,
763 // but shared libraries and splits are not uncommon. We expect at least three elements
764 // for native libraries (app-based, system, vendor). As such, give both some breathing
765 // space and initialize to a small value (instead of incurring growth code).
766 final List<String> zipPaths = new ArrayList<>(10);
767 final List<String> libPaths = new ArrayList<>(10);
Narayan Kamath8995b002016-05-11 20:31:09 +0100768
Jiyong Parkfcad6962017-08-22 10:24:28 +0900769 boolean isBundledApp = mApplicationInfo.isSystemApp()
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700770 && !mApplicationInfo.isUpdatedSystemApp();
Dimitry Ivanovbf3b5f72016-05-03 11:34:58 -0700771
Jiyong Parkfcad6962017-08-22 10:24:28 +0900772 // Vendor apks are treated as bundled only when /vendor/lib is in the default search
773 // paths. If not, they are treated as unbundled; access to system libs is limited.
774 // Having /vendor/lib in the default search paths means that all system processes
775 // are allowed to use any vendor library, which in turn means that system is dependent
776 // on vendor partition. In the contrary, not having /vendor/lib in the default search
777 // paths mean that the two partitions are separated and thus we can treat vendor apks
778 // as unbundled.
779 final String defaultSearchPaths = System.getProperty("java.library.path");
780 final boolean treatVendorApkAsUnbundled = !defaultSearchPaths.contains("/vendor/lib");
Jiyong Park63495c22017-09-15 07:48:06 +0900781 if (mApplicationInfo.getCodePath() != null
Jiyong Park002fdbd2017-02-13 20:50:31 +0900782 && mApplicationInfo.isVendor() && treatVendorApkAsUnbundled) {
Jiyong Parkfcad6962017-08-22 10:24:28 +0900783 isBundledApp = false;
784 }
785
Dimitry Ivanov638d8102017-02-22 15:39:42 -0800786 makePaths(mActivityThread, isBundledApp, mApplicationInfo, zipPaths, libPaths);
787
Dimitry Ivanoveb96b002016-05-10 10:51:40 -0700788 String libraryPermittedPath = mDataDir;
Jiyong Park29d9eba2018-05-04 12:44:38 +0900789
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700790 if (isBundledApp) {
Jiyong Park29d9eba2018-05-04 12:44:38 +0900791 // For bundled apps, add the base directory of the app (e.g.,
792 // /system/app/Foo/) to the permitted paths so that it can load libraries
793 // embedded in module apks under the directory. For now, GmsCore is relying
794 // on this, but this isn't specific to the app. Also note that, we don't
795 // need to do this for unbundled apps as entire /data is already set to
796 // the permitted paths for them.
797 libraryPermittedPath += File.pathSeparator
798 + Paths.get(getAppDir()).getParent().toString();
799
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700800 // This is necessary to grant bundled apps access to
801 // libraries located in subdirectories of /system/lib
Jiyong Parkfcad6962017-08-22 10:24:28 +0900802 libraryPermittedPath += File.pathSeparator + defaultSearchPaths;
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700803 }
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700804
805 final String librarySearchPath = TextUtils.join(File.pathSeparator, libPaths);
806
Narayan Kamath8995b002016-05-11 20:31:09 +0100807 // If we're not asked to include code, we construct a classloader that has
808 // no code path included. We still need to set up the library search paths
809 // and permitted path because NativeActivity relies on it (it attempts to
810 // call System.loadLibrary() on a classloader from a LoadedApk with
811 // mIncludeCode == false).
812 if (!mIncludeCode) {
David Brazdilfd6dcc22018-10-25 14:07:51 +0100813 if (mDefaultClassLoader == null) {
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100814 StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads();
David Brazdilfd6dcc22018-10-25 14:07:51 +0100815 mDefaultClassLoader = ApplicationLoaders.getDefault().getClassLoader(
Narayan Kamathf9419f02017-06-15 11:35:38 +0100816 "" /* codePath */, mApplicationInfo.targetSdkVersion, isBundledApp,
817 librarySearchPath, libraryPermittedPath, mBaseClassLoader,
818 null /* classLoaderName */);
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100819 setThreadPolicy(oldPolicy);
Jason Monk2544c692018-05-15 11:30:09 -0400820 mAppComponentFactory = AppComponentFactory.DEFAULT;
Narayan Kamath8995b002016-05-11 20:31:09 +0100821 }
822
David Brazdilfd6dcc22018-10-25 14:07:51 +0100823 if (mClassLoader == null) {
824 mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader);
825 }
826
Narayan Kamath8995b002016-05-11 20:31:09 +0100827 return;
828 }
829
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700830 /*
Narayan Kamath8995b002016-05-11 20:31:09 +0100831 * With all the combination done (if necessary, actually create the java class
832 * loader and set up JIT profiling support if necessary.
Andreas Gampea8a58ff2016-05-18 11:58:39 -0700833 *
834 * In many cases this is a single APK, so try to avoid the StringBuilder in TextUtils.
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700835 */
Andreas Gampea8a58ff2016-05-18 11:58:39 -0700836 final String zip = (zipPaths.size() == 1) ? zipPaths.get(0) :
837 TextUtils.join(File.pathSeparator, zipPaths);
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700838
Dianne Hackborn94846032017-03-31 17:55:23 -0700839 if (DEBUG) Slog.v(ActivityThread.TAG, "Class path: " + zip +
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700840 ", JNI path: " + librarySearchPath);
841
Calin Juravle430ef452016-04-22 17:43:07 +0100842 boolean needToSetupJitProfiles = false;
David Brazdilfd6dcc22018-10-25 14:07:51 +0100843 if (mDefaultClassLoader == null) {
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700844 // Temporarily disable logging of disk reads on the Looper thread
845 // as this is early and necessary.
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100846 StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads();
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700847
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000848 List<ClassLoader> sharedLibraries = createSharedLibrariesLoaders(
849 mApplicationInfo.sharedLibraryInfos, isBundledApp, librarySearchPath,
850 libraryPermittedPath);
851
852 mDefaultClassLoader = ApplicationLoaders.getDefault().getClassLoaderWithSharedLibraries(
853 zip, mApplicationInfo.targetSdkVersion, isBundledApp, librarySearchPath,
Narayan Kamathf9419f02017-06-15 11:35:38 +0100854 libraryPermittedPath, mBaseClassLoader,
Nicolas Geoffray8d144eb2018-11-15 12:59:52 +0000855 mApplicationInfo.classLoaderName, sharedLibraries);
David Brazdilfd6dcc22018-10-25 14:07:51 +0100856 mAppComponentFactory = createAppFactory(mApplicationInfo, mDefaultClassLoader);
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700857
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100858 setThreadPolicy(oldPolicy);
Calin Juravle430ef452016-04-22 17:43:07 +0100859 // Setup the class loader paths for profiling.
860 needToSetupJitProfiles = true;
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700861 }
862
Patrick Baumann1bea2372018-03-13 14:26:58 -0700863 if (!libPaths.isEmpty() && SystemProperties.getBoolean(PROPERTY_NAME_APPEND_NATIVE, true)) {
Patrick Baumann5c5daa42018-05-09 11:12:49 -0700864 // Temporarily disable logging of disk reads on the Looper thread as this is necessary
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100865 StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads();
Patrick Baumann5c5daa42018-05-09 11:12:49 -0700866 try {
David Brazdilfd6dcc22018-10-25 14:07:51 +0100867 ApplicationLoaders.getDefault().addNative(mDefaultClassLoader, libPaths);
Patrick Baumann5c5daa42018-05-09 11:12:49 -0700868 } finally {
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100869 setThreadPolicy(oldPolicy);
Patrick Baumann5c5daa42018-05-09 11:12:49 -0700870 }
Patrick Baumann1bea2372018-03-13 14:26:58 -0700871 }
872
Victor Changa366cc82019-02-07 15:20:25 +0000873 // /aepx/com.android.runtime/lib, /vendor/lib, /odm/lib and /product/lib
874 // are added to the native lib search paths of the classloader.
875 // Note that this is done AFTER the classloader is
Jiyong Parkcfe38cd2018-06-04 15:05:29 +0900876 // created by ApplicationLoaders.getDefault().getClassLoader(...). The
877 // reason is because if we have added the paths when creating the classloader
878 // above, the paths are also added to the search path of the linker namespace
879 // 'classloader-namespace', which will allow ALL libs in the paths to apps.
880 // Since only the libs listed in <partition>/etc/public.libraries.txt can be
881 // available to apps, we shouldn't add the paths then.
882 //
883 // However, we need to add the paths to the classloader (Java) though. This
884 // is because when a native lib is requested via System.loadLibrary(), the
885 // classloader first tries to find the requested lib in its own native libs
886 // search paths. If a lib is not found in one of the paths, dlopen() is not
887 // called at all. This can cause a problem that a vendor public native lib
888 // is accessible when directly opened via dlopen(), but inaccesible via
889 // System.loadLibrary(). In order to prevent the problem, we explicitly
890 // add the paths only to the classloader, and not to the native loader
891 // (linker namespace).
Victor Changa366cc82019-02-07 15:20:25 +0000892 List<String> extraLibPaths = new ArrayList<>(4);
Jiyong Parkcfe38cd2018-06-04 15:05:29 +0900893 String abiSuffix = VMRuntime.getRuntime().is64Bit() ? "64" : "";
Victor Changa366cc82019-02-07 15:20:25 +0000894 if (!defaultSearchPaths.contains("/apex/com.android.runtime/lib")) {
895 extraLibPaths.add("/apex/com.android.runtime/lib" + abiSuffix);
896 }
Jiyong Parkcfe38cd2018-06-04 15:05:29 +0900897 if (!defaultSearchPaths.contains("/vendor/lib")) {
898 extraLibPaths.add("/vendor/lib" + abiSuffix);
899 }
900 if (!defaultSearchPaths.contains("/odm/lib")) {
901 extraLibPaths.add("/odm/lib" + abiSuffix);
902 }
903 if (!defaultSearchPaths.contains("/product/lib")) {
904 extraLibPaths.add("/product/lib" + abiSuffix);
905 }
906 if (!extraLibPaths.isEmpty()) {
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100907 StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads();
Jiyong Parkcfe38cd2018-06-04 15:05:29 +0900908 try {
David Brazdilfd6dcc22018-10-25 14:07:51 +0100909 ApplicationLoaders.getDefault().addNative(mDefaultClassLoader, extraLibPaths);
Jiyong Parkcfe38cd2018-06-04 15:05:29 +0900910 } finally {
Martijn Coenend9ce1b02018-10-31 17:05:35 +0100911 setThreadPolicy(oldPolicy);
Jiyong Parkcfe38cd2018-06-04 15:05:29 +0900912 }
913 }
914
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700915 if (addedPaths != null && addedPaths.size() > 0) {
916 final String add = TextUtils.join(File.pathSeparator, addedPaths);
David Brazdilfd6dcc22018-10-25 14:07:51 +0100917 ApplicationLoaders.getDefault().addPath(mDefaultClassLoader, add);
Calin Juravle430ef452016-04-22 17:43:07 +0100918 // Setup the new code paths for profiling.
919 needToSetupJitProfiles = true;
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700920 }
Calin Juravle2a727d72016-04-15 19:33:46 +0100921
922 // Setup jit profile support.
Narayan Kamath2d4a2222016-04-25 19:16:56 +0100923 //
Calin Juravle2a727d72016-04-15 19:33:46 +0100924 // It is ok to call this multiple times if the application gets updated with new splits.
925 // The runtime only keeps track of unique code paths and can handle re-registration of
926 // the same code path. There's no need to pass `addedPaths` since any new code paths
927 // are already in `mApplicationInfo`.
Narayan Kamath2d4a2222016-04-25 19:16:56 +0100928 //
929 // It is NOT ok to call this function from the system_server (for any of the packages it
930 // loads code from) so we explicitly disallow it there.
931 if (needToSetupJitProfiles && !ActivityThread.isSystem()) {
Calin Juravle430ef452016-04-22 17:43:07 +0100932 setupJitProfileSupport();
Calin Juravle430ef452016-04-22 17:43:07 +0100933 }
David Brazdilfd6dcc22018-10-25 14:07:51 +0100934
935 // Call AppComponentFactory to select/create the main class loader of this app.
936 // Since this may call code in the app, mDefaultClassLoader must be fully set up
937 // before invoking the factory.
938 if (mClassLoader == null) {
939 mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader);
940 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800941 }
942
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100943 @UnsupportedAppUsage
Todd Kennedy39bfee52016-02-24 10:28:21 -0800944 public ClassLoader getClassLoader() {
945 synchronized (this) {
946 if (mClassLoader == null) {
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700947 createOrUpdateClassLoaderLocked(null /*addedPaths*/);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800948 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700949 return mClassLoader;
950 }
951 }
952
Calin Juravle2a727d72016-04-15 19:33:46 +0100953 private void setupJitProfileSupport() {
954 if (!SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false)) {
955 return;
956 }
David Brazdil991ff902018-12-03 10:59:29 +0000957
958 // If we use profiles, setup the dex reporter to notify package manager
959 // of any relevant dex loads. The idle maintenance job will use the information
960 // reported to optimize the loaded dex files.
961 // Note that we only need one global reporter per app.
962 // Make sure we do this before invoking app code for the first time so that we
963 // can capture the complete application startup.
964 BaseDexClassLoader.setReporter(DexLoadReporter.getInstance());
965
Calin Juravle126f7802016-05-24 15:23:47 +0100966 // Only set up profile support if the loaded apk has the same uid as the
967 // current process.
968 // Currently, we do not support profiling across different apps.
969 // (e.g. application's uid might be different when the code is
970 // loaded by another app via createApplicationContext)
971 if (mApplicationInfo.uid != Process.myUid()) {
972 return;
973 }
974
Calin Juravle2a727d72016-04-15 19:33:46 +0100975 final List<String> codePaths = new ArrayList<>();
976 if ((mApplicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0) {
977 codePaths.add(mApplicationInfo.sourceDir);
978 }
979 if (mApplicationInfo.splitSourceDirs != null) {
980 Collections.addAll(codePaths, mApplicationInfo.splitSourceDirs);
981 }
982
983 if (codePaths.isEmpty()) {
984 // If there are no code paths there's no need to setup a profile file and register with
985 // the runtime,
986 return;
987 }
988
Calin Juravle6ae39fc2018-01-19 20:32:47 -0800989 for (int i = codePaths.size() - 1; i >= 0; i--) {
990 String splitName = i == 0 ? null : mApplicationInfo.splitNames[i - 1];
991 String profileFile = ArtManager.getCurrentProfilePath(
992 mPackageName, UserHandle.myUserId(), splitName);
993 VMRuntime.registerAppInfo(profileFile, new String[] {codePaths.get(i)});
994 }
Calin Juravlef5a7bfc2017-03-13 23:30:30 -0700995
996 // Register the app data directory with the reporter. It will
997 // help deciding whether or not a dex file is the primary apk or a
998 // secondary dex.
999 DexLoadReporter.getInstance().registerAppDataDir(mPackageName, mDataDir);
Calin Juravle2a727d72016-04-15 19:33:46 +01001000 }
1001
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001002 /**
1003 * Setup value for Thread.getContextClassLoader(). If the
1004 * package will not run in in a VM with other packages, we set
1005 * the Java context ClassLoader to the
1006 * PackageInfo.getClassLoader value. However, if this VM can
1007 * contain multiple packages, we intead set the Java context
1008 * ClassLoader to a proxy that will warn about the use of Java
1009 * context ClassLoaders and then fall through to use the
1010 * system ClassLoader.
1011 *
1012 * <p> Note that this is similar to but not the same as the
1013 * android.content.Context.getClassLoader(). While both
1014 * context class loaders are typically set to the
1015 * PathClassLoader used to load the package archive in the
1016 * single application per VM case, a single Android process
1017 * may contain several Contexts executing on one thread with
1018 * their own logical ClassLoaders while the Java context
1019 * ClassLoader is a thread local. This is why in the case when
1020 * we have multiple packages per VM we do not set the Java
1021 * context ClassLoader to an arbitrary but instead warn the
1022 * user to set their own if we detect that they are using a
1023 * Java library that expects it to be set.
1024 */
1025 private void initializeJavaContextClassLoader() {
1026 IPackageManager pm = ActivityThread.getPackageManager();
1027 android.content.pm.PackageInfo pi;
1028 try {
Jeff Sharkeyc7bacab2016-02-09 15:56:11 -07001029 pi = pm.getPackageInfo(mPackageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
1030 UserHandle.myUserId());
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001031 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001032 throw e.rethrowFromSystemServer();
Dianne Hackborn208d9372013-02-25 13:17:54 -08001033 }
1034 if (pi == null) {
1035 throw new IllegalStateException("Unable to get package info for "
1036 + mPackageName + "; is package not installed?");
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001037 }
1038 /*
1039 * Two possible indications that this package could be
1040 * sharing its virtual machine with other packages:
1041 *
1042 * 1.) the sharedUserId attribute is set in the manifest,
1043 * indicating a request to share a VM with other
1044 * packages with the same sharedUserId.
1045 *
1046 * 2.) the application element of the manifest has an
1047 * attribute specifying a non-default process name,
1048 * indicating the desire to run in another packages VM.
1049 */
1050 boolean sharedUserIdSet = (pi.sharedUserId != null);
1051 boolean processNameNotDefault =
1052 (pi.applicationInfo != null &&
1053 !mPackageName.equals(pi.applicationInfo.processName));
1054 boolean sharable = (sharedUserIdSet || processNameNotDefault);
1055 ClassLoader contextClassLoader =
1056 (sharable)
1057 ? new WarningContextClassLoader()
1058 : mClassLoader;
1059 Thread.currentThread().setContextClassLoader(contextClassLoader);
1060 }
1061
1062 private static class WarningContextClassLoader extends ClassLoader {
1063
1064 private static boolean warned = false;
1065
1066 private void warn(String methodName) {
1067 if (warned) {
1068 return;
1069 }
1070 warned = true;
1071 Thread.currentThread().setContextClassLoader(getParent());
1072 Slog.w(ActivityThread.TAG, "ClassLoader." + methodName + ": " +
1073 "The class loader returned by " +
1074 "Thread.getContextClassLoader() may fail for processes " +
1075 "that host multiple applications. You should explicitly " +
1076 "specify a context class loader. For example: " +
1077 "Thread.setContextClassLoader(getClass().getClassLoader());");
1078 }
1079
1080 @Override public URL getResource(String resName) {
1081 warn("getResource");
1082 return getParent().getResource(resName);
1083 }
1084
1085 @Override public Enumeration<URL> getResources(String resName) throws IOException {
1086 warn("getResources");
1087 return getParent().getResources(resName);
1088 }
1089
1090 @Override public InputStream getResourceAsStream(String resName) {
1091 warn("getResourceAsStream");
1092 return getParent().getResourceAsStream(resName);
1093 }
1094
1095 @Override public Class<?> loadClass(String className) throws ClassNotFoundException {
1096 warn("loadClass");
1097 return getParent().loadClass(className);
1098 }
1099
1100 @Override public void setClassAssertionStatus(String cname, boolean enable) {
1101 warn("setClassAssertionStatus");
1102 getParent().setClassAssertionStatus(cname, enable);
1103 }
1104
1105 @Override public void setPackageAssertionStatus(String pname, boolean enable) {
1106 warn("setPackageAssertionStatus");
1107 getParent().setPackageAssertionStatus(pname, enable);
1108 }
1109
1110 @Override public void setDefaultAssertionStatus(boolean enable) {
1111 warn("setDefaultAssertionStatus");
1112 getParent().setDefaultAssertionStatus(enable);
1113 }
1114
1115 @Override public void clearAssertionStatus() {
1116 warn("clearAssertionStatus");
1117 getParent().clearAssertionStatus();
1118 }
1119 }
1120
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001121 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001122 public String getAppDir() {
1123 return mAppDir;
1124 }
1125
Brian Carlstromd893a892012-04-01 21:30:26 -07001126 public String getLibDir() {
1127 return mLibDir;
1128 }
1129
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001130 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001131 public String getResDir() {
1132 return mResDir;
1133 }
1134
Jeff Sharkey8a4c9722014-06-16 13:48:42 -07001135 public String[] getSplitAppDirs() {
1136 return mSplitAppDirs;
1137 }
1138
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001139 @UnsupportedAppUsage
Jeff Sharkey8a4c9722014-06-16 13:48:42 -07001140 public String[] getSplitResDirs() {
1141 return mSplitResDirs;
1142 }
1143
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001144 @UnsupportedAppUsage
MÃ¥rten Kongstad48d22322014-01-31 14:43:27 +01001145 public String[] getOverlayDirs() {
1146 return mOverlayDirs;
1147 }
1148
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001149 public String getDataDir() {
1150 return mDataDir;
1151 }
1152
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001153 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001154 public File getDataDirFile() {
1155 return mDataDirFile;
1156 }
1157
Jeff Sharkey8a372a02016-03-16 16:25:45 -06001158 public File getDeviceProtectedDataDirFile() {
1159 return mDeviceProtectedDataDirFile;
Jeff Sharkey15447792015-11-05 16:18:51 -08001160 }
1161
Jeff Sharkey8a372a02016-03-16 16:25:45 -06001162 public File getCredentialProtectedDataDirFile() {
1163 return mCredentialProtectedDataDirFile;
Jeff Sharkey15447792015-11-05 16:18:51 -08001164 }
1165
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001166 @UnsupportedAppUsage
Adam Lesinski4e862812016-11-21 16:02:24 -08001167 public AssetManager getAssets() {
1168 return getResources().getAssets();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001169 }
1170
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001171 @UnsupportedAppUsage
Adam Lesinski4e862812016-11-21 16:02:24 -08001172 public Resources getResources() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001173 if (mResources == null) {
Adam Lesinski4e862812016-11-21 16:02:24 -08001174 final String[] splitPaths;
1175 try {
1176 splitPaths = getSplitPaths(null);
Adam Lesinski1665d0f2017-03-10 14:46:57 -08001177 } catch (NameNotFoundException e) {
Adam Lesinski4e862812016-11-21 16:02:24 -08001178 // This should never fail.
1179 throw new AssertionError("null split not found");
1180 }
1181
Todd Kennedy233a0b12018-01-29 20:30:24 +00001182 mResources = ResourcesManager.getInstance().getResources(null, mResDir,
1183 splitPaths, mOverlayDirs, mApplicationInfo.sharedLibraryFiles,
1184 Display.DEFAULT_DISPLAY, null, getCompatibilityInfo(),
Adam Lesinski4e862812016-11-21 16:02:24 -08001185 getClassLoader());
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001186 }
1187 return mResources;
1188 }
1189
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001190 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001191 public Application makeApplication(boolean forceDefaultAppClass,
1192 Instrumentation instrumentation) {
1193 if (mApplication != null) {
1194 return mApplication;
1195 }
1196
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001197 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");
1198
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001199 Application app = null;
1200
1201 String appClass = mApplicationInfo.className;
1202 if (forceDefaultAppClass || (appClass == null)) {
1203 appClass = "android.app.Application";
1204 }
1205
1206 try {
1207 java.lang.ClassLoader cl = getClassLoader();
Narayan Kamath8091edb2014-10-15 11:38:44 +01001208 if (!mPackageName.equals("android")) {
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001209 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
1210 "initializeJavaContextClassLoader");
Narayan Kamath8091edb2014-10-15 11:38:44 +01001211 initializeJavaContextClassLoader();
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001212 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Narayan Kamath8091edb2014-10-15 11:38:44 +01001213 }
Jeff Browndefd4a62014-03-10 21:24:37 -07001214 ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001215 app = mActivityThread.mInstrumentation.newApplication(
1216 cl, appClass, appContext);
1217 appContext.setOuterContext(app);
1218 } catch (Exception e) {
1219 if (!mActivityThread.mInstrumentation.onException(app, e)) {
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001220 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001221 throw new RuntimeException(
1222 "Unable to instantiate application " + appClass
1223 + ": " + e.toString(), e);
1224 }
1225 }
1226 mActivityThread.mAllApplications.add(app);
1227 mApplication = app;
1228
1229 if (instrumentation != null) {
1230 try {
1231 instrumentation.callApplicationOnCreate(app);
1232 } catch (Exception e) {
1233 if (!instrumentation.onException(app, e)) {
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001234 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001235 throw new RuntimeException(
1236 "Unable to create application " + app.getClass().getName()
1237 + ": " + e.toString(), e);
1238 }
1239 }
1240 }
Adam Lesinskide898ff2014-01-29 18:20:45 -08001241
1242 // Rewrite the R 'constants' for all library apks.
Adam Lesinski4e862812016-11-21 16:02:24 -08001243 SparseArray<String> packageIdentifiers = getAssets().getAssignedPackageIdentifiers();
Adam Lesinskide898ff2014-01-29 18:20:45 -08001244 final int N = packageIdentifiers.size();
1245 for (int i = 0; i < N; i++) {
1246 final int id = packageIdentifiers.keyAt(i);
1247 if (id == 0x01 || id == 0x7f) {
1248 continue;
1249 }
1250
1251 rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);
1252 }
1253
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001254 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1255
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001256 return app;
1257 }
1258
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001259 @UnsupportedAppUsage
Adam Lesinskide898ff2014-01-29 18:20:45 -08001260 private void rewriteRValues(ClassLoader cl, String packageName, int id) {
Adam Lesinski2cb761e2014-08-15 13:59:02 -07001261 final Class<?> rClazz;
Adam Lesinskide898ff2014-01-29 18:20:45 -08001262 try {
Adam Lesinski2cb761e2014-08-15 13:59:02 -07001263 rClazz = cl.loadClass(packageName + ".R");
1264 } catch (ClassNotFoundException e) {
1265 // This is not necessarily an error, as some packages do not ship with resources
1266 // (or they do not need rewriting).
Adam Lesinski1e4663852014-08-15 14:47:28 -07001267 Log.i(TAG, "No resource references to update in package " + packageName);
Adam Lesinski2cb761e2014-08-15 13:59:02 -07001268 return;
1269 }
1270
Adam Lesinski1e4663852014-08-15 14:47:28 -07001271 final Method callback;
Adam Lesinski2cb761e2014-08-15 13:59:02 -07001272 try {
Adam Lesinski1e4663852014-08-15 14:47:28 -07001273 callback = rClazz.getMethod("onResourcesLoaded", int.class);
1274 } catch (NoSuchMethodException e) {
1275 // No rewriting to be done.
1276 return;
Adam Lesinskide898ff2014-01-29 18:20:45 -08001277 }
Adam Lesinski1e4663852014-08-15 14:47:28 -07001278
1279 Throwable cause;
1280 try {
1281 callback.invoke(null, id);
1282 return;
1283 } catch (IllegalAccessException e) {
1284 cause = e;
1285 } catch (InvocationTargetException e) {
1286 cause = e.getCause();
1287 }
1288
1289 throw new RuntimeException("Failed to rewrite resource references for " + packageName,
1290 cause);
Adam Lesinskide898ff2014-01-29 18:20:45 -08001291 }
1292
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001293 public void removeContextRegistrations(Context context,
1294 String who, String what) {
Jeff Sharkeyd7026f12012-03-01 20:50:32 -08001295 final boolean reportRegistrationLeaks = StrictMode.vmRegistrationLeaksEnabled();
Adam Lesinski23d40c42014-11-20 11:58:21 -08001296 synchronized (mReceivers) {
1297 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> rmap =
1298 mReceivers.remove(context);
1299 if (rmap != null) {
1300 for (int i = 0; i < rmap.size(); i++) {
1301 LoadedApk.ReceiverDispatcher rd = rmap.valueAt(i);
1302 IntentReceiverLeaked leak = new IntentReceiverLeaked(
1303 what + " " + who + " has leaked IntentReceiver "
1304 + rd.getIntentReceiver() + " that was " +
1305 "originally registered here. Are you missing a " +
1306 "call to unregisterReceiver()?");
1307 leak.setStackTrace(rd.getLocation().getStackTrace());
1308 Slog.e(ActivityThread.TAG, leak.getMessage(), leak);
1309 if (reportRegistrationLeaks) {
1310 StrictMode.onIntentReceiverLeaked(leak);
1311 }
1312 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001313 ActivityManager.getService().unregisterReceiver(
Adam Lesinski23d40c42014-11-20 11:58:21 -08001314 rd.getIIntentReceiver());
1315 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001316 throw e.rethrowFromSystemServer();
Adam Lesinski23d40c42014-11-20 11:58:21 -08001317 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001318 }
1319 }
Adam Lesinski23d40c42014-11-20 11:58:21 -08001320 mUnregisteredReceivers.remove(context);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001321 }
Adam Lesinski23d40c42014-11-20 11:58:21 -08001322
1323 synchronized (mServices) {
1324 //Slog.i(TAG, "Receiver registrations: " + mReceivers);
1325 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> smap =
1326 mServices.remove(context);
1327 if (smap != null) {
1328 for (int i = 0; i < smap.size(); i++) {
1329 LoadedApk.ServiceDispatcher sd = smap.valueAt(i);
1330 ServiceConnectionLeaked leak = new ServiceConnectionLeaked(
1331 what + " " + who + " has leaked ServiceConnection "
1332 + sd.getServiceConnection() + " that was originally bound here");
1333 leak.setStackTrace(sd.getLocation().getStackTrace());
1334 Slog.e(ActivityThread.TAG, leak.getMessage(), leak);
1335 if (reportRegistrationLeaks) {
1336 StrictMode.onServiceConnectionLeaked(leak);
1337 }
1338 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001339 ActivityManager.getService().unbindService(
Adam Lesinski23d40c42014-11-20 11:58:21 -08001340 sd.getIServiceConnection());
1341 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001342 throw e.rethrowFromSystemServer();
Adam Lesinski23d40c42014-11-20 11:58:21 -08001343 }
1344 sd.doForget();
Jeff Sharkeyd7026f12012-03-01 20:50:32 -08001345 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001346 }
Adam Lesinski23d40c42014-11-20 11:58:21 -08001347 mUnboundServices.remove(context);
1348 //Slog.i(TAG, "Service registrations: " + mServices);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001349 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001350 }
1351
1352 public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r,
1353 Context context, Handler handler,
1354 Instrumentation instrumentation, boolean registered) {
1355 synchronized (mReceivers) {
1356 LoadedApk.ReceiverDispatcher rd = null;
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001357 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001358 if (registered) {
1359 map = mReceivers.get(context);
1360 if (map != null) {
1361 rd = map.get(r);
1362 }
1363 }
1364 if (rd == null) {
1365 rd = new ReceiverDispatcher(r, context, handler,
1366 instrumentation, registered);
1367 if (registered) {
1368 if (map == null) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001369 map = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001370 mReceivers.put(context, map);
1371 }
1372 map.put(r, rd);
1373 }
1374 } else {
1375 rd.validate(context, handler);
1376 }
Dianne Hackbornc2d9c8e2011-01-24 21:59:21 -08001377 rd.mForgotten = false;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001378 return rd.getIIntentReceiver();
1379 }
1380 }
1381
1382 public IIntentReceiver forgetReceiverDispatcher(Context context,
1383 BroadcastReceiver r) {
1384 synchronized (mReceivers) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001385 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = mReceivers.get(context);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001386 LoadedApk.ReceiverDispatcher rd = null;
1387 if (map != null) {
1388 rd = map.get(r);
1389 if (rd != null) {
1390 map.remove(r);
1391 if (map.size() == 0) {
1392 mReceivers.remove(context);
1393 }
1394 if (r.getDebugUnregister()) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001395 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> holder
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001396 = mUnregisteredReceivers.get(context);
1397 if (holder == null) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001398 holder = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001399 mUnregisteredReceivers.put(context, holder);
1400 }
1401 RuntimeException ex = new IllegalArgumentException(
1402 "Originally unregistered here:");
1403 ex.fillInStackTrace();
1404 rd.setUnregisterLocation(ex);
1405 holder.put(r, rd);
1406 }
Dianne Hackbornc2d9c8e2011-01-24 21:59:21 -08001407 rd.mForgotten = true;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001408 return rd.getIIntentReceiver();
1409 }
1410 }
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001411 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> holder
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001412 = mUnregisteredReceivers.get(context);
1413 if (holder != null) {
1414 rd = holder.get(r);
1415 if (rd != null) {
1416 RuntimeException ex = rd.getUnregisterLocation();
1417 throw new IllegalArgumentException(
1418 "Unregistering Receiver " + r
1419 + " that was already unregistered", ex);
1420 }
1421 }
1422 if (context == null) {
1423 throw new IllegalStateException("Unbinding Receiver " + r
1424 + " from Context that is no longer in use: " + context);
1425 } else {
1426 throw new IllegalArgumentException("Receiver not registered: " + r);
1427 }
1428
1429 }
1430 }
1431
1432 static final class ReceiverDispatcher {
1433
1434 final static class InnerReceiver extends IIntentReceiver.Stub {
1435 final WeakReference<LoadedApk.ReceiverDispatcher> mDispatcher;
1436 final LoadedApk.ReceiverDispatcher mStrongRef;
1437
1438 InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) {
1439 mDispatcher = new WeakReference<LoadedApk.ReceiverDispatcher>(rd);
1440 mStrongRef = strong ? rd : null;
1441 }
Jeff Sharkeyd136e512016-03-09 22:30:56 -07001442
1443 @Override
Dianne Hackborn20e80982012-08-31 19:00:44 -07001444 public void performReceive(Intent intent, int resultCode, String data,
1445 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
Dianne Hackborn26756162016-05-17 13:40:44 -07001446 final LoadedApk.ReceiverDispatcher rd;
1447 if (intent == null) {
1448 Log.wtf(TAG, "Null intent received");
1449 rd = null;
1450 } else {
1451 rd = mDispatcher.get();
1452 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001453 if (ActivityThread.DEBUG_BROADCAST) {
1454 int seq = intent.getIntExtra("seq", -1);
Dianne Hackborn26756162016-05-17 13:40:44 -07001455 Slog.i(ActivityThread.TAG, "Receiving broadcast " + intent.getAction()
1456 + " seq=" + seq + " to " + (rd != null ? rd.mReceiver : null));
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001457 }
1458 if (rd != null) {
1459 rd.performReceive(intent, resultCode, data, extras,
Dianne Hackborn20e80982012-08-31 19:00:44 -07001460 ordered, sticky, sendingUser);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001461 } else {
1462 // The activity manager dispatched a broadcast to a registered
1463 // receiver in this process, but before it could be delivered the
1464 // receiver was unregistered. Acknowledge the broadcast on its
1465 // behalf so that the system's broadcast sequence can continue.
1466 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1467 "Finishing broadcast to unregistered receiver");
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001468 IActivityManager mgr = ActivityManager.getService();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001469 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001470 if (extras != null) {
1471 extras.setAllowFds(false);
1472 }
riddle_hsu1f5ac4d2015-01-03 15:38:21 +08001473 mgr.finishReceiver(this, resultCode, data, extras, false, intent.getFlags());
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001474 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001475 throw e.rethrowFromSystemServer();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001476 }
1477 }
1478 }
1479 }
1480
1481 final IIntentReceiver.Stub mIIntentReceiver;
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001482 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001483 final BroadcastReceiver mReceiver;
Mathew Inwood8c854f82018-09-14 12:35:36 +01001484 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001485 final Context mContext;
1486 final Handler mActivityThread;
1487 final Instrumentation mInstrumentation;
1488 final boolean mRegistered;
1489 final IntentReceiverLeaked mLocation;
1490 RuntimeException mUnregisterLocation;
Dianne Hackbornc2d9c8e2011-01-24 21:59:21 -08001491 boolean mForgotten;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001492
Makoto Onuki08408b92017-05-09 13:48:53 -07001493 final class Args extends BroadcastReceiver.PendingResult {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001494 private Intent mCurIntent;
Dianne Hackborne829fef2010-10-26 17:44:01 -07001495 private final boolean mOrdered;
Dianne Hackborn17c77532016-06-22 16:49:14 -07001496 private boolean mDispatched;
Makoto Onukif3bb6f32017-05-02 12:02:23 -07001497 private Throwable mPreviousRunStacktrace; // To investigate b/37809561. STOPSHIP remove.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001498
Dianne Hackborne829fef2010-10-26 17:44:01 -07001499 public Args(Intent intent, int resultCode, String resultData, Bundle resultExtras,
Dianne Hackborn20e80982012-08-31 19:00:44 -07001500 boolean ordered, boolean sticky, int sendingUser) {
Dianne Hackborne829fef2010-10-26 17:44:01 -07001501 super(resultCode, resultData, resultExtras,
riddle_hsu1f5ac4d2015-01-03 15:38:21 +08001502 mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED, ordered,
1503 sticky, mIIntentReceiver.asBinder(), sendingUser, intent.getFlags());
Dianne Hackborne829fef2010-10-26 17:44:01 -07001504 mCurIntent = intent;
1505 mOrdered = ordered;
1506 }
Dianne Hackborn17c77532016-06-22 16:49:14 -07001507
Makoto Onuki08408b92017-05-09 13:48:53 -07001508 public final Runnable getRunnable() {
1509 return () -> {
1510 final BroadcastReceiver receiver = mReceiver;
1511 final boolean ordered = mOrdered;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001512
Makoto Onuki08408b92017-05-09 13:48:53 -07001513 if (ActivityThread.DEBUG_BROADCAST) {
1514 int seq = mCurIntent.getIntExtra("seq", -1);
1515 Slog.i(ActivityThread.TAG, "Dispatching broadcast " + mCurIntent.getAction()
1516 + " seq=" + seq + " to " + mReceiver);
1517 Slog.i(ActivityThread.TAG, " mRegistered=" + mRegistered
1518 + " mOrderedHint=" + ordered);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001519 }
Makoto Onuki08408b92017-05-09 13:48:53 -07001520
1521 final IActivityManager mgr = ActivityManager.getService();
1522 final Intent intent = mCurIntent;
1523 if (intent == null) {
1524 Log.wtf(TAG, "Null intent being dispatched, mDispatched=" + mDispatched
1525 + ": run() previously called at "
1526 + Log.getStackTraceString(mPreviousRunStacktrace));
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001527 }
Makoto Onuki08408b92017-05-09 13:48:53 -07001528
1529 mCurIntent = null;
1530 mDispatched = true;
1531 mPreviousRunStacktrace = new Throwable("Previous stacktrace");
1532 if (receiver == null || intent == null || mForgotten) {
1533 if (mRegistered && ordered) {
1534 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1535 "Finishing null broadcast to " + mReceiver);
1536 sendFinished(mgr);
1537 }
1538 return;
1539 }
1540
1541 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveReg");
1542 try {
1543 ClassLoader cl = mReceiver.getClass().getClassLoader();
1544 intent.setExtrasClassLoader(cl);
1545 intent.prepareToEnterProcess();
1546 setExtrasClassLoader(cl);
1547 receiver.setPendingResult(this);
1548 receiver.onReceive(mContext, intent);
1549 } catch (Exception e) {
1550 if (mRegistered && ordered) {
1551 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1552 "Finishing failed broadcast to " + mReceiver);
1553 sendFinished(mgr);
1554 }
1555 if (mInstrumentation == null ||
1556 !mInstrumentation.onException(mReceiver, e)) {
1557 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1558 throw new RuntimeException(
1559 "Error receiving broadcast " + intent
1560 + " in " + mReceiver, e);
1561 }
1562 }
1563
1564 if (receiver.getPendingResult() != null) {
1565 finish();
1566 }
1567 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1568 };
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001569 }
1570 }
1571
1572 ReceiverDispatcher(BroadcastReceiver receiver, Context context,
1573 Handler activityThread, Instrumentation instrumentation,
1574 boolean registered) {
1575 if (activityThread == null) {
1576 throw new NullPointerException("Handler must not be null");
1577 }
1578
1579 mIIntentReceiver = new InnerReceiver(this, !registered);
1580 mReceiver = receiver;
1581 mContext = context;
1582 mActivityThread = activityThread;
1583 mInstrumentation = instrumentation;
1584 mRegistered = registered;
1585 mLocation = new IntentReceiverLeaked(null);
1586 mLocation.fillInStackTrace();
1587 }
1588
1589 void validate(Context context, Handler activityThread) {
1590 if (mContext != context) {
1591 throw new IllegalStateException(
1592 "Receiver " + mReceiver +
1593 " registered with differing Context (was " +
1594 mContext + " now " + context + ")");
1595 }
1596 if (mActivityThread != activityThread) {
1597 throw new IllegalStateException(
1598 "Receiver " + mReceiver +
1599 " registered with differing handler (was " +
1600 mActivityThread + " now " + activityThread + ")");
1601 }
1602 }
1603
1604 IntentReceiverLeaked getLocation() {
1605 return mLocation;
1606 }
1607
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001608 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001609 BroadcastReceiver getIntentReceiver() {
1610 return mReceiver;
1611 }
1612
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001613 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001614 IIntentReceiver getIIntentReceiver() {
1615 return mIIntentReceiver;
1616 }
1617
1618 void setUnregisterLocation(RuntimeException ex) {
1619 mUnregisterLocation = ex;
1620 }
1621
1622 RuntimeException getUnregisterLocation() {
1623 return mUnregisterLocation;
1624 }
1625
Dianne Hackborn20e80982012-08-31 19:00:44 -07001626 public void performReceive(Intent intent, int resultCode, String data,
1627 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
Dianne Hackborn41bfaf82016-06-08 16:33:29 -07001628 final Args args = new Args(intent, resultCode, data, extras, ordered,
Dianne Hackborn20e80982012-08-31 19:00:44 -07001629 sticky, sendingUser);
Dianne Hackborn41bfaf82016-06-08 16:33:29 -07001630 if (intent == null) {
1631 Log.wtf(TAG, "Null intent received");
1632 } else {
1633 if (ActivityThread.DEBUG_BROADCAST) {
1634 int seq = intent.getIntExtra("seq", -1);
1635 Slog.i(ActivityThread.TAG, "Enqueueing broadcast " + intent.getAction()
1636 + " seq=" + seq + " to " + mReceiver);
1637 }
1638 }
Makoto Onuki08408b92017-05-09 13:48:53 -07001639 if (intent == null || !mActivityThread.post(args.getRunnable())) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001640 if (mRegistered && ordered) {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001641 IActivityManager mgr = ActivityManager.getService();
Dianne Hackborne829fef2010-10-26 17:44:01 -07001642 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1643 "Finishing sync broadcast to " + mReceiver);
1644 args.sendFinished(mgr);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001645 }
1646 }
1647 }
1648
1649 }
1650
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001651 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001652 public final IServiceConnection getServiceDispatcher(ServiceConnection c,
1653 Context context, Handler handler, int flags) {
1654 synchronized (mServices) {
1655 LoadedApk.ServiceDispatcher sd = null;
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001656 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001657 if (map != null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001658 if (DEBUG) Slog.d(TAG, "Returning existing dispatcher " + sd + " for conn " + c);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001659 sd = map.get(c);
1660 }
1661 if (sd == null) {
1662 sd = new ServiceDispatcher(c, context, handler, flags);
Dianne Hackborn94846032017-03-31 17:55:23 -07001663 if (DEBUG) Slog.d(TAG, "Creating new dispatcher " + sd + " for conn " + c);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001664 if (map == null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001665 map = new ArrayMap<>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001666 mServices.put(context, map);
1667 }
1668 map.put(c, sd);
1669 } else {
1670 sd.validate(context, handler);
1671 }
1672 return sd.getIServiceConnection();
1673 }
1674 }
1675
Dianne Hackborn2f55e5a2018-11-30 16:31:31 -08001676 @UnsupportedAppUsage
1677 public IServiceConnection lookupServiceDispatcher(ServiceConnection c,
1678 Context context) {
1679 synchronized (mServices) {
1680 LoadedApk.ServiceDispatcher sd = null;
1681 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
1682 if (map != null) {
1683 sd = map.get(c);
1684 }
1685 return sd != null ? sd.getIServiceConnection() : null;
1686 }
1687 }
1688
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001689 public final IServiceConnection forgetServiceDispatcher(Context context,
1690 ServiceConnection c) {
1691 synchronized (mServices) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001692 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001693 = mServices.get(context);
1694 LoadedApk.ServiceDispatcher sd = null;
1695 if (map != null) {
1696 sd = map.get(c);
1697 if (sd != null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001698 if (DEBUG) Slog.d(TAG, "Removing dispatcher " + sd + " for conn " + c);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001699 map.remove(c);
1700 sd.doForget();
1701 if (map.size() == 0) {
1702 mServices.remove(context);
1703 }
1704 if ((sd.getFlags()&Context.BIND_DEBUG_UNBIND) != 0) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001705 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> holder
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001706 = mUnboundServices.get(context);
1707 if (holder == null) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001708 holder = new ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001709 mUnboundServices.put(context, holder);
1710 }
1711 RuntimeException ex = new IllegalArgumentException(
1712 "Originally unbound here:");
1713 ex.fillInStackTrace();
1714 sd.setUnbindLocation(ex);
1715 holder.put(c, sd);
1716 }
1717 return sd.getIServiceConnection();
1718 }
1719 }
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001720 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> holder
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001721 = mUnboundServices.get(context);
1722 if (holder != null) {
1723 sd = holder.get(c);
1724 if (sd != null) {
1725 RuntimeException ex = sd.getUnbindLocation();
1726 throw new IllegalArgumentException(
1727 "Unbinding Service " + c
1728 + " that was already unbound", ex);
1729 }
1730 }
1731 if (context == null) {
1732 throw new IllegalStateException("Unbinding Service " + c
1733 + " from Context that is no longer in use: " + context);
1734 } else {
1735 throw new IllegalArgumentException("Service not registered: " + c);
1736 }
1737 }
1738 }
1739
1740 static final class ServiceDispatcher {
1741 private final ServiceDispatcher.InnerConnection mIServiceConnection;
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001742 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001743 private final ServiceConnection mConnection;
Mathew Inwood8c854f82018-09-14 12:35:36 +01001744 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001745 private final Context mContext;
1746 private final Handler mActivityThread;
1747 private final ServiceConnectionLeaked mLocation;
1748 private final int mFlags;
1749
1750 private RuntimeException mUnbindLocation;
1751
Dianne Hackborn5a6ef732011-11-11 12:31:52 -08001752 private boolean mForgotten;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001753
1754 private static class ConnectionInfo {
1755 IBinder binder;
1756 IBinder.DeathRecipient deathMonitor;
1757 }
1758
1759 private static class InnerConnection extends IServiceConnection.Stub {
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001760 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001761 final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;
1762
1763 InnerConnection(LoadedApk.ServiceDispatcher sd) {
1764 mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
1765 }
1766
Dianne Hackborn94846032017-03-31 17:55:23 -07001767 public void connected(ComponentName name, IBinder service, boolean dead)
1768 throws RemoteException {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001769 LoadedApk.ServiceDispatcher sd = mDispatcher.get();
1770 if (sd != null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001771 sd.connected(name, service, dead);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001772 }
1773 }
1774 }
1775
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001776 private final ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo> mActiveConnections
1777 = new ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001778
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001779 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001780 ServiceDispatcher(ServiceConnection conn,
1781 Context context, Handler activityThread, int flags) {
1782 mIServiceConnection = new InnerConnection(this);
1783 mConnection = conn;
1784 mContext = context;
1785 mActivityThread = activityThread;
1786 mLocation = new ServiceConnectionLeaked(null);
1787 mLocation.fillInStackTrace();
1788 mFlags = flags;
1789 }
1790
1791 void validate(Context context, Handler activityThread) {
1792 if (mContext != context) {
1793 throw new RuntimeException(
1794 "ServiceConnection " + mConnection +
1795 " registered with differing Context (was " +
1796 mContext + " now " + context + ")");
1797 }
1798 if (mActivityThread != activityThread) {
1799 throw new RuntimeException(
1800 "ServiceConnection " + mConnection +
1801 " registered with differing handler (was " +
1802 mActivityThread + " now " + activityThread + ")");
1803 }
1804 }
1805
1806 void doForget() {
1807 synchronized(this) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001808 for (int i=0; i<mActiveConnections.size(); i++) {
1809 ServiceDispatcher.ConnectionInfo ci = mActiveConnections.valueAt(i);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001810 ci.binder.unlinkToDeath(ci.deathMonitor, 0);
1811 }
1812 mActiveConnections.clear();
Dianne Hackborn5a6ef732011-11-11 12:31:52 -08001813 mForgotten = true;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001814 }
1815 }
1816
1817 ServiceConnectionLeaked getLocation() {
1818 return mLocation;
1819 }
1820
1821 ServiceConnection getServiceConnection() {
1822 return mConnection;
1823 }
1824
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001825 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001826 IServiceConnection getIServiceConnection() {
1827 return mIServiceConnection;
1828 }
1829
1830 int getFlags() {
1831 return mFlags;
1832 }
1833
1834 void setUnbindLocation(RuntimeException ex) {
1835 mUnbindLocation = ex;
1836 }
1837
1838 RuntimeException getUnbindLocation() {
1839 return mUnbindLocation;
1840 }
1841
Dianne Hackborn94846032017-03-31 17:55:23 -07001842 public void connected(ComponentName name, IBinder service, boolean dead) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001843 if (mActivityThread != null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001844 mActivityThread.post(new RunConnection(name, service, 0, dead));
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001845 } else {
Dianne Hackborn94846032017-03-31 17:55:23 -07001846 doConnected(name, service, dead);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001847 }
1848 }
1849
1850 public void death(ComponentName name, IBinder service) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001851 if (mActivityThread != null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001852 mActivityThread.post(new RunConnection(name, service, 1, false));
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001853 } else {
1854 doDeath(name, service);
1855 }
1856 }
1857
Dianne Hackborn94846032017-03-31 17:55:23 -07001858 public void doConnected(ComponentName name, IBinder service, boolean dead) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001859 ServiceDispatcher.ConnectionInfo old;
1860 ServiceDispatcher.ConnectionInfo info;
1861
1862 synchronized (this) {
Dianne Hackborn5a6ef732011-11-11 12:31:52 -08001863 if (mForgotten) {
1864 // We unbound before receiving the connection; ignore
1865 // any connection received.
1866 return;
1867 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001868 old = mActiveConnections.get(name);
1869 if (old != null && old.binder == service) {
1870 // Huh, already have this one. Oh well!
1871 return;
1872 }
1873
1874 if (service != null) {
1875 // A new service is being connected... set it all up.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001876 info = new ConnectionInfo();
1877 info.binder = service;
1878 info.deathMonitor = new DeathMonitor(name, service);
1879 try {
1880 service.linkToDeath(info.deathMonitor, 0);
1881 mActiveConnections.put(name, info);
1882 } catch (RemoteException e) {
1883 // This service was dead before we got it... just
1884 // don't do anything with it.
1885 mActiveConnections.remove(name);
1886 return;
1887 }
1888
1889 } else {
1890 // The named service is being disconnected... clean up.
1891 mActiveConnections.remove(name);
1892 }
1893
1894 if (old != null) {
1895 old.binder.unlinkToDeath(old.deathMonitor, 0);
1896 }
1897 }
1898
Adrian Roosa9b43182016-07-21 13:20:38 -07001899 // If there was an old service, it is now disconnected.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001900 if (old != null) {
1901 mConnection.onServiceDisconnected(name);
1902 }
Dianne Hackborn94846032017-03-31 17:55:23 -07001903 if (dead) {
Dianne Hackbornac265342017-04-19 14:53:18 -07001904 mConnection.onBindingDied(name);
Dianne Hackborn94846032017-03-31 17:55:23 -07001905 }
Christopher Tate5d73b6d2017-10-06 16:15:34 -07001906 // If there is a new viable service, it is now connected.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001907 if (service != null) {
1908 mConnection.onServiceConnected(name, service);
Christopher Tate5d73b6d2017-10-06 16:15:34 -07001909 } else {
1910 // The binding machinery worked, but the remote returned null from onBind().
1911 mConnection.onNullBinding(name);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001912 }
1913 }
1914
1915 public void doDeath(ComponentName name, IBinder service) {
Adrian Roosa9b43182016-07-21 13:20:38 -07001916 synchronized (this) {
1917 ConnectionInfo old = mActiveConnections.get(name);
1918 if (old == null || old.binder != service) {
1919 // Death for someone different than who we last
1920 // reported... just ignore it.
1921 return;
1922 }
1923 mActiveConnections.remove(name);
1924 old.binder.unlinkToDeath(old.deathMonitor, 0);
1925 }
1926
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001927 mConnection.onServiceDisconnected(name);
1928 }
1929
1930 private final class RunConnection implements Runnable {
Dianne Hackborn94846032017-03-31 17:55:23 -07001931 RunConnection(ComponentName name, IBinder service, int command, boolean dead) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001932 mName = name;
1933 mService = service;
1934 mCommand = command;
Dianne Hackborn94846032017-03-31 17:55:23 -07001935 mDead = dead;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001936 }
1937
1938 public void run() {
1939 if (mCommand == 0) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001940 doConnected(mName, mService, mDead);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001941 } else if (mCommand == 1) {
1942 doDeath(mName, mService);
1943 }
1944 }
1945
1946 final ComponentName mName;
1947 final IBinder mService;
1948 final int mCommand;
Dianne Hackborn94846032017-03-31 17:55:23 -07001949 final boolean mDead;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001950 }
1951
1952 private final class DeathMonitor implements IBinder.DeathRecipient
1953 {
1954 DeathMonitor(ComponentName name, IBinder service) {
1955 mName = name;
1956 mService = service;
1957 }
1958
1959 public void binderDied() {
1960 death(mName, mService);
1961 }
1962
1963 final ComponentName mName;
1964 final IBinder mService;
1965 }
1966 }
1967}