blob: b827d01314ce993ebfda0fcfedd93256669469c8 [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 Inwood4fb17d12018-08-14 14:25: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;
Calin Juravle6ae39fc2018-01-19 20:32:47 -080032import android.content.pm.dex.ArtManager;
Adam Lesinski1665d0f2017-03-10 14:46:57 -080033import android.content.pm.split.SplitDependencyLoader;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070034import android.content.res.AssetManager;
35import android.content.res.CompatibilityInfo;
36import android.content.res.Resources;
Adam Lesinski4e862812016-11-21 16:02:24 -080037import android.os.Build;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070038import android.os.Bundle;
Jeff Sharkey15447792015-11-05 16:18:51 -080039import android.os.FileUtils;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070040import android.os.Handler;
41import android.os.IBinder;
42import android.os.Process;
43import android.os.RemoteException;
Brad Fitzpatrick624d50f2010-11-09 14:25:12 -080044import android.os.StrictMode;
Jeff Sharkey8a372a02016-03-16 16:25:45 -060045import android.os.SystemProperties;
Dianne Hackborn1ded0b12012-04-26 14:14:50 -070046import android.os.Trace;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070047import android.os.UserHandle;
Jeff Sharkey8a372a02016-03-16 16:25:45 -060048import android.text.TextUtils;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070049import android.util.AndroidRuntimeException;
Jeff Sharkey8a372a02016-03-16 16:25:45 -060050import android.util.ArrayMap;
Adam Lesinski2cb761e2014-08-15 13:59:02 -070051import android.util.Log;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070052import android.util.Slog;
Adam Lesinskide898ff2014-01-29 18:20:45 -080053import android.util.SparseArray;
Jeff Browna492c3a2012-08-23 19:48:44 -070054import android.view.Display;
Jeff Sharkey8a372a02016-03-16 16:25:45 -060055import android.view.DisplayAdjustments;
Calin Juravle6ae39fc2018-01-19 20:32:47 -080056
Adam Lesinski4e862812016-11-21 16:02:24 -080057import com.android.internal.util.ArrayUtils;
Calin Juravle6ae39fc2018-01-19 20:32:47 -080058
Narayan Kamath7dba6eb2014-07-16 08:53:30 +010059import dalvik.system.VMRuntime;
Calin Juravle6ae39fc2018-01-19 20:32:47 -080060
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070061import java.io.File;
62import java.io.IOException;
63import java.io.InputStream;
64import java.lang.ref.WeakReference;
Adam Lesinski1e4663852014-08-15 14:47:28 -070065import java.lang.reflect.InvocationTargetException;
66import java.lang.reflect.Method;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070067import java.net.URL;
Jiyong Park29d9eba2018-05-04 12:44:38 +090068import java.nio.file.Paths;
Jeff Sharkey8a4c9722014-06-16 13:48:42 -070069import java.util.ArrayList;
Adam Lesinski4e862812016-11-21 16:02:24 -080070import java.util.Arrays;
Jeff Sharkey8a4c9722014-06-16 13:48:42 -070071import java.util.Collections;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070072import java.util.Enumeration;
Jeff Sharkey8a372a02016-03-16 16:25:45 -060073import java.util.List;
Narayan Kamath20531682014-07-14 13:18:43 +010074import java.util.Objects;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070075
76final class IntentReceiverLeaked extends AndroidRuntimeException {
Mathew Inwood4fb17d12018-08-14 14:25:44 +010077 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070078 public IntentReceiverLeaked(String msg) {
79 super(msg);
80 }
81}
82
83final class ServiceConnectionLeaked extends AndroidRuntimeException {
Mathew Inwood4fb17d12018-08-14 14:25:44 +010084 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070085 public ServiceConnectionLeaked(String msg) {
86 super(msg);
87 }
88}
89
90/**
91 * Local state maintained about a currently loaded .apk.
92 * @hide
93 */
Dianne Hackborn5fd21692011-06-07 14:09:47 -070094public final class LoadedApk {
Dianne Hackborn94846032017-03-31 17:55:23 -070095 static final String TAG = "LoadedApk";
96 static final boolean DEBUG = false;
Patrick Baumann1bea2372018-03-13 14:26:58 -070097 private static final String PROPERTY_NAME_APPEND_NATIVE = "pi.append_native_lib_paths";
Amith Yamasani742a6712011-05-04 14:49:28 -070098
Mathew Inwood4fb17d12018-08-14 14:25:44 +010099 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700100 private final ActivityThread mActivityThread;
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100101 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700102 final String mPackageName;
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100103 @UnsupportedAppUsage
Todd Kennedy39bfee52016-02-24 10:28:21 -0800104 private ApplicationInfo mApplicationInfo;
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100105 @UnsupportedAppUsage
Todd Kennedy39bfee52016-02-24 10:28:21 -0800106 private String mAppDir;
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100107 @UnsupportedAppUsage
Todd Kennedy39bfee52016-02-24 10:28:21 -0800108 private String mResDir;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800109 private String[] mOverlayDirs;
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100110 @UnsupportedAppUsage
Todd Kennedy39bfee52016-02-24 10:28:21 -0800111 private String mDataDir;
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100112 @UnsupportedAppUsage
Todd Kennedy39bfee52016-02-24 10:28:21 -0800113 private String mLibDir;
Mathew Inwood45d2c252018-09-14 12:35:36 +0100114 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Todd Kennedy39bfee52016-02-24 10:28:21 -0800115 private File mDataDirFile;
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600116 private File mDeviceProtectedDataDirFile;
117 private File mCredentialProtectedDataDirFile;
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100118 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700119 private final ClassLoader mBaseClassLoader;
120 private final boolean mSecurityViolation;
121 private final boolean mIncludeCode;
Dianne Hackbornfee756f2014-07-16 17:31:10 -0700122 private final boolean mRegisterPackage;
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100123 @UnsupportedAppUsage
Craig Mautner48d0d182013-06-11 07:53:06 -0700124 private final DisplayAdjustments mDisplayAdjustments = new DisplayAdjustments();
Todd Kennedy39bfee52016-02-24 10:28:21 -0800125 /** WARNING: This may change. Don't hold external references to it. */
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100126 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700127 Resources mResources;
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100128 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700129 private ClassLoader mClassLoader;
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100130 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700131 private Application mApplication;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700132
Adam Lesinski4e862812016-11-21 16:02:24 -0800133 private String[] mSplitNames;
134 private String[] mSplitAppDirs;
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100135 @UnsupportedAppUsage
Adam Lesinski4e862812016-11-21 16:02:24 -0800136 private String[] mSplitResDirs;
Narayan Kamathf9419f02017-06-15 11:35:38 +0100137 private String[] mSplitClassLoaderNames;
Adam Lesinski4e862812016-11-21 16:02:24 -0800138
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100139 @UnsupportedAppUsage
Dianne Hackbornadd005c2013-07-17 18:43:12 -0700140 private final ArrayMap<Context, ArrayMap<BroadcastReceiver, ReceiverDispatcher>> mReceivers
Adam Lesinski4e862812016-11-21 16:02:24 -0800141 = new ArrayMap<>();
Dianne Hackbornadd005c2013-07-17 18:43:12 -0700142 private final ArrayMap<Context, ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>> mUnregisteredReceivers
Adam Lesinski4e862812016-11-21 16:02:24 -0800143 = new ArrayMap<>();
Mathew Inwood45d2c252018-09-14 12:35:36 +0100144 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Dianne Hackbornadd005c2013-07-17 18:43:12 -0700145 private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mServices
Adam Lesinski4e862812016-11-21 16:02:24 -0800146 = new ArrayMap<>();
Dianne Hackbornadd005c2013-07-17 18:43:12 -0700147 private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mUnboundServices
Adam Lesinski4e862812016-11-21 16:02:24 -0800148 = new ArrayMap<>();
Jason Monka80bfb52017-11-16 17:15:37 -0500149 private AppComponentFactory mAppComponentFactory;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700150
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700151 Application getApplication() {
152 return mApplication;
153 }
154
Dianne Hackborn2f0b1752011-05-31 17:59:49 -0700155 /**
156 * Create information about a new .apk
157 *
158 * NOTE: This constructor is called with ActivityThread's lock held,
159 * so MUST NOT call back out to the activity manager.
160 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700161 public LoadedApk(ActivityThread activityThread, ApplicationInfo aInfo,
Jeff Browndefd4a62014-03-10 21:24:37 -0700162 CompatibilityInfo compatInfo, ClassLoader baseLoader,
Dianne Hackbornfee756f2014-07-16 17:31:10 -0700163 boolean securityViolation, boolean includeCode, boolean registerPackage) {
Narayan Kamath7dba6eb2014-07-16 08:53:30 +0100164
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700165 mActivityThread = activityThread;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800166 setApplicationInfo(aInfo);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700167 mPackageName = aInfo.packageName;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700168 mBaseClassLoader = baseLoader;
169 mSecurityViolation = securityViolation;
170 mIncludeCode = includeCode;
Dianne Hackbornfee756f2014-07-16 17:31:10 -0700171 mRegisterPackage = registerPackage;
Craig Mautner48d0d182013-06-11 07:53:06 -0700172 mDisplayAdjustments.setCompatibilityInfo(compatInfo);
Jason Monka80bfb52017-11-16 17:15:37 -0500173 mAppComponentFactory = createAppFactory(mApplicationInfo, mBaseClassLoader);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700174 }
175
Narayan Kamath7dba6eb2014-07-16 08:53:30 +0100176 private static ApplicationInfo adjustNativeLibraryPaths(ApplicationInfo info) {
177 // If we're dealing with a multi-arch application that has both
178 // 32 and 64 bit shared libraries, we might need to choose the secondary
179 // depending on what the current runtime's instruction set is.
180 if (info.primaryCpuAbi != null && info.secondaryCpuAbi != null) {
181 final String runtimeIsa = VMRuntime.getRuntime().vmInstructionSet();
jgu214741cd92014-12-17 17:23:29 -0500182
183 // Get the instruction set that the libraries of secondary Abi is supported.
184 // In presence of a native bridge this might be different than the one secondary Abi used.
185 String secondaryIsa = VMRuntime.getInstructionSet(info.secondaryCpuAbi);
186 final String secondaryDexCodeIsa = SystemProperties.get("ro.dalvik.vm.isa." + secondaryIsa);
187 secondaryIsa = secondaryDexCodeIsa.isEmpty() ? secondaryIsa : secondaryDexCodeIsa;
Narayan Kamath7dba6eb2014-07-16 08:53:30 +0100188
189 // If the runtimeIsa is the same as the primary isa, then we do nothing.
190 // Everything will be set up correctly because info.nativeLibraryDir will
191 // correspond to the right ISA.
192 if (runtimeIsa.equals(secondaryIsa)) {
193 final ApplicationInfo modified = new ApplicationInfo(info);
194 modified.nativeLibraryDir = modified.secondaryNativeLibraryDir;
Dmitriy Ivanove56b3f62015-06-05 22:00:13 -0700195 modified.primaryCpuAbi = modified.secondaryCpuAbi;
Narayan Kamath7dba6eb2014-07-16 08:53:30 +0100196 return modified;
197 }
198 }
199
200 return info;
201 }
202
Jeff Browndefd4a62014-03-10 21:24:37 -0700203 /**
204 * Create information about the system package.
205 * Must call {@link #installSystemApplicationInfo} later.
206 */
207 LoadedApk(ActivityThread activityThread) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700208 mActivityThread = activityThread;
Jeff Browndefd4a62014-03-10 21:24:37 -0700209 mApplicationInfo = new ApplicationInfo();
210 mApplicationInfo.packageName = "android";
211 mPackageName = "android";
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700212 mAppDir = null;
213 mResDir = null;
Jeff Sharkey8a4c9722014-06-16 13:48:42 -0700214 mSplitAppDirs = null;
215 mSplitResDirs = null;
Narayan Kamathf9419f02017-06-15 11:35:38 +0100216 mSplitClassLoaderNames = null;
MÃ¥rten Kongstad48d22322014-01-31 14:43:27 +0100217 mOverlayDirs = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700218 mDataDir = null;
219 mDataDirFile = null;
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600220 mDeviceProtectedDataDirFile = null;
221 mCredentialProtectedDataDirFile = null;
Kenny Root85387d72010-08-26 10:13:11 -0700222 mLibDir = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700223 mBaseClassLoader = null;
224 mSecurityViolation = false;
225 mIncludeCode = true;
Dianne Hackbornfee756f2014-07-16 17:31:10 -0700226 mRegisterPackage = false;
Jeff Browndefd4a62014-03-10 21:24:37 -0700227 mClassLoader = ClassLoader.getSystemClassLoader();
228 mResources = Resources.getSystem();
Jason Monka80bfb52017-11-16 17:15:37 -0500229 mAppComponentFactory = createAppFactory(mApplicationInfo, mClassLoader);
Jeff Browndefd4a62014-03-10 21:24:37 -0700230 }
231
232 /**
233 * Sets application info about the system package.
234 */
Narayan Kamath29564cd2014-08-07 10:57:40 +0100235 void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
Jeff Browndefd4a62014-03-10 21:24:37 -0700236 assert info.packageName.equals("android");
237 mApplicationInfo = info;
Narayan Kamath29564cd2014-08-07 10:57:40 +0100238 mClassLoader = classLoader;
Jason Monka80bfb52017-11-16 17:15:37 -0500239 mAppComponentFactory = createAppFactory(info, classLoader);
240 }
241
242 private AppComponentFactory createAppFactory(ApplicationInfo appInfo, ClassLoader cl) {
Jason Monk6ee51bb2018-03-02 11:20:31 -0500243 if (appInfo.appComponentFactory != null && cl != null) {
Jason Monka80bfb52017-11-16 17:15:37 -0500244 try {
245 return (AppComponentFactory) cl.loadClass(appInfo.appComponentFactory)
246 .newInstance();
247 } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
248 Slog.e(TAG, "Unable to instantiate appComponentFactory", e);
249 }
250 }
251 return AppComponentFactory.DEFAULT;
252 }
253
254 public AppComponentFactory getAppFactory() {
255 return mAppComponentFactory;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700256 }
257
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100258 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700259 public String getPackageName() {
260 return mPackageName;
261 }
262
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100263 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700264 public ApplicationInfo getApplicationInfo() {
265 return mApplicationInfo;
266 }
267
Jeff Sharkey369f5092016-02-29 11:16:21 -0700268 public int getTargetSdkVersion() {
269 return mApplicationInfo.targetSdkVersion;
270 }
271
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700272 public boolean isSecurityViolation() {
273 return mSecurityViolation;
274 }
275
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100276 @UnsupportedAppUsage
Craig Mautner48d0d182013-06-11 07:53:06 -0700277 public CompatibilityInfo getCompatibilityInfo() {
278 return mDisplayAdjustments.getCompatibilityInfo();
279 }
280
281 public void setCompatibilityInfo(CompatibilityInfo compatInfo) {
282 mDisplayAdjustments.setCompatibilityInfo(compatInfo);
283 }
284
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700285 /**
286 * Gets the array of shared libraries that are listed as
287 * used by the given package.
288 *
289 * @param packageName the name of the package (note: not its
290 * file name)
291 * @return null-ok; the array of shared libraries, each one
292 * a fully-qualified path
293 */
294 private static String[] getLibrariesFor(String packageName) {
295 ApplicationInfo ai = null;
296 try {
297 ai = ActivityThread.getPackageManager().getApplicationInfo(packageName,
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700298 PackageManager.GET_SHARED_LIBRARY_FILES, UserHandle.myUserId());
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700299 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700300 throw e.rethrowFromSystemServer();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700301 }
302
303 if (ai == null) {
304 return null;
305 }
306
307 return ai.sharedLibraryFiles;
308 }
309
Adam Lesinskid33ef562017-01-19 14:49:59 -0800310 /**
311 * Update the ApplicationInfo for an app. If oldPaths is null, all the paths are considered
312 * new.
313 * @param aInfo The new ApplicationInfo to use for this LoadedApk
314 * @param oldPaths The code paths for the old ApplicationInfo object. null means no paths can
315 * be reused.
316 */
317 public void updateApplicationInfo(@NonNull ApplicationInfo aInfo,
318 @Nullable List<String> oldPaths) {
Todd Kennedy39bfee52016-02-24 10:28:21 -0800319 setApplicationInfo(aInfo);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700320
Todd Kennedy39bfee52016-02-24 10:28:21 -0800321 final List<String> newPaths = new ArrayList<>();
Dimitry Ivanov638d8102017-02-22 15:39:42 -0800322 makePaths(mActivityThread, aInfo, newPaths);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800323 final List<String> addedPaths = new ArrayList<>(newPaths.size());
324
325 if (oldPaths != null) {
326 for (String path : newPaths) {
327 final String apkName = path.substring(path.lastIndexOf(File.separator));
328 boolean match = false;
329 for (String oldPath : oldPaths) {
Adam Lesinskia5ca6242017-03-01 15:45:12 -0800330 final String oldApkName = oldPath.substring(oldPath.lastIndexOf(File.separator));
Todd Kennedy39bfee52016-02-24 10:28:21 -0800331 if (apkName.equals(oldApkName)) {
332 match = true;
333 break;
334 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700335 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800336 if (!match) {
337 addedPaths.add(path);
338 }
339 }
340 } else {
341 addedPaths.addAll(newPaths);
342 }
343 synchronized (this) {
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700344 createOrUpdateClassLoaderLocked(addedPaths);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800345 if (mResources != null) {
Adam Lesinski4e862812016-11-21 16:02:24 -0800346 final String[] splitPaths;
347 try {
348 splitPaths = getSplitPaths(null);
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800349 } catch (NameNotFoundException e) {
Adam Lesinski4e862812016-11-21 16:02:24 -0800350 // This should NEVER fail.
351 throw new AssertionError("null split not found");
352 }
353
354 mResources = ResourcesManager.getInstance().getResources(null, mResDir,
Adam Lesinski0e618832017-02-07 11:40:12 -0800355 splitPaths, mOverlayDirs, mApplicationInfo.sharedLibraryFiles,
Adam Lesinski4e862812016-11-21 16:02:24 -0800356 Display.DEFAULT_DISPLAY, null, getCompatibilityInfo(),
357 getClassLoader());
Todd Kennedy39bfee52016-02-24 10:28:21 -0800358 }
359 }
Jason Monka80bfb52017-11-16 17:15:37 -0500360 mAppComponentFactory = createAppFactory(aInfo, mClassLoader);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800361 }
362
363 private void setApplicationInfo(ApplicationInfo aInfo) {
364 final int myUid = Process.myUid();
365 aInfo = adjustNativeLibraryPaths(aInfo);
366 mApplicationInfo = aInfo;
367 mAppDir = aInfo.sourceDir;
368 mResDir = aInfo.uid == myUid ? aInfo.sourceDir : aInfo.publicSourceDir;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800369 mOverlayDirs = aInfo.resourceDirs;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800370 mDataDir = aInfo.dataDir;
371 mLibDir = aInfo.nativeLibraryDir;
372 mDataDirFile = FileUtils.newFileOrNull(aInfo.dataDir);
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600373 mDeviceProtectedDataDirFile = FileUtils.newFileOrNull(aInfo.deviceProtectedDataDir);
374 mCredentialProtectedDataDirFile = FileUtils.newFileOrNull(aInfo.credentialProtectedDataDir);
Adam Lesinski4e862812016-11-21 16:02:24 -0800375
376 mSplitNames = aInfo.splitNames;
377 mSplitAppDirs = aInfo.splitSourceDirs;
378 mSplitResDirs = aInfo.uid == myUid ? aInfo.splitSourceDirs : aInfo.splitPublicSourceDirs;
Narayan Kamathf9419f02017-06-15 11:35:38 +0100379 mSplitClassLoaderNames = aInfo.splitClassLoaderNames;
Adam Lesinski4e862812016-11-21 16:02:24 -0800380
381 if (aInfo.requestsIsolatedSplitLoading() && !ArrayUtils.isEmpty(mSplitNames)) {
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800382 mSplitLoader = new SplitDependencyLoaderImpl(aInfo.splitDependencies);
Adam Lesinski4e862812016-11-21 16:02:24 -0800383 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800384 }
385
Dimitry Ivanov638d8102017-02-22 15:39:42 -0800386 public static void makePaths(ActivityThread activityThread,
387 ApplicationInfo aInfo,
388 List<String> outZipPaths) {
389 makePaths(activityThread, false, aInfo, outZipPaths, null);
390 }
391
392 public static void makePaths(ActivityThread activityThread,
393 boolean isBundledApp,
394 ApplicationInfo aInfo,
395 List<String> outZipPaths,
396 List<String> outLibPaths) {
Todd Kennedy39bfee52016-02-24 10:28:21 -0800397 final String appDir = aInfo.sourceDir;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800398 final String libDir = aInfo.nativeLibraryDir;
399 final String[] sharedLibraries = aInfo.sharedLibraryFiles;
400
401 outZipPaths.clear();
402 outZipPaths.add(appDir);
Adam Lesinski4e862812016-11-21 16:02:24 -0800403
404 // Do not load all available splits if the app requested isolated split loading.
405 if (aInfo.splitSourceDirs != null && !aInfo.requestsIsolatedSplitLoading()) {
406 Collections.addAll(outZipPaths, aInfo.splitSourceDirs);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800407 }
408
409 if (outLibPaths != null) {
410 outLibPaths.clear();
411 }
412
413 /*
414 * The following is a bit of a hack to inject
415 * instrumentation into the system: If the app
416 * being started matches one of the instrumentation names,
417 * then we combine both the "instrumentation" and
418 * "instrumented" app into the path, along with the
419 * concatenation of both apps' shared library lists.
420 */
421
Todd Kennedy39bfee52016-02-24 10:28:21 -0800422 String[] instrumentationLibs = null;
Torne (Richard Coles)3b6ca992016-10-10 15:11:36 +0100423 // activityThread will be null when called from the WebView zygote; just assume
424 // no instrumentation applies in this case.
425 if (activityThread != null) {
426 String instrumentationPackageName = activityThread.mInstrumentationPackageName;
427 String instrumentationAppDir = activityThread.mInstrumentationAppDir;
428 String[] instrumentationSplitAppDirs = activityThread.mInstrumentationSplitAppDirs;
429 String instrumentationLibDir = activityThread.mInstrumentationLibDir;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800430
Torne (Richard Coles)3b6ca992016-10-10 15:11:36 +0100431 String instrumentedAppDir = activityThread.mInstrumentedAppDir;
432 String[] instrumentedSplitAppDirs = activityThread.mInstrumentedSplitAppDirs;
433 String instrumentedLibDir = activityThread.mInstrumentedLibDir;
434
435 if (appDir.equals(instrumentationAppDir)
436 || appDir.equals(instrumentedAppDir)) {
437 outZipPaths.clear();
438 outZipPaths.add(instrumentationAppDir);
Adam Lesinski4e862812016-11-21 16:02:24 -0800439
440 // Only add splits if the app did not request isolated split loading.
441 if (!aInfo.requestsIsolatedSplitLoading()) {
442 if (instrumentationSplitAppDirs != null) {
443 Collections.addAll(outZipPaths, instrumentationSplitAppDirs);
444 }
445
446 if (!instrumentationAppDir.equals(instrumentedAppDir)) {
447 outZipPaths.add(instrumentedAppDir);
448 if (instrumentedSplitAppDirs != null) {
449 Collections.addAll(outZipPaths, instrumentedSplitAppDirs);
450 }
Torne (Richard Coles)3b6ca992016-10-10 15:11:36 +0100451 }
Jeff Haoc7b94822016-03-16 15:56:07 -0700452 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800453
Torne (Richard Coles)3b6ca992016-10-10 15:11:36 +0100454 if (outLibPaths != null) {
455 outLibPaths.add(instrumentationLibDir);
456 if (!instrumentationLibDir.equals(instrumentedLibDir)) {
457 outLibPaths.add(instrumentedLibDir);
458 }
459 }
460
461 if (!instrumentedAppDir.equals(instrumentationAppDir)) {
462 instrumentationLibs = getLibrariesFor(instrumentationPackageName);
463 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800464 }
465 }
466
467 if (outLibPaths != null) {
468 if (outLibPaths.isEmpty()) {
469 outLibPaths.add(libDir);
470 }
471
472 // Add path to libraries in apk for current abi. Do this now because more entries
473 // will be added to zipPaths that shouldn't be part of the library path.
474 if (aInfo.primaryCpuAbi != null) {
Alex Light20ed24f2016-04-20 14:07:43 -0700475 // Add fake libs into the library search path if we target prior to N.
Adam Lesinski4e862812016-11-21 16:02:24 -0800476 if (aInfo.targetSdkVersion < Build.VERSION_CODES.N) {
Alex Light20ed24f2016-04-20 14:07:43 -0700477 outLibPaths.add("/system/fake-libs" +
478 (VMRuntime.is64BitAbi(aInfo.primaryCpuAbi) ? "64" : ""));
479 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800480 for (String apk : outZipPaths) {
481 outLibPaths.add(apk + "!/lib/" + aInfo.primaryCpuAbi);
482 }
483 }
484
Dimitry Ivanov638d8102017-02-22 15:39:42 -0800485 if (isBundledApp) {
Todd Kennedy39bfee52016-02-24 10:28:21 -0800486 // Add path to system libraries to libPaths;
487 // Access to system libs should be limited
488 // to bundled applications; this is why updated
489 // system apps are not included.
490 outLibPaths.add(System.getProperty("java.library.path"));
491 }
492 }
493
Jeff Hao090892f2017-04-24 17:37:31 -0700494 // Prepend the shared libraries, maintaining their original order where possible.
Todd Kennedy39bfee52016-02-24 10:28:21 -0800495 if (sharedLibraries != null) {
Jeff Hao090892f2017-04-24 17:37:31 -0700496 int index = 0;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800497 for (String lib : sharedLibraries) {
498 if (!outZipPaths.contains(lib)) {
Jeff Hao090892f2017-04-24 17:37:31 -0700499 outZipPaths.add(index, lib);
500 index++;
Svetoslav Ganov40610e32017-06-20 19:35:51 -0700501 appendApkLibPathIfNeeded(lib, aInfo, outLibPaths);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800502 }
503 }
504 }
505
506 if (instrumentationLibs != null) {
507 for (String lib : instrumentationLibs) {
508 if (!outZipPaths.contains(lib)) {
509 outZipPaths.add(0, lib);
Svetoslav Ganov40610e32017-06-20 19:35:51 -0700510 appendApkLibPathIfNeeded(lib, aInfo, outLibPaths);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800511 }
512 }
513 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800514 }
515
Svetoslav Ganov40610e32017-06-20 19:35:51 -0700516 /**
517 * This method appends a path to the appropriate native library folder of a
518 * library if this library is hosted in an APK. This allows support for native
519 * shared libraries. The library API is determined based on the application
520 * ABI.
521 *
522 * @param path Path to the library.
523 * @param applicationInfo The application depending on the library.
524 * @param outLibPaths List to which to add the native lib path if needed.
525 */
526 private static void appendApkLibPathIfNeeded(@NonNull String path,
527 @NonNull ApplicationInfo applicationInfo, @Nullable List<String> outLibPaths) {
528 // Looking at the suffix is a little hacky but a safe and simple solution.
529 // We will be revisiting code in the next release and clean this up.
530 if (outLibPaths != null && applicationInfo.primaryCpuAbi != null && path.endsWith(".apk")) {
531 if (applicationInfo.targetSdkVersion >= Build.VERSION_CODES.O) {
532 outLibPaths.add(path + "!/lib/" + applicationInfo.primaryCpuAbi);
533 }
534 }
535 }
536
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800537 /*
538 * All indices received by the super class should be shifted by 1 when accessing mSplitNames,
539 * etc. The super class assumes the base APK is index 0, while the PackageManager APIs don't
540 * include the base APK in the list of splits.
541 */
542 private class SplitDependencyLoaderImpl extends SplitDependencyLoader<NameNotFoundException> {
Adam Lesinski4e862812016-11-21 16:02:24 -0800543 private final String[][] mCachedResourcePaths;
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800544 private final ClassLoader[] mCachedClassLoaders;
Adam Lesinski4e862812016-11-21 16:02:24 -0800545
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800546 SplitDependencyLoaderImpl(@NonNull SparseArray<int[]> dependencies) {
Adam Lesinski4e862812016-11-21 16:02:24 -0800547 super(dependencies);
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800548 mCachedResourcePaths = new String[mSplitNames.length + 1][];
549 mCachedClassLoaders = new ClassLoader[mSplitNames.length + 1];
Adam Lesinski4e862812016-11-21 16:02:24 -0800550 }
551
552 @Override
553 protected boolean isSplitCached(int splitIdx) {
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800554 return mCachedClassLoaders[splitIdx] != null;
Adam Lesinski4e862812016-11-21 16:02:24 -0800555 }
556
557 @Override
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800558 protected void constructSplit(int splitIdx, @NonNull int[] configSplitIndices,
559 int parentSplitIdx) throws NameNotFoundException {
Adam Lesinski4e862812016-11-21 16:02:24 -0800560 final ArrayList<String> splitPaths = new ArrayList<>();
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800561 if (splitIdx == 0) {
Adam Lesinski4e862812016-11-21 16:02:24 -0800562 createOrUpdateClassLoaderLocked(null);
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800563 mCachedClassLoaders[0] = mClassLoader;
564
565 // Never add the base resources here, they always get added no matter what.
566 for (int configSplitIdx : configSplitIndices) {
567 splitPaths.add(mSplitResDirs[configSplitIdx - 1]);
568 }
569 mCachedResourcePaths[0] = splitPaths.toArray(new String[splitPaths.size()]);
Adam Lesinski4e862812016-11-21 16:02:24 -0800570 return;
571 }
572
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800573 // Since we handled the special base case above, parentSplitIdx is always valid.
574 final ClassLoader parent = mCachedClassLoaders[parentSplitIdx];
575 mCachedClassLoaders[splitIdx] = ApplicationLoaders.getDefault().getClassLoader(
Narayan Kamathf9419f02017-06-15 11:35:38 +0100576 mSplitAppDirs[splitIdx - 1], getTargetSdkVersion(), false, null, null, parent,
577 mSplitClassLoaderNames[splitIdx - 1]);
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800578
579 Collections.addAll(splitPaths, mCachedResourcePaths[parentSplitIdx]);
580 splitPaths.add(mSplitResDirs[splitIdx - 1]);
581 for (int configSplitIdx : configSplitIndices) {
582 splitPaths.add(mSplitResDirs[configSplitIdx - 1]);
Adam Lesinski4e862812016-11-21 16:02:24 -0800583 }
Adam Lesinski4e862812016-11-21 16:02:24 -0800584 mCachedResourcePaths[splitIdx] = splitPaths.toArray(new String[splitPaths.size()]);
585 }
586
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800587 private int ensureSplitLoaded(String splitName) throws NameNotFoundException {
588 int idx = 0;
589 if (splitName != null) {
Adam Lesinski4e862812016-11-21 16:02:24 -0800590 idx = Arrays.binarySearch(mSplitNames, splitName);
591 if (idx < 0) {
592 throw new PackageManager.NameNotFoundException(
593 "Split name '" + splitName + "' is not installed");
594 }
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800595 idx += 1;
Adam Lesinski4e862812016-11-21 16:02:24 -0800596 }
Adam Lesinski4e862812016-11-21 16:02:24 -0800597 loadDependenciesForSplit(idx);
598 return idx;
599 }
600
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800601 ClassLoader getClassLoaderForSplit(String splitName) throws NameNotFoundException {
602 return mCachedClassLoaders[ensureSplitLoaded(splitName)];
Adam Lesinski4e862812016-11-21 16:02:24 -0800603 }
604
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800605 String[] getSplitPathsForSplit(String splitName) throws NameNotFoundException {
606 return mCachedResourcePaths[ensureSplitLoaded(splitName)];
Adam Lesinski4e862812016-11-21 16:02:24 -0800607 }
608 }
609
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800610 private SplitDependencyLoaderImpl mSplitLoader;
Adam Lesinski4e862812016-11-21 16:02:24 -0800611
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800612 ClassLoader getSplitClassLoader(String splitName) throws NameNotFoundException {
Adam Lesinski4e862812016-11-21 16:02:24 -0800613 if (mSplitLoader == null) {
614 return mClassLoader;
615 }
616 return mSplitLoader.getClassLoaderForSplit(splitName);
617 }
618
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800619 String[] getSplitPaths(String splitName) throws NameNotFoundException {
Adam Lesinski4e862812016-11-21 16:02:24 -0800620 if (mSplitLoader == null) {
621 return mSplitResDirs;
622 }
623 return mSplitLoader.getSplitPathsForSplit(splitName);
624 }
625
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700626 private void createOrUpdateClassLoaderLocked(List<String> addedPaths) {
627 if (mPackageName.equals("android")) {
Calin Juravle430ef452016-04-22 17:43:07 +0100628 // Note: This branch is taken for system server and we don't need to setup
629 // jit profiling support.
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700630 if (mClassLoader != null) {
631 // nothing to update
632 return;
Dimitry Ivanovb9c90262016-02-19 14:09:20 -0800633 }
634
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700635 if (mBaseClassLoader != null) {
636 mClassLoader = mBaseClassLoader;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800637 } else {
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700638 mClassLoader = ClassLoader.getSystemClassLoader();
Todd Kennedy39bfee52016-02-24 10:28:21 -0800639 }
Jason Monk6ee51bb2018-03-02 11:20:31 -0500640 mAppComponentFactory = createAppFactory(mApplicationInfo, mClassLoader);
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700641
642 return;
643 }
644
645 // Avoid the binder call when the package is the current application package.
646 // The activity manager will perform ensure that dexopt is performed before
647 // spinning up the process.
Narayan Kamathbf07e2a2017-03-15 11:37:32 +0000648 if (!Objects.equals(mPackageName, ActivityThread.currentPackageName()) && mIncludeCode) {
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700649 try {
Brian Carlstromca82e612016-04-19 23:16:08 -0700650 ActivityThread.getPackageManager().notifyPackageUse(mPackageName,
651 PackageManager.NOTIFY_PACKAGE_USE_CROSS_PACKAGE);
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700652 } catch (RemoteException re) {
653 throw re.rethrowFromSystemServer();
Todd Kennedy39bfee52016-02-24 10:28:21 -0800654 }
655 }
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700656
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700657 if (mRegisterPackage) {
658 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -0800659 ActivityManager.getService().addPackageDependency(mPackageName);
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700660 } catch (RemoteException e) {
661 throw e.rethrowFromSystemServer();
662 }
663 }
664
Andreas Gampea8a58ff2016-05-18 11:58:39 -0700665 // Lists for the elements of zip/code and native libraries.
666 //
667 // Both lists are usually not empty. We expect on average one APK for the zip component,
668 // but shared libraries and splits are not uncommon. We expect at least three elements
669 // for native libraries (app-based, system, vendor). As such, give both some breathing
670 // space and initialize to a small value (instead of incurring growth code).
671 final List<String> zipPaths = new ArrayList<>(10);
672 final List<String> libPaths = new ArrayList<>(10);
Narayan Kamath8995b002016-05-11 20:31:09 +0100673
Jiyong Parkfcad6962017-08-22 10:24:28 +0900674 boolean isBundledApp = mApplicationInfo.isSystemApp()
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700675 && !mApplicationInfo.isUpdatedSystemApp();
Dimitry Ivanovbf3b5f72016-05-03 11:34:58 -0700676
Jiyong Parkfcad6962017-08-22 10:24:28 +0900677 // Vendor apks are treated as bundled only when /vendor/lib is in the default search
678 // paths. If not, they are treated as unbundled; access to system libs is limited.
679 // Having /vendor/lib in the default search paths means that all system processes
680 // are allowed to use any vendor library, which in turn means that system is dependent
681 // on vendor partition. In the contrary, not having /vendor/lib in the default search
682 // paths mean that the two partitions are separated and thus we can treat vendor apks
683 // as unbundled.
684 final String defaultSearchPaths = System.getProperty("java.library.path");
685 final boolean treatVendorApkAsUnbundled = !defaultSearchPaths.contains("/vendor/lib");
Jiyong Park63495c22017-09-15 07:48:06 +0900686 if (mApplicationInfo.getCodePath() != null
Jiyong Park002fdbd2017-02-13 20:50:31 +0900687 && mApplicationInfo.isVendor() && treatVendorApkAsUnbundled) {
Jiyong Parkfcad6962017-08-22 10:24:28 +0900688 isBundledApp = false;
689 }
690
Dimitry Ivanov638d8102017-02-22 15:39:42 -0800691 makePaths(mActivityThread, isBundledApp, mApplicationInfo, zipPaths, libPaths);
692
Dimitry Ivanoveb96b002016-05-10 10:51:40 -0700693 String libraryPermittedPath = mDataDir;
Jiyong Park29d9eba2018-05-04 12:44:38 +0900694
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700695 if (isBundledApp) {
Jiyong Park29d9eba2018-05-04 12:44:38 +0900696 // For bundled apps, add the base directory of the app (e.g.,
697 // /system/app/Foo/) to the permitted paths so that it can load libraries
698 // embedded in module apks under the directory. For now, GmsCore is relying
699 // on this, but this isn't specific to the app. Also note that, we don't
700 // need to do this for unbundled apps as entire /data is already set to
701 // the permitted paths for them.
702 libraryPermittedPath += File.pathSeparator
703 + Paths.get(getAppDir()).getParent().toString();
704
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700705 // This is necessary to grant bundled apps access to
706 // libraries located in subdirectories of /system/lib
Jiyong Parkfcad6962017-08-22 10:24:28 +0900707 libraryPermittedPath += File.pathSeparator + defaultSearchPaths;
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700708 }
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700709
710 final String librarySearchPath = TextUtils.join(File.pathSeparator, libPaths);
711
Narayan Kamath8995b002016-05-11 20:31:09 +0100712 // If we're not asked to include code, we construct a classloader that has
713 // no code path included. We still need to set up the library search paths
714 // and permitted path because NativeActivity relies on it (it attempts to
715 // call System.loadLibrary() on a classloader from a LoadedApk with
716 // mIncludeCode == false).
717 if (!mIncludeCode) {
718 if (mClassLoader == null) {
719 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
720 mClassLoader = ApplicationLoaders.getDefault().getClassLoader(
Narayan Kamathf9419f02017-06-15 11:35:38 +0100721 "" /* codePath */, mApplicationInfo.targetSdkVersion, isBundledApp,
722 librarySearchPath, libraryPermittedPath, mBaseClassLoader,
723 null /* classLoaderName */);
Narayan Kamath8995b002016-05-11 20:31:09 +0100724 StrictMode.setThreadPolicy(oldPolicy);
Jason Monk2544c692018-05-15 11:30:09 -0400725 mAppComponentFactory = AppComponentFactory.DEFAULT;
Narayan Kamath8995b002016-05-11 20:31:09 +0100726 }
727
728 return;
729 }
730
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700731 /*
Narayan Kamath8995b002016-05-11 20:31:09 +0100732 * With all the combination done (if necessary, actually create the java class
733 * loader and set up JIT profiling support if necessary.
Andreas Gampea8a58ff2016-05-18 11:58:39 -0700734 *
735 * In many cases this is a single APK, so try to avoid the StringBuilder in TextUtils.
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700736 */
Andreas Gampea8a58ff2016-05-18 11:58:39 -0700737 final String zip = (zipPaths.size() == 1) ? zipPaths.get(0) :
738 TextUtils.join(File.pathSeparator, zipPaths);
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700739
Dianne Hackborn94846032017-03-31 17:55:23 -0700740 if (DEBUG) Slog.v(ActivityThread.TAG, "Class path: " + zip +
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700741 ", JNI path: " + librarySearchPath);
742
Calin Juravle430ef452016-04-22 17:43:07 +0100743 boolean needToSetupJitProfiles = false;
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700744 if (mClassLoader == null) {
745 // Temporarily disable logging of disk reads on the Looper thread
746 // as this is early and necessary.
747 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
748
749 mClassLoader = ApplicationLoaders.getDefault().getClassLoader(zip,
750 mApplicationInfo.targetSdkVersion, isBundledApp, librarySearchPath,
Narayan Kamathf9419f02017-06-15 11:35:38 +0100751 libraryPermittedPath, mBaseClassLoader,
752 mApplicationInfo.classLoaderName);
Jason Monk6ee51bb2018-03-02 11:20:31 -0500753 mAppComponentFactory = createAppFactory(mApplicationInfo, mClassLoader);
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700754
755 StrictMode.setThreadPolicy(oldPolicy);
Calin Juravle430ef452016-04-22 17:43:07 +0100756 // Setup the class loader paths for profiling.
757 needToSetupJitProfiles = true;
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700758 }
759
Patrick Baumann1bea2372018-03-13 14:26:58 -0700760 if (!libPaths.isEmpty() && SystemProperties.getBoolean(PROPERTY_NAME_APPEND_NATIVE, true)) {
Patrick Baumann5c5daa42018-05-09 11:12:49 -0700761 // Temporarily disable logging of disk reads on the Looper thread as this is necessary
762 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
763 try {
764 ApplicationLoaders.getDefault().addNative(mClassLoader, libPaths);
765 } finally {
766 StrictMode.setThreadPolicy(oldPolicy);
767 }
Patrick Baumann1bea2372018-03-13 14:26:58 -0700768 }
769
Jiyong Parkcfe38cd2018-06-04 15:05:29 +0900770 // /vendor/lib, /odm/lib and /product/lib are added to the native lib search
771 // paths of the classloader. Note that this is done AFTER the classloader is
772 // created by ApplicationLoaders.getDefault().getClassLoader(...). The
773 // reason is because if we have added the paths when creating the classloader
774 // above, the paths are also added to the search path of the linker namespace
775 // 'classloader-namespace', which will allow ALL libs in the paths to apps.
776 // Since only the libs listed in <partition>/etc/public.libraries.txt can be
777 // available to apps, we shouldn't add the paths then.
778 //
779 // However, we need to add the paths to the classloader (Java) though. This
780 // is because when a native lib is requested via System.loadLibrary(), the
781 // classloader first tries to find the requested lib in its own native libs
782 // search paths. If a lib is not found in one of the paths, dlopen() is not
783 // called at all. This can cause a problem that a vendor public native lib
784 // is accessible when directly opened via dlopen(), but inaccesible via
785 // System.loadLibrary(). In order to prevent the problem, we explicitly
786 // add the paths only to the classloader, and not to the native loader
787 // (linker namespace).
788 List<String> extraLibPaths = new ArrayList<>(3);
789 String abiSuffix = VMRuntime.getRuntime().is64Bit() ? "64" : "";
790 if (!defaultSearchPaths.contains("/vendor/lib")) {
791 extraLibPaths.add("/vendor/lib" + abiSuffix);
792 }
793 if (!defaultSearchPaths.contains("/odm/lib")) {
794 extraLibPaths.add("/odm/lib" + abiSuffix);
795 }
796 if (!defaultSearchPaths.contains("/product/lib")) {
797 extraLibPaths.add("/product/lib" + abiSuffix);
798 }
799 if (!extraLibPaths.isEmpty()) {
800 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
801 try {
802 ApplicationLoaders.getDefault().addNative(mClassLoader, extraLibPaths);
803 } finally {
804 StrictMode.setThreadPolicy(oldPolicy);
805 }
806 }
807
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700808 if (addedPaths != null && addedPaths.size() > 0) {
809 final String add = TextUtils.join(File.pathSeparator, addedPaths);
810 ApplicationLoaders.getDefault().addPath(mClassLoader, add);
Calin Juravle430ef452016-04-22 17:43:07 +0100811 // Setup the new code paths for profiling.
812 needToSetupJitProfiles = true;
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700813 }
Calin Juravle2a727d72016-04-15 19:33:46 +0100814
815 // Setup jit profile support.
Narayan Kamath2d4a2222016-04-25 19:16:56 +0100816 //
Calin Juravle2a727d72016-04-15 19:33:46 +0100817 // It is ok to call this multiple times if the application gets updated with new splits.
818 // The runtime only keeps track of unique code paths and can handle re-registration of
819 // the same code path. There's no need to pass `addedPaths` since any new code paths
820 // are already in `mApplicationInfo`.
Narayan Kamath2d4a2222016-04-25 19:16:56 +0100821 //
822 // It is NOT ok to call this function from the system_server (for any of the packages it
823 // loads code from) so we explicitly disallow it there.
824 if (needToSetupJitProfiles && !ActivityThread.isSystem()) {
Calin Juravle430ef452016-04-22 17:43:07 +0100825 setupJitProfileSupport();
Calin Juravle430ef452016-04-22 17:43:07 +0100826 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800827 }
828
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100829 @UnsupportedAppUsage
Todd Kennedy39bfee52016-02-24 10:28:21 -0800830 public ClassLoader getClassLoader() {
831 synchronized (this) {
832 if (mClassLoader == null) {
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700833 createOrUpdateClassLoaderLocked(null /*addedPaths*/);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800834 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700835 return mClassLoader;
836 }
837 }
838
Calin Juravle2a727d72016-04-15 19:33:46 +0100839 private void setupJitProfileSupport() {
840 if (!SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false)) {
841 return;
842 }
Calin Juravle126f7802016-05-24 15:23:47 +0100843 // Only set up profile support if the loaded apk has the same uid as the
844 // current process.
845 // Currently, we do not support profiling across different apps.
846 // (e.g. application's uid might be different when the code is
847 // loaded by another app via createApplicationContext)
848 if (mApplicationInfo.uid != Process.myUid()) {
849 return;
850 }
851
Calin Juravle2a727d72016-04-15 19:33:46 +0100852 final List<String> codePaths = new ArrayList<>();
853 if ((mApplicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0) {
854 codePaths.add(mApplicationInfo.sourceDir);
855 }
856 if (mApplicationInfo.splitSourceDirs != null) {
857 Collections.addAll(codePaths, mApplicationInfo.splitSourceDirs);
858 }
859
860 if (codePaths.isEmpty()) {
861 // If there are no code paths there's no need to setup a profile file and register with
862 // the runtime,
863 return;
864 }
865
Calin Juravle6ae39fc2018-01-19 20:32:47 -0800866 for (int i = codePaths.size() - 1; i >= 0; i--) {
867 String splitName = i == 0 ? null : mApplicationInfo.splitNames[i - 1];
868 String profileFile = ArtManager.getCurrentProfilePath(
869 mPackageName, UserHandle.myUserId(), splitName);
870 VMRuntime.registerAppInfo(profileFile, new String[] {codePaths.get(i)});
871 }
Calin Juravlef5a7bfc2017-03-13 23:30:30 -0700872
873 // Register the app data directory with the reporter. It will
874 // help deciding whether or not a dex file is the primary apk or a
875 // secondary dex.
876 DexLoadReporter.getInstance().registerAppDataDir(mPackageName, mDataDir);
Calin Juravle2a727d72016-04-15 19:33:46 +0100877 }
878
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700879 /**
880 * Setup value for Thread.getContextClassLoader(). If the
881 * package will not run in in a VM with other packages, we set
882 * the Java context ClassLoader to the
883 * PackageInfo.getClassLoader value. However, if this VM can
884 * contain multiple packages, we intead set the Java context
885 * ClassLoader to a proxy that will warn about the use of Java
886 * context ClassLoaders and then fall through to use the
887 * system ClassLoader.
888 *
889 * <p> Note that this is similar to but not the same as the
890 * android.content.Context.getClassLoader(). While both
891 * context class loaders are typically set to the
892 * PathClassLoader used to load the package archive in the
893 * single application per VM case, a single Android process
894 * may contain several Contexts executing on one thread with
895 * their own logical ClassLoaders while the Java context
896 * ClassLoader is a thread local. This is why in the case when
897 * we have multiple packages per VM we do not set the Java
898 * context ClassLoader to an arbitrary but instead warn the
899 * user to set their own if we detect that they are using a
900 * Java library that expects it to be set.
901 */
902 private void initializeJavaContextClassLoader() {
903 IPackageManager pm = ActivityThread.getPackageManager();
904 android.content.pm.PackageInfo pi;
905 try {
Jeff Sharkeyc7bacab2016-02-09 15:56:11 -0700906 pi = pm.getPackageInfo(mPackageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
907 UserHandle.myUserId());
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700908 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700909 throw e.rethrowFromSystemServer();
Dianne Hackborn208d9372013-02-25 13:17:54 -0800910 }
911 if (pi == null) {
912 throw new IllegalStateException("Unable to get package info for "
913 + mPackageName + "; is package not installed?");
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700914 }
915 /*
916 * Two possible indications that this package could be
917 * sharing its virtual machine with other packages:
918 *
919 * 1.) the sharedUserId attribute is set in the manifest,
920 * indicating a request to share a VM with other
921 * packages with the same sharedUserId.
922 *
923 * 2.) the application element of the manifest has an
924 * attribute specifying a non-default process name,
925 * indicating the desire to run in another packages VM.
926 */
927 boolean sharedUserIdSet = (pi.sharedUserId != null);
928 boolean processNameNotDefault =
929 (pi.applicationInfo != null &&
930 !mPackageName.equals(pi.applicationInfo.processName));
931 boolean sharable = (sharedUserIdSet || processNameNotDefault);
932 ClassLoader contextClassLoader =
933 (sharable)
934 ? new WarningContextClassLoader()
935 : mClassLoader;
936 Thread.currentThread().setContextClassLoader(contextClassLoader);
937 }
938
939 private static class WarningContextClassLoader extends ClassLoader {
940
941 private static boolean warned = false;
942
943 private void warn(String methodName) {
944 if (warned) {
945 return;
946 }
947 warned = true;
948 Thread.currentThread().setContextClassLoader(getParent());
949 Slog.w(ActivityThread.TAG, "ClassLoader." + methodName + ": " +
950 "The class loader returned by " +
951 "Thread.getContextClassLoader() may fail for processes " +
952 "that host multiple applications. You should explicitly " +
953 "specify a context class loader. For example: " +
954 "Thread.setContextClassLoader(getClass().getClassLoader());");
955 }
956
957 @Override public URL getResource(String resName) {
958 warn("getResource");
959 return getParent().getResource(resName);
960 }
961
962 @Override public Enumeration<URL> getResources(String resName) throws IOException {
963 warn("getResources");
964 return getParent().getResources(resName);
965 }
966
967 @Override public InputStream getResourceAsStream(String resName) {
968 warn("getResourceAsStream");
969 return getParent().getResourceAsStream(resName);
970 }
971
972 @Override public Class<?> loadClass(String className) throws ClassNotFoundException {
973 warn("loadClass");
974 return getParent().loadClass(className);
975 }
976
977 @Override public void setClassAssertionStatus(String cname, boolean enable) {
978 warn("setClassAssertionStatus");
979 getParent().setClassAssertionStatus(cname, enable);
980 }
981
982 @Override public void setPackageAssertionStatus(String pname, boolean enable) {
983 warn("setPackageAssertionStatus");
984 getParent().setPackageAssertionStatus(pname, enable);
985 }
986
987 @Override public void setDefaultAssertionStatus(boolean enable) {
988 warn("setDefaultAssertionStatus");
989 getParent().setDefaultAssertionStatus(enable);
990 }
991
992 @Override public void clearAssertionStatus() {
993 warn("clearAssertionStatus");
994 getParent().clearAssertionStatus();
995 }
996 }
997
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100998 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700999 public String getAppDir() {
1000 return mAppDir;
1001 }
1002
Brian Carlstromd893a892012-04-01 21:30:26 -07001003 public String getLibDir() {
1004 return mLibDir;
1005 }
1006
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001007 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001008 public String getResDir() {
1009 return mResDir;
1010 }
1011
Jeff Sharkey8a4c9722014-06-16 13:48:42 -07001012 public String[] getSplitAppDirs() {
1013 return mSplitAppDirs;
1014 }
1015
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001016 @UnsupportedAppUsage
Jeff Sharkey8a4c9722014-06-16 13:48:42 -07001017 public String[] getSplitResDirs() {
1018 return mSplitResDirs;
1019 }
1020
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001021 @UnsupportedAppUsage
MÃ¥rten Kongstad48d22322014-01-31 14:43:27 +01001022 public String[] getOverlayDirs() {
1023 return mOverlayDirs;
1024 }
1025
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001026 public String getDataDir() {
1027 return mDataDir;
1028 }
1029
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001030 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001031 public File getDataDirFile() {
1032 return mDataDirFile;
1033 }
1034
Jeff Sharkey8a372a02016-03-16 16:25:45 -06001035 public File getDeviceProtectedDataDirFile() {
1036 return mDeviceProtectedDataDirFile;
Jeff Sharkey15447792015-11-05 16:18:51 -08001037 }
1038
Jeff Sharkey8a372a02016-03-16 16:25:45 -06001039 public File getCredentialProtectedDataDirFile() {
1040 return mCredentialProtectedDataDirFile;
Jeff Sharkey15447792015-11-05 16:18:51 -08001041 }
1042
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001043 @UnsupportedAppUsage
Adam Lesinski4e862812016-11-21 16:02:24 -08001044 public AssetManager getAssets() {
1045 return getResources().getAssets();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001046 }
1047
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001048 @UnsupportedAppUsage
Adam Lesinski4e862812016-11-21 16:02:24 -08001049 public Resources getResources() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001050 if (mResources == null) {
Adam Lesinski4e862812016-11-21 16:02:24 -08001051 final String[] splitPaths;
1052 try {
1053 splitPaths = getSplitPaths(null);
Adam Lesinski1665d0f2017-03-10 14:46:57 -08001054 } catch (NameNotFoundException e) {
Adam Lesinski4e862812016-11-21 16:02:24 -08001055 // This should never fail.
1056 throw new AssertionError("null split not found");
1057 }
1058
Todd Kennedy233a0b12018-01-29 20:30:24 +00001059 mResources = ResourcesManager.getInstance().getResources(null, mResDir,
1060 splitPaths, mOverlayDirs, mApplicationInfo.sharedLibraryFiles,
1061 Display.DEFAULT_DISPLAY, null, getCompatibilityInfo(),
Adam Lesinski4e862812016-11-21 16:02:24 -08001062 getClassLoader());
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001063 }
1064 return mResources;
1065 }
1066
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001067 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001068 public Application makeApplication(boolean forceDefaultAppClass,
1069 Instrumentation instrumentation) {
1070 if (mApplication != null) {
1071 return mApplication;
1072 }
1073
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001074 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");
1075
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001076 Application app = null;
1077
1078 String appClass = mApplicationInfo.className;
1079 if (forceDefaultAppClass || (appClass == null)) {
1080 appClass = "android.app.Application";
1081 }
1082
1083 try {
1084 java.lang.ClassLoader cl = getClassLoader();
Narayan Kamath8091edb2014-10-15 11:38:44 +01001085 if (!mPackageName.equals("android")) {
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001086 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
1087 "initializeJavaContextClassLoader");
Narayan Kamath8091edb2014-10-15 11:38:44 +01001088 initializeJavaContextClassLoader();
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001089 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Narayan Kamath8091edb2014-10-15 11:38:44 +01001090 }
Jeff Browndefd4a62014-03-10 21:24:37 -07001091 ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001092 app = mActivityThread.mInstrumentation.newApplication(
1093 cl, appClass, appContext);
1094 appContext.setOuterContext(app);
1095 } catch (Exception e) {
1096 if (!mActivityThread.mInstrumentation.onException(app, e)) {
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001097 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001098 throw new RuntimeException(
1099 "Unable to instantiate application " + appClass
1100 + ": " + e.toString(), e);
1101 }
1102 }
1103 mActivityThread.mAllApplications.add(app);
1104 mApplication = app;
1105
1106 if (instrumentation != null) {
1107 try {
1108 instrumentation.callApplicationOnCreate(app);
1109 } catch (Exception e) {
1110 if (!instrumentation.onException(app, e)) {
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001111 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001112 throw new RuntimeException(
1113 "Unable to create application " + app.getClass().getName()
1114 + ": " + e.toString(), e);
1115 }
1116 }
1117 }
Adam Lesinskide898ff2014-01-29 18:20:45 -08001118
1119 // Rewrite the R 'constants' for all library apks.
Adam Lesinski4e862812016-11-21 16:02:24 -08001120 SparseArray<String> packageIdentifiers = getAssets().getAssignedPackageIdentifiers();
Adam Lesinskide898ff2014-01-29 18:20:45 -08001121 final int N = packageIdentifiers.size();
1122 for (int i = 0; i < N; i++) {
1123 final int id = packageIdentifiers.keyAt(i);
1124 if (id == 0x01 || id == 0x7f) {
1125 continue;
1126 }
1127
1128 rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);
1129 }
1130
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001131 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1132
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001133 return app;
1134 }
1135
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001136 @UnsupportedAppUsage
Adam Lesinskide898ff2014-01-29 18:20:45 -08001137 private void rewriteRValues(ClassLoader cl, String packageName, int id) {
Adam Lesinski2cb761e2014-08-15 13:59:02 -07001138 final Class<?> rClazz;
Adam Lesinskide898ff2014-01-29 18:20:45 -08001139 try {
Adam Lesinski2cb761e2014-08-15 13:59:02 -07001140 rClazz = cl.loadClass(packageName + ".R");
1141 } catch (ClassNotFoundException e) {
1142 // This is not necessarily an error, as some packages do not ship with resources
1143 // (or they do not need rewriting).
Adam Lesinski1e4663852014-08-15 14:47:28 -07001144 Log.i(TAG, "No resource references to update in package " + packageName);
Adam Lesinski2cb761e2014-08-15 13:59:02 -07001145 return;
1146 }
1147
Adam Lesinski1e4663852014-08-15 14:47:28 -07001148 final Method callback;
Adam Lesinski2cb761e2014-08-15 13:59:02 -07001149 try {
Adam Lesinski1e4663852014-08-15 14:47:28 -07001150 callback = rClazz.getMethod("onResourcesLoaded", int.class);
1151 } catch (NoSuchMethodException e) {
1152 // No rewriting to be done.
1153 return;
Adam Lesinskide898ff2014-01-29 18:20:45 -08001154 }
Adam Lesinski1e4663852014-08-15 14:47:28 -07001155
1156 Throwable cause;
1157 try {
1158 callback.invoke(null, id);
1159 return;
1160 } catch (IllegalAccessException e) {
1161 cause = e;
1162 } catch (InvocationTargetException e) {
1163 cause = e.getCause();
1164 }
1165
1166 throw new RuntimeException("Failed to rewrite resource references for " + packageName,
1167 cause);
Adam Lesinskide898ff2014-01-29 18:20:45 -08001168 }
1169
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001170 public void removeContextRegistrations(Context context,
1171 String who, String what) {
Jeff Sharkeyd7026f12012-03-01 20:50:32 -08001172 final boolean reportRegistrationLeaks = StrictMode.vmRegistrationLeaksEnabled();
Adam Lesinski23d40c42014-11-20 11:58:21 -08001173 synchronized (mReceivers) {
1174 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> rmap =
1175 mReceivers.remove(context);
1176 if (rmap != null) {
1177 for (int i = 0; i < rmap.size(); i++) {
1178 LoadedApk.ReceiverDispatcher rd = rmap.valueAt(i);
1179 IntentReceiverLeaked leak = new IntentReceiverLeaked(
1180 what + " " + who + " has leaked IntentReceiver "
1181 + rd.getIntentReceiver() + " that was " +
1182 "originally registered here. Are you missing a " +
1183 "call to unregisterReceiver()?");
1184 leak.setStackTrace(rd.getLocation().getStackTrace());
1185 Slog.e(ActivityThread.TAG, leak.getMessage(), leak);
1186 if (reportRegistrationLeaks) {
1187 StrictMode.onIntentReceiverLeaked(leak);
1188 }
1189 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001190 ActivityManager.getService().unregisterReceiver(
Adam Lesinski23d40c42014-11-20 11:58:21 -08001191 rd.getIIntentReceiver());
1192 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001193 throw e.rethrowFromSystemServer();
Adam Lesinski23d40c42014-11-20 11:58:21 -08001194 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001195 }
1196 }
Adam Lesinski23d40c42014-11-20 11:58:21 -08001197 mUnregisteredReceivers.remove(context);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001198 }
Adam Lesinski23d40c42014-11-20 11:58:21 -08001199
1200 synchronized (mServices) {
1201 //Slog.i(TAG, "Receiver registrations: " + mReceivers);
1202 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> smap =
1203 mServices.remove(context);
1204 if (smap != null) {
1205 for (int i = 0; i < smap.size(); i++) {
1206 LoadedApk.ServiceDispatcher sd = smap.valueAt(i);
1207 ServiceConnectionLeaked leak = new ServiceConnectionLeaked(
1208 what + " " + who + " has leaked ServiceConnection "
1209 + sd.getServiceConnection() + " that was originally bound here");
1210 leak.setStackTrace(sd.getLocation().getStackTrace());
1211 Slog.e(ActivityThread.TAG, leak.getMessage(), leak);
1212 if (reportRegistrationLeaks) {
1213 StrictMode.onServiceConnectionLeaked(leak);
1214 }
1215 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001216 ActivityManager.getService().unbindService(
Adam Lesinski23d40c42014-11-20 11:58:21 -08001217 sd.getIServiceConnection());
1218 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001219 throw e.rethrowFromSystemServer();
Adam Lesinski23d40c42014-11-20 11:58:21 -08001220 }
1221 sd.doForget();
Jeff Sharkeyd7026f12012-03-01 20:50:32 -08001222 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001223 }
Adam Lesinski23d40c42014-11-20 11:58:21 -08001224 mUnboundServices.remove(context);
1225 //Slog.i(TAG, "Service registrations: " + mServices);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001226 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001227 }
1228
1229 public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r,
1230 Context context, Handler handler,
1231 Instrumentation instrumentation, boolean registered) {
1232 synchronized (mReceivers) {
1233 LoadedApk.ReceiverDispatcher rd = null;
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001234 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001235 if (registered) {
1236 map = mReceivers.get(context);
1237 if (map != null) {
1238 rd = map.get(r);
1239 }
1240 }
1241 if (rd == null) {
1242 rd = new ReceiverDispatcher(r, context, handler,
1243 instrumentation, registered);
1244 if (registered) {
1245 if (map == null) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001246 map = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001247 mReceivers.put(context, map);
1248 }
1249 map.put(r, rd);
1250 }
1251 } else {
1252 rd.validate(context, handler);
1253 }
Dianne Hackbornc2d9c8e2011-01-24 21:59:21 -08001254 rd.mForgotten = false;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001255 return rd.getIIntentReceiver();
1256 }
1257 }
1258
1259 public IIntentReceiver forgetReceiverDispatcher(Context context,
1260 BroadcastReceiver r) {
1261 synchronized (mReceivers) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001262 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = mReceivers.get(context);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001263 LoadedApk.ReceiverDispatcher rd = null;
1264 if (map != null) {
1265 rd = map.get(r);
1266 if (rd != null) {
1267 map.remove(r);
1268 if (map.size() == 0) {
1269 mReceivers.remove(context);
1270 }
1271 if (r.getDebugUnregister()) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001272 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> holder
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001273 = mUnregisteredReceivers.get(context);
1274 if (holder == null) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001275 holder = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001276 mUnregisteredReceivers.put(context, holder);
1277 }
1278 RuntimeException ex = new IllegalArgumentException(
1279 "Originally unregistered here:");
1280 ex.fillInStackTrace();
1281 rd.setUnregisterLocation(ex);
1282 holder.put(r, rd);
1283 }
Dianne Hackbornc2d9c8e2011-01-24 21:59:21 -08001284 rd.mForgotten = true;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001285 return rd.getIIntentReceiver();
1286 }
1287 }
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001288 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> holder
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001289 = mUnregisteredReceivers.get(context);
1290 if (holder != null) {
1291 rd = holder.get(r);
1292 if (rd != null) {
1293 RuntimeException ex = rd.getUnregisterLocation();
1294 throw new IllegalArgumentException(
1295 "Unregistering Receiver " + r
1296 + " that was already unregistered", ex);
1297 }
1298 }
1299 if (context == null) {
1300 throw new IllegalStateException("Unbinding Receiver " + r
1301 + " from Context that is no longer in use: " + context);
1302 } else {
1303 throw new IllegalArgumentException("Receiver not registered: " + r);
1304 }
1305
1306 }
1307 }
1308
1309 static final class ReceiverDispatcher {
1310
1311 final static class InnerReceiver extends IIntentReceiver.Stub {
1312 final WeakReference<LoadedApk.ReceiverDispatcher> mDispatcher;
1313 final LoadedApk.ReceiverDispatcher mStrongRef;
1314
1315 InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) {
1316 mDispatcher = new WeakReference<LoadedApk.ReceiverDispatcher>(rd);
1317 mStrongRef = strong ? rd : null;
1318 }
Jeff Sharkeyd136e512016-03-09 22:30:56 -07001319
1320 @Override
Dianne Hackborn20e80982012-08-31 19:00:44 -07001321 public void performReceive(Intent intent, int resultCode, String data,
1322 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
Dianne Hackborn26756162016-05-17 13:40:44 -07001323 final LoadedApk.ReceiverDispatcher rd;
1324 if (intent == null) {
1325 Log.wtf(TAG, "Null intent received");
1326 rd = null;
1327 } else {
1328 rd = mDispatcher.get();
1329 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001330 if (ActivityThread.DEBUG_BROADCAST) {
1331 int seq = intent.getIntExtra("seq", -1);
Dianne Hackborn26756162016-05-17 13:40:44 -07001332 Slog.i(ActivityThread.TAG, "Receiving broadcast " + intent.getAction()
1333 + " seq=" + seq + " to " + (rd != null ? rd.mReceiver : null));
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001334 }
1335 if (rd != null) {
1336 rd.performReceive(intent, resultCode, data, extras,
Dianne Hackborn20e80982012-08-31 19:00:44 -07001337 ordered, sticky, sendingUser);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001338 } else {
1339 // The activity manager dispatched a broadcast to a registered
1340 // receiver in this process, but before it could be delivered the
1341 // receiver was unregistered. Acknowledge the broadcast on its
1342 // behalf so that the system's broadcast sequence can continue.
1343 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1344 "Finishing broadcast to unregistered receiver");
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001345 IActivityManager mgr = ActivityManager.getService();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001346 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001347 if (extras != null) {
1348 extras.setAllowFds(false);
1349 }
riddle_hsu1f5ac4d2015-01-03 15:38:21 +08001350 mgr.finishReceiver(this, resultCode, data, extras, false, intent.getFlags());
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001351 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001352 throw e.rethrowFromSystemServer();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001353 }
1354 }
1355 }
1356 }
1357
1358 final IIntentReceiver.Stub mIIntentReceiver;
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001359 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001360 final BroadcastReceiver mReceiver;
Mathew Inwood45d2c252018-09-14 12:35:36 +01001361 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001362 final Context mContext;
1363 final Handler mActivityThread;
1364 final Instrumentation mInstrumentation;
1365 final boolean mRegistered;
1366 final IntentReceiverLeaked mLocation;
1367 RuntimeException mUnregisterLocation;
Dianne Hackbornc2d9c8e2011-01-24 21:59:21 -08001368 boolean mForgotten;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001369
Makoto Onuki08408b92017-05-09 13:48:53 -07001370 final class Args extends BroadcastReceiver.PendingResult {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001371 private Intent mCurIntent;
Dianne Hackborne829fef2010-10-26 17:44:01 -07001372 private final boolean mOrdered;
Dianne Hackborn17c77532016-06-22 16:49:14 -07001373 private boolean mDispatched;
Makoto Onukif3bb6f32017-05-02 12:02:23 -07001374 private Throwable mPreviousRunStacktrace; // To investigate b/37809561. STOPSHIP remove.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001375
Dianne Hackborne829fef2010-10-26 17:44:01 -07001376 public Args(Intent intent, int resultCode, String resultData, Bundle resultExtras,
Dianne Hackborn20e80982012-08-31 19:00:44 -07001377 boolean ordered, boolean sticky, int sendingUser) {
Dianne Hackborne829fef2010-10-26 17:44:01 -07001378 super(resultCode, resultData, resultExtras,
riddle_hsu1f5ac4d2015-01-03 15:38:21 +08001379 mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED, ordered,
1380 sticky, mIIntentReceiver.asBinder(), sendingUser, intent.getFlags());
Dianne Hackborne829fef2010-10-26 17:44:01 -07001381 mCurIntent = intent;
1382 mOrdered = ordered;
1383 }
Dianne Hackborn17c77532016-06-22 16:49:14 -07001384
Makoto Onuki08408b92017-05-09 13:48:53 -07001385 public final Runnable getRunnable() {
1386 return () -> {
1387 final BroadcastReceiver receiver = mReceiver;
1388 final boolean ordered = mOrdered;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001389
Makoto Onuki08408b92017-05-09 13:48:53 -07001390 if (ActivityThread.DEBUG_BROADCAST) {
1391 int seq = mCurIntent.getIntExtra("seq", -1);
1392 Slog.i(ActivityThread.TAG, "Dispatching broadcast " + mCurIntent.getAction()
1393 + " seq=" + seq + " to " + mReceiver);
1394 Slog.i(ActivityThread.TAG, " mRegistered=" + mRegistered
1395 + " mOrderedHint=" + ordered);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001396 }
Makoto Onuki08408b92017-05-09 13:48:53 -07001397
1398 final IActivityManager mgr = ActivityManager.getService();
1399 final Intent intent = mCurIntent;
1400 if (intent == null) {
1401 Log.wtf(TAG, "Null intent being dispatched, mDispatched=" + mDispatched
1402 + ": run() previously called at "
1403 + Log.getStackTraceString(mPreviousRunStacktrace));
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001404 }
Makoto Onuki08408b92017-05-09 13:48:53 -07001405
1406 mCurIntent = null;
1407 mDispatched = true;
1408 mPreviousRunStacktrace = new Throwable("Previous stacktrace");
1409 if (receiver == null || intent == null || mForgotten) {
1410 if (mRegistered && ordered) {
1411 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1412 "Finishing null broadcast to " + mReceiver);
1413 sendFinished(mgr);
1414 }
1415 return;
1416 }
1417
1418 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveReg");
1419 try {
1420 ClassLoader cl = mReceiver.getClass().getClassLoader();
1421 intent.setExtrasClassLoader(cl);
1422 intent.prepareToEnterProcess();
1423 setExtrasClassLoader(cl);
1424 receiver.setPendingResult(this);
1425 receiver.onReceive(mContext, intent);
1426 } catch (Exception e) {
1427 if (mRegistered && ordered) {
1428 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1429 "Finishing failed broadcast to " + mReceiver);
1430 sendFinished(mgr);
1431 }
1432 if (mInstrumentation == null ||
1433 !mInstrumentation.onException(mReceiver, e)) {
1434 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1435 throw new RuntimeException(
1436 "Error receiving broadcast " + intent
1437 + " in " + mReceiver, e);
1438 }
1439 }
1440
1441 if (receiver.getPendingResult() != null) {
1442 finish();
1443 }
1444 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1445 };
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001446 }
1447 }
1448
1449 ReceiverDispatcher(BroadcastReceiver receiver, Context context,
1450 Handler activityThread, Instrumentation instrumentation,
1451 boolean registered) {
1452 if (activityThread == null) {
1453 throw new NullPointerException("Handler must not be null");
1454 }
1455
1456 mIIntentReceiver = new InnerReceiver(this, !registered);
1457 mReceiver = receiver;
1458 mContext = context;
1459 mActivityThread = activityThread;
1460 mInstrumentation = instrumentation;
1461 mRegistered = registered;
1462 mLocation = new IntentReceiverLeaked(null);
1463 mLocation.fillInStackTrace();
1464 }
1465
1466 void validate(Context context, Handler activityThread) {
1467 if (mContext != context) {
1468 throw new IllegalStateException(
1469 "Receiver " + mReceiver +
1470 " registered with differing Context (was " +
1471 mContext + " now " + context + ")");
1472 }
1473 if (mActivityThread != activityThread) {
1474 throw new IllegalStateException(
1475 "Receiver " + mReceiver +
1476 " registered with differing handler (was " +
1477 mActivityThread + " now " + activityThread + ")");
1478 }
1479 }
1480
1481 IntentReceiverLeaked getLocation() {
1482 return mLocation;
1483 }
1484
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001485 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001486 BroadcastReceiver getIntentReceiver() {
1487 return mReceiver;
1488 }
1489
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001490 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001491 IIntentReceiver getIIntentReceiver() {
1492 return mIIntentReceiver;
1493 }
1494
1495 void setUnregisterLocation(RuntimeException ex) {
1496 mUnregisterLocation = ex;
1497 }
1498
1499 RuntimeException getUnregisterLocation() {
1500 return mUnregisterLocation;
1501 }
1502
Dianne Hackborn20e80982012-08-31 19:00:44 -07001503 public void performReceive(Intent intent, int resultCode, String data,
1504 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
Dianne Hackborn41bfaf82016-06-08 16:33:29 -07001505 final Args args = new Args(intent, resultCode, data, extras, ordered,
Dianne Hackborn20e80982012-08-31 19:00:44 -07001506 sticky, sendingUser);
Dianne Hackborn41bfaf82016-06-08 16:33:29 -07001507 if (intent == null) {
1508 Log.wtf(TAG, "Null intent received");
1509 } else {
1510 if (ActivityThread.DEBUG_BROADCAST) {
1511 int seq = intent.getIntExtra("seq", -1);
1512 Slog.i(ActivityThread.TAG, "Enqueueing broadcast " + intent.getAction()
1513 + " seq=" + seq + " to " + mReceiver);
1514 }
1515 }
Makoto Onuki08408b92017-05-09 13:48:53 -07001516 if (intent == null || !mActivityThread.post(args.getRunnable())) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001517 if (mRegistered && ordered) {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001518 IActivityManager mgr = ActivityManager.getService();
Dianne Hackborne829fef2010-10-26 17:44:01 -07001519 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1520 "Finishing sync broadcast to " + mReceiver);
1521 args.sendFinished(mgr);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001522 }
1523 }
1524 }
1525
1526 }
1527
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001528 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001529 public final IServiceConnection getServiceDispatcher(ServiceConnection c,
1530 Context context, Handler handler, int flags) {
1531 synchronized (mServices) {
1532 LoadedApk.ServiceDispatcher sd = null;
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001533 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001534 if (map != null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001535 if (DEBUG) Slog.d(TAG, "Returning existing dispatcher " + sd + " for conn " + c);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001536 sd = map.get(c);
1537 }
1538 if (sd == null) {
1539 sd = new ServiceDispatcher(c, context, handler, flags);
Dianne Hackborn94846032017-03-31 17:55:23 -07001540 if (DEBUG) Slog.d(TAG, "Creating new dispatcher " + sd + " for conn " + c);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001541 if (map == null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001542 map = new ArrayMap<>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001543 mServices.put(context, map);
1544 }
1545 map.put(c, sd);
1546 } else {
1547 sd.validate(context, handler);
1548 }
1549 return sd.getIServiceConnection();
1550 }
1551 }
1552
1553 public final IServiceConnection forgetServiceDispatcher(Context context,
1554 ServiceConnection c) {
1555 synchronized (mServices) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001556 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001557 = mServices.get(context);
1558 LoadedApk.ServiceDispatcher sd = null;
1559 if (map != null) {
1560 sd = map.get(c);
1561 if (sd != null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001562 if (DEBUG) Slog.d(TAG, "Removing dispatcher " + sd + " for conn " + c);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001563 map.remove(c);
1564 sd.doForget();
1565 if (map.size() == 0) {
1566 mServices.remove(context);
1567 }
1568 if ((sd.getFlags()&Context.BIND_DEBUG_UNBIND) != 0) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001569 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> holder
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001570 = mUnboundServices.get(context);
1571 if (holder == null) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001572 holder = new ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001573 mUnboundServices.put(context, holder);
1574 }
1575 RuntimeException ex = new IllegalArgumentException(
1576 "Originally unbound here:");
1577 ex.fillInStackTrace();
1578 sd.setUnbindLocation(ex);
1579 holder.put(c, sd);
1580 }
1581 return sd.getIServiceConnection();
1582 }
1583 }
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001584 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> holder
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001585 = mUnboundServices.get(context);
1586 if (holder != null) {
1587 sd = holder.get(c);
1588 if (sd != null) {
1589 RuntimeException ex = sd.getUnbindLocation();
1590 throw new IllegalArgumentException(
1591 "Unbinding Service " + c
1592 + " that was already unbound", ex);
1593 }
1594 }
1595 if (context == null) {
1596 throw new IllegalStateException("Unbinding Service " + c
1597 + " from Context that is no longer in use: " + context);
1598 } else {
1599 throw new IllegalArgumentException("Service not registered: " + c);
1600 }
1601 }
1602 }
1603
1604 static final class ServiceDispatcher {
1605 private final ServiceDispatcher.InnerConnection mIServiceConnection;
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001606 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001607 private final ServiceConnection mConnection;
Mathew Inwood45d2c252018-09-14 12:35:36 +01001608 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001609 private final Context mContext;
1610 private final Handler mActivityThread;
1611 private final ServiceConnectionLeaked mLocation;
1612 private final int mFlags;
1613
1614 private RuntimeException mUnbindLocation;
1615
Dianne Hackborn5a6ef732011-11-11 12:31:52 -08001616 private boolean mForgotten;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001617
1618 private static class ConnectionInfo {
1619 IBinder binder;
1620 IBinder.DeathRecipient deathMonitor;
1621 }
1622
1623 private static class InnerConnection extends IServiceConnection.Stub {
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001624 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001625 final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;
1626
1627 InnerConnection(LoadedApk.ServiceDispatcher sd) {
1628 mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
1629 }
1630
Dianne Hackborn94846032017-03-31 17:55:23 -07001631 public void connected(ComponentName name, IBinder service, boolean dead)
1632 throws RemoteException {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001633 LoadedApk.ServiceDispatcher sd = mDispatcher.get();
1634 if (sd != null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001635 sd.connected(name, service, dead);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001636 }
1637 }
1638 }
1639
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001640 private final ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo> mActiveConnections
1641 = new ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001642
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001643 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001644 ServiceDispatcher(ServiceConnection conn,
1645 Context context, Handler activityThread, int flags) {
1646 mIServiceConnection = new InnerConnection(this);
1647 mConnection = conn;
1648 mContext = context;
1649 mActivityThread = activityThread;
1650 mLocation = new ServiceConnectionLeaked(null);
1651 mLocation.fillInStackTrace();
1652 mFlags = flags;
1653 }
1654
1655 void validate(Context context, Handler activityThread) {
1656 if (mContext != context) {
1657 throw new RuntimeException(
1658 "ServiceConnection " + mConnection +
1659 " registered with differing Context (was " +
1660 mContext + " now " + context + ")");
1661 }
1662 if (mActivityThread != activityThread) {
1663 throw new RuntimeException(
1664 "ServiceConnection " + mConnection +
1665 " registered with differing handler (was " +
1666 mActivityThread + " now " + activityThread + ")");
1667 }
1668 }
1669
1670 void doForget() {
1671 synchronized(this) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001672 for (int i=0; i<mActiveConnections.size(); i++) {
1673 ServiceDispatcher.ConnectionInfo ci = mActiveConnections.valueAt(i);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001674 ci.binder.unlinkToDeath(ci.deathMonitor, 0);
1675 }
1676 mActiveConnections.clear();
Dianne Hackborn5a6ef732011-11-11 12:31:52 -08001677 mForgotten = true;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001678 }
1679 }
1680
1681 ServiceConnectionLeaked getLocation() {
1682 return mLocation;
1683 }
1684
1685 ServiceConnection getServiceConnection() {
1686 return mConnection;
1687 }
1688
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001689 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001690 IServiceConnection getIServiceConnection() {
1691 return mIServiceConnection;
1692 }
1693
1694 int getFlags() {
1695 return mFlags;
1696 }
1697
1698 void setUnbindLocation(RuntimeException ex) {
1699 mUnbindLocation = ex;
1700 }
1701
1702 RuntimeException getUnbindLocation() {
1703 return mUnbindLocation;
1704 }
1705
Dianne Hackborn94846032017-03-31 17:55:23 -07001706 public void connected(ComponentName name, IBinder service, boolean dead) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001707 if (mActivityThread != null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001708 mActivityThread.post(new RunConnection(name, service, 0, dead));
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001709 } else {
Dianne Hackborn94846032017-03-31 17:55:23 -07001710 doConnected(name, service, dead);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001711 }
1712 }
1713
1714 public void death(ComponentName name, IBinder service) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001715 if (mActivityThread != null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001716 mActivityThread.post(new RunConnection(name, service, 1, false));
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001717 } else {
1718 doDeath(name, service);
1719 }
1720 }
1721
Dianne Hackborn94846032017-03-31 17:55:23 -07001722 public void doConnected(ComponentName name, IBinder service, boolean dead) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001723 ServiceDispatcher.ConnectionInfo old;
1724 ServiceDispatcher.ConnectionInfo info;
1725
1726 synchronized (this) {
Dianne Hackborn5a6ef732011-11-11 12:31:52 -08001727 if (mForgotten) {
1728 // We unbound before receiving the connection; ignore
1729 // any connection received.
1730 return;
1731 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001732 old = mActiveConnections.get(name);
1733 if (old != null && old.binder == service) {
1734 // Huh, already have this one. Oh well!
1735 return;
1736 }
1737
1738 if (service != null) {
1739 // A new service is being connected... set it all up.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001740 info = new ConnectionInfo();
1741 info.binder = service;
1742 info.deathMonitor = new DeathMonitor(name, service);
1743 try {
1744 service.linkToDeath(info.deathMonitor, 0);
1745 mActiveConnections.put(name, info);
1746 } catch (RemoteException e) {
1747 // This service was dead before we got it... just
1748 // don't do anything with it.
1749 mActiveConnections.remove(name);
1750 return;
1751 }
1752
1753 } else {
1754 // The named service is being disconnected... clean up.
1755 mActiveConnections.remove(name);
1756 }
1757
1758 if (old != null) {
1759 old.binder.unlinkToDeath(old.deathMonitor, 0);
1760 }
1761 }
1762
Adrian Roosa9b43182016-07-21 13:20:38 -07001763 // If there was an old service, it is now disconnected.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001764 if (old != null) {
1765 mConnection.onServiceDisconnected(name);
1766 }
Dianne Hackborn94846032017-03-31 17:55:23 -07001767 if (dead) {
Dianne Hackbornac265342017-04-19 14:53:18 -07001768 mConnection.onBindingDied(name);
Dianne Hackborn94846032017-03-31 17:55:23 -07001769 }
Christopher Tate5d73b6d2017-10-06 16:15:34 -07001770 // If there is a new viable service, it is now connected.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001771 if (service != null) {
1772 mConnection.onServiceConnected(name, service);
Christopher Tate5d73b6d2017-10-06 16:15:34 -07001773 } else {
1774 // The binding machinery worked, but the remote returned null from onBind().
1775 mConnection.onNullBinding(name);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001776 }
1777 }
1778
1779 public void doDeath(ComponentName name, IBinder service) {
Adrian Roosa9b43182016-07-21 13:20:38 -07001780 synchronized (this) {
1781 ConnectionInfo old = mActiveConnections.get(name);
1782 if (old == null || old.binder != service) {
1783 // Death for someone different than who we last
1784 // reported... just ignore it.
1785 return;
1786 }
1787 mActiveConnections.remove(name);
1788 old.binder.unlinkToDeath(old.deathMonitor, 0);
1789 }
1790
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001791 mConnection.onServiceDisconnected(name);
1792 }
1793
1794 private final class RunConnection implements Runnable {
Dianne Hackborn94846032017-03-31 17:55:23 -07001795 RunConnection(ComponentName name, IBinder service, int command, boolean dead) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001796 mName = name;
1797 mService = service;
1798 mCommand = command;
Dianne Hackborn94846032017-03-31 17:55:23 -07001799 mDead = dead;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001800 }
1801
1802 public void run() {
1803 if (mCommand == 0) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001804 doConnected(mName, mService, mDead);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001805 } else if (mCommand == 1) {
1806 doDeath(mName, mService);
1807 }
1808 }
1809
1810 final ComponentName mName;
1811 final IBinder mService;
1812 final int mCommand;
Dianne Hackborn94846032017-03-31 17:55:23 -07001813 final boolean mDead;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001814 }
1815
1816 private final class DeathMonitor implements IBinder.DeathRecipient
1817 {
1818 DeathMonitor(ComponentName name, IBinder service) {
1819 mName = name;
1820 mService = service;
1821 }
1822
1823 public void binderDied() {
1824 death(mName, mService);
1825 }
1826
1827 final ComponentName mName;
1828 final IBinder mService;
1829 }
1830 }
1831}