blob: 3f1075448c847aaaa1a93fe599935ec53a52d48b [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;
Nicolas Geoffray972b39e2018-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
Narayan Kamath7dba6eb2014-07-16 08:53:30 +010060import dalvik.system.VMRuntime;
Calin Juravle6ae39fc2018-01-19 20:32:47 -080061
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070062import java.io.File;
63import java.io.IOException;
64import java.io.InputStream;
65import java.lang.ref.WeakReference;
Adam Lesinski1e4663852014-08-15 14:47:28 -070066import java.lang.reflect.InvocationTargetException;
67import java.lang.reflect.Method;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070068import java.net.URL;
Jiyong Park29d9eba2018-05-04 12:44:38 +090069import java.nio.file.Paths;
Jeff Sharkey8a4c9722014-06-16 13:48:42 -070070import java.util.ArrayList;
Adam Lesinski4e862812016-11-21 16:02:24 -080071import java.util.Arrays;
Jeff Sharkey8a4c9722014-06-16 13:48:42 -070072import java.util.Collections;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070073import java.util.Enumeration;
Nicolas Geoffray972b39e2018-11-15 12:59:52 +000074import java.util.LinkedHashSet;
Jeff Sharkey8a372a02016-03-16 16:25:45 -060075import java.util.List;
Narayan Kamath20531682014-07-14 13:18:43 +010076import java.util.Objects;
Nicolas Geoffray972b39e2018-11-15 12:59:52 +000077import java.util.Set;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070078
79final class IntentReceiverLeaked extends AndroidRuntimeException {
Mathew Inwood4fb17d12018-08-14 14:25:44 +010080 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070081 public IntentReceiverLeaked(String msg) {
82 super(msg);
83 }
84}
85
86final class ServiceConnectionLeaked extends AndroidRuntimeException {
Mathew Inwood4fb17d12018-08-14 14:25:44 +010087 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070088 public ServiceConnectionLeaked(String msg) {
89 super(msg);
90 }
91}
92
93/**
94 * Local state maintained about a currently loaded .apk.
95 * @hide
96 */
Dianne Hackborn5fd21692011-06-07 14:09:47 -070097public final class LoadedApk {
Dianne Hackborn94846032017-03-31 17:55:23 -070098 static final String TAG = "LoadedApk";
99 static final boolean DEBUG = false;
Patrick Baumann1bea2372018-03-13 14:26:58 -0700100 private static final String PROPERTY_NAME_APPEND_NATIVE = "pi.append_native_lib_paths";
Amith Yamasani742a6712011-05-04 14:49:28 -0700101
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100102 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700103 private final ActivityThread mActivityThread;
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100104 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700105 final String mPackageName;
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100106 @UnsupportedAppUsage
Todd Kennedy39bfee52016-02-24 10:28:21 -0800107 private ApplicationInfo mApplicationInfo;
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100108 @UnsupportedAppUsage
Todd Kennedy39bfee52016-02-24 10:28:21 -0800109 private String mAppDir;
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100110 @UnsupportedAppUsage
Todd Kennedy39bfee52016-02-24 10:28:21 -0800111 private String mResDir;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800112 private String[] mOverlayDirs;
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100113 @UnsupportedAppUsage
Todd Kennedy39bfee52016-02-24 10:28:21 -0800114 private String mDataDir;
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100115 @UnsupportedAppUsage
Todd Kennedy39bfee52016-02-24 10:28:21 -0800116 private String mLibDir;
Mathew Inwood45d2c252018-09-14 12:35:36 +0100117 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Todd Kennedy39bfee52016-02-24 10:28:21 -0800118 private File mDataDirFile;
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600119 private File mDeviceProtectedDataDirFile;
120 private File mCredentialProtectedDataDirFile;
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100121 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700122 private final ClassLoader mBaseClassLoader;
David Brazdilb319ccf2018-10-25 14:07:51 +0100123 private ClassLoader mDefaultClassLoader;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700124 private final boolean mSecurityViolation;
125 private final boolean mIncludeCode;
Dianne Hackbornfee756f2014-07-16 17:31:10 -0700126 private final boolean mRegisterPackage;
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100127 @UnsupportedAppUsage
Craig Mautner48d0d182013-06-11 07:53:06 -0700128 private final DisplayAdjustments mDisplayAdjustments = new DisplayAdjustments();
Todd Kennedy39bfee52016-02-24 10:28:21 -0800129 /** WARNING: This may change. Don't hold external references to it. */
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100130 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700131 Resources mResources;
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100132 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700133 private ClassLoader mClassLoader;
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100134 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700135 private Application mApplication;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700136
Adam Lesinski4e862812016-11-21 16:02:24 -0800137 private String[] mSplitNames;
138 private String[] mSplitAppDirs;
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100139 @UnsupportedAppUsage
Adam Lesinski4e862812016-11-21 16:02:24 -0800140 private String[] mSplitResDirs;
Narayan Kamathf9419f02017-06-15 11:35:38 +0100141 private String[] mSplitClassLoaderNames;
Adam Lesinski4e862812016-11-21 16:02:24 -0800142
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100143 @UnsupportedAppUsage
Dianne Hackbornadd005c2013-07-17 18:43:12 -0700144 private final ArrayMap<Context, ArrayMap<BroadcastReceiver, ReceiverDispatcher>> mReceivers
Adam Lesinski4e862812016-11-21 16:02:24 -0800145 = new ArrayMap<>();
Dianne Hackbornadd005c2013-07-17 18:43:12 -0700146 private final ArrayMap<Context, ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>> mUnregisteredReceivers
Adam Lesinski4e862812016-11-21 16:02:24 -0800147 = new ArrayMap<>();
Mathew Inwood45d2c252018-09-14 12:35:36 +0100148 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Dianne Hackbornadd005c2013-07-17 18:43:12 -0700149 private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mServices
Adam Lesinski4e862812016-11-21 16:02:24 -0800150 = new ArrayMap<>();
Dianne Hackbornadd005c2013-07-17 18:43:12 -0700151 private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mUnboundServices
Adam Lesinski4e862812016-11-21 16:02:24 -0800152 = new ArrayMap<>();
Jason Monka80bfb52017-11-16 17:15:37 -0500153 private AppComponentFactory mAppComponentFactory;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700154
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700155 Application getApplication() {
156 return mApplication;
157 }
158
Dianne Hackborn2f0b1752011-05-31 17:59:49 -0700159 /**
160 * Create information about a new .apk
161 *
162 * NOTE: This constructor is called with ActivityThread's lock held,
163 * so MUST NOT call back out to the activity manager.
164 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700165 public LoadedApk(ActivityThread activityThread, ApplicationInfo aInfo,
Jeff Browndefd4a62014-03-10 21:24:37 -0700166 CompatibilityInfo compatInfo, ClassLoader baseLoader,
Dianne Hackbornfee756f2014-07-16 17:31:10 -0700167 boolean securityViolation, boolean includeCode, boolean registerPackage) {
Narayan Kamath7dba6eb2014-07-16 08:53:30 +0100168
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700169 mActivityThread = activityThread;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800170 setApplicationInfo(aInfo);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700171 mPackageName = aInfo.packageName;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700172 mBaseClassLoader = baseLoader;
173 mSecurityViolation = securityViolation;
174 mIncludeCode = includeCode;
Dianne Hackbornfee756f2014-07-16 17:31:10 -0700175 mRegisterPackage = registerPackage;
Craig Mautner48d0d182013-06-11 07:53:06 -0700176 mDisplayAdjustments.setCompatibilityInfo(compatInfo);
Jason Monka80bfb52017-11-16 17:15:37 -0500177 mAppComponentFactory = createAppFactory(mApplicationInfo, mBaseClassLoader);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700178 }
179
Narayan Kamath7dba6eb2014-07-16 08:53:30 +0100180 private static ApplicationInfo adjustNativeLibraryPaths(ApplicationInfo info) {
181 // If we're dealing with a multi-arch application that has both
182 // 32 and 64 bit shared libraries, we might need to choose the secondary
183 // depending on what the current runtime's instruction set is.
184 if (info.primaryCpuAbi != null && info.secondaryCpuAbi != null) {
185 final String runtimeIsa = VMRuntime.getRuntime().vmInstructionSet();
jgu214741cd92014-12-17 17:23:29 -0500186
187 // Get the instruction set that the libraries of secondary Abi is supported.
188 // In presence of a native bridge this might be different than the one secondary Abi used.
189 String secondaryIsa = VMRuntime.getInstructionSet(info.secondaryCpuAbi);
190 final String secondaryDexCodeIsa = SystemProperties.get("ro.dalvik.vm.isa." + secondaryIsa);
191 secondaryIsa = secondaryDexCodeIsa.isEmpty() ? secondaryIsa : secondaryDexCodeIsa;
Narayan Kamath7dba6eb2014-07-16 08:53:30 +0100192
193 // If the runtimeIsa is the same as the primary isa, then we do nothing.
194 // Everything will be set up correctly because info.nativeLibraryDir will
195 // correspond to the right ISA.
196 if (runtimeIsa.equals(secondaryIsa)) {
197 final ApplicationInfo modified = new ApplicationInfo(info);
198 modified.nativeLibraryDir = modified.secondaryNativeLibraryDir;
Dmitriy Ivanove56b3f62015-06-05 22:00:13 -0700199 modified.primaryCpuAbi = modified.secondaryCpuAbi;
Narayan Kamath7dba6eb2014-07-16 08:53:30 +0100200 return modified;
201 }
202 }
203
204 return info;
205 }
206
Jeff Browndefd4a62014-03-10 21:24:37 -0700207 /**
208 * Create information about the system package.
209 * Must call {@link #installSystemApplicationInfo} later.
210 */
211 LoadedApk(ActivityThread activityThread) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700212 mActivityThread = activityThread;
Jeff Browndefd4a62014-03-10 21:24:37 -0700213 mApplicationInfo = new ApplicationInfo();
214 mApplicationInfo.packageName = "android";
215 mPackageName = "android";
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700216 mAppDir = null;
217 mResDir = null;
Jeff Sharkey8a4c9722014-06-16 13:48:42 -0700218 mSplitAppDirs = null;
219 mSplitResDirs = null;
Narayan Kamathf9419f02017-06-15 11:35:38 +0100220 mSplitClassLoaderNames = null;
MÃ¥rten Kongstad48d22322014-01-31 14:43:27 +0100221 mOverlayDirs = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700222 mDataDir = null;
223 mDataDirFile = null;
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600224 mDeviceProtectedDataDirFile = null;
225 mCredentialProtectedDataDirFile = null;
Kenny Root85387d72010-08-26 10:13:11 -0700226 mLibDir = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700227 mBaseClassLoader = null;
228 mSecurityViolation = false;
229 mIncludeCode = true;
Dianne Hackbornfee756f2014-07-16 17:31:10 -0700230 mRegisterPackage = false;
Jeff Browndefd4a62014-03-10 21:24:37 -0700231 mResources = Resources.getSystem();
David Brazdilb319ccf2018-10-25 14:07:51 +0100232 mDefaultClassLoader = ClassLoader.getSystemClassLoader();
233 mAppComponentFactory = createAppFactory(mApplicationInfo, mDefaultClassLoader);
234 mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader);
Jeff Browndefd4a62014-03-10 21:24:37 -0700235 }
236
237 /**
238 * Sets application info about the system package.
239 */
Narayan Kamath29564cd2014-08-07 10:57:40 +0100240 void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
Jeff Browndefd4a62014-03-10 21:24:37 -0700241 assert info.packageName.equals("android");
242 mApplicationInfo = info;
David Brazdilb319ccf2018-10-25 14:07:51 +0100243 mDefaultClassLoader = classLoader;
244 mAppComponentFactory = createAppFactory(info, mDefaultClassLoader);
245 mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader);
Jason Monka80bfb52017-11-16 17:15:37 -0500246 }
247
248 private AppComponentFactory createAppFactory(ApplicationInfo appInfo, ClassLoader cl) {
Jason Monk6ee51bb2018-03-02 11:20:31 -0500249 if (appInfo.appComponentFactory != null && cl != null) {
Jason Monka80bfb52017-11-16 17:15:37 -0500250 try {
David Brazdilb319ccf2018-10-25 14:07:51 +0100251 AppComponentFactory factory = (AppComponentFactory) cl.loadClass(
252 appInfo.appComponentFactory).newInstance();
253 // Pass a copy of ApplicationInfo to the factory. Copying protects the framework
254 // from apps which would override the factory and change ApplicationInfo contents.
255 // ApplicationInfo is used to set up the default class loader.
256 factory.setApplicationInfo(new ApplicationInfo(appInfo));
257 return factory;
Jason Monka80bfb52017-11-16 17:15:37 -0500258 } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
259 Slog.e(TAG, "Unable to instantiate appComponentFactory", e);
260 }
261 }
262 return AppComponentFactory.DEFAULT;
263 }
264
265 public AppComponentFactory getAppFactory() {
266 return mAppComponentFactory;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700267 }
268
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100269 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700270 public String getPackageName() {
271 return mPackageName;
272 }
273
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100274 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700275 public ApplicationInfo getApplicationInfo() {
276 return mApplicationInfo;
277 }
278
Jeff Sharkey369f5092016-02-29 11:16:21 -0700279 public int getTargetSdkVersion() {
280 return mApplicationInfo.targetSdkVersion;
281 }
282
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700283 public boolean isSecurityViolation() {
284 return mSecurityViolation;
285 }
286
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100287 @UnsupportedAppUsage
Craig Mautner48d0d182013-06-11 07:53:06 -0700288 public CompatibilityInfo getCompatibilityInfo() {
289 return mDisplayAdjustments.getCompatibilityInfo();
290 }
291
292 public void setCompatibilityInfo(CompatibilityInfo compatInfo) {
293 mDisplayAdjustments.setCompatibilityInfo(compatInfo);
294 }
295
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700296 /**
297 * Gets the array of shared libraries that are listed as
298 * used by the given package.
299 *
300 * @param packageName the name of the package (note: not its
301 * file name)
302 * @return null-ok; the array of shared libraries, each one
303 * a fully-qualified path
304 */
305 private static String[] getLibrariesFor(String packageName) {
306 ApplicationInfo ai = null;
307 try {
308 ai = ActivityThread.getPackageManager().getApplicationInfo(packageName,
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700309 PackageManager.GET_SHARED_LIBRARY_FILES, UserHandle.myUserId());
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700310 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700311 throw e.rethrowFromSystemServer();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700312 }
313
314 if (ai == null) {
315 return null;
316 }
317
318 return ai.sharedLibraryFiles;
319 }
320
Adam Lesinskid33ef562017-01-19 14:49:59 -0800321 /**
322 * Update the ApplicationInfo for an app. If oldPaths is null, all the paths are considered
323 * new.
324 * @param aInfo The new ApplicationInfo to use for this LoadedApk
325 * @param oldPaths The code paths for the old ApplicationInfo object. null means no paths can
326 * be reused.
327 */
328 public void updateApplicationInfo(@NonNull ApplicationInfo aInfo,
329 @Nullable List<String> oldPaths) {
Todd Kennedy39bfee52016-02-24 10:28:21 -0800330 setApplicationInfo(aInfo);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700331
Todd Kennedy39bfee52016-02-24 10:28:21 -0800332 final List<String> newPaths = new ArrayList<>();
Dimitry Ivanov638d8102017-02-22 15:39:42 -0800333 makePaths(mActivityThread, aInfo, newPaths);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800334 final List<String> addedPaths = new ArrayList<>(newPaths.size());
335
336 if (oldPaths != null) {
337 for (String path : newPaths) {
338 final String apkName = path.substring(path.lastIndexOf(File.separator));
339 boolean match = false;
340 for (String oldPath : oldPaths) {
Adam Lesinskia5ca6242017-03-01 15:45:12 -0800341 final String oldApkName = oldPath.substring(oldPath.lastIndexOf(File.separator));
Todd Kennedy39bfee52016-02-24 10:28:21 -0800342 if (apkName.equals(oldApkName)) {
343 match = true;
344 break;
345 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700346 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800347 if (!match) {
348 addedPaths.add(path);
349 }
350 }
351 } else {
352 addedPaths.addAll(newPaths);
353 }
354 synchronized (this) {
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700355 createOrUpdateClassLoaderLocked(addedPaths);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800356 if (mResources != null) {
Adam Lesinski4e862812016-11-21 16:02:24 -0800357 final String[] splitPaths;
358 try {
359 splitPaths = getSplitPaths(null);
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800360 } catch (NameNotFoundException e) {
Adam Lesinski4e862812016-11-21 16:02:24 -0800361 // This should NEVER fail.
362 throw new AssertionError("null split not found");
363 }
364
365 mResources = ResourcesManager.getInstance().getResources(null, mResDir,
Adam Lesinski0e618832017-02-07 11:40:12 -0800366 splitPaths, mOverlayDirs, mApplicationInfo.sharedLibraryFiles,
Adam Lesinski4e862812016-11-21 16:02:24 -0800367 Display.DEFAULT_DISPLAY, null, getCompatibilityInfo(),
368 getClassLoader());
Todd Kennedy39bfee52016-02-24 10:28:21 -0800369 }
370 }
David Brazdilb319ccf2018-10-25 14:07:51 +0100371 mAppComponentFactory = createAppFactory(aInfo, mDefaultClassLoader);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800372 }
373
374 private void setApplicationInfo(ApplicationInfo aInfo) {
375 final int myUid = Process.myUid();
376 aInfo = adjustNativeLibraryPaths(aInfo);
377 mApplicationInfo = aInfo;
378 mAppDir = aInfo.sourceDir;
379 mResDir = aInfo.uid == myUid ? aInfo.sourceDir : aInfo.publicSourceDir;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800380 mOverlayDirs = aInfo.resourceDirs;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800381 mDataDir = aInfo.dataDir;
382 mLibDir = aInfo.nativeLibraryDir;
383 mDataDirFile = FileUtils.newFileOrNull(aInfo.dataDir);
Jeff Sharkey8a372a02016-03-16 16:25:45 -0600384 mDeviceProtectedDataDirFile = FileUtils.newFileOrNull(aInfo.deviceProtectedDataDir);
385 mCredentialProtectedDataDirFile = FileUtils.newFileOrNull(aInfo.credentialProtectedDataDir);
Adam Lesinski4e862812016-11-21 16:02:24 -0800386
387 mSplitNames = aInfo.splitNames;
388 mSplitAppDirs = aInfo.splitSourceDirs;
389 mSplitResDirs = aInfo.uid == myUid ? aInfo.splitSourceDirs : aInfo.splitPublicSourceDirs;
Narayan Kamathf9419f02017-06-15 11:35:38 +0100390 mSplitClassLoaderNames = aInfo.splitClassLoaderNames;
Adam Lesinski4e862812016-11-21 16:02:24 -0800391
392 if (aInfo.requestsIsolatedSplitLoading() && !ArrayUtils.isEmpty(mSplitNames)) {
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800393 mSplitLoader = new SplitDependencyLoaderImpl(aInfo.splitDependencies);
Adam Lesinski4e862812016-11-21 16:02:24 -0800394 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800395 }
396
Dimitry Ivanov638d8102017-02-22 15:39:42 -0800397 public static void makePaths(ActivityThread activityThread,
398 ApplicationInfo aInfo,
399 List<String> outZipPaths) {
400 makePaths(activityThread, false, aInfo, outZipPaths, null);
401 }
402
Nicolas Geoffray972b39e2018-11-15 12:59:52 +0000403 private static void appendSharedLibrariesLibPathsIfNeeded(
404 List<SharedLibraryInfo> sharedLibraries, ApplicationInfo aInfo,
405 Set<String> outSeenPaths,
406 List<String> outLibPaths) {
407 if (sharedLibraries == null) {
408 return;
409 }
410 for (SharedLibraryInfo lib : sharedLibraries) {
411 List<String> paths = lib.getAllCodePaths();
412 outSeenPaths.addAll(paths);
413 for (String path : paths) {
414 appendApkLibPathIfNeeded(path, aInfo, outLibPaths);
415 }
416 appendSharedLibrariesLibPathsIfNeeded(
417 lib.getDependencies(), aInfo, outSeenPaths, outLibPaths);
418 }
419 }
420
Dimitry Ivanov638d8102017-02-22 15:39:42 -0800421 public static void makePaths(ActivityThread activityThread,
422 boolean isBundledApp,
423 ApplicationInfo aInfo,
424 List<String> outZipPaths,
425 List<String> outLibPaths) {
Todd Kennedy39bfee52016-02-24 10:28:21 -0800426 final String appDir = aInfo.sourceDir;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800427 final String libDir = aInfo.nativeLibraryDir;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800428
429 outZipPaths.clear();
430 outZipPaths.add(appDir);
Adam Lesinski4e862812016-11-21 16:02:24 -0800431
432 // Do not load all available splits if the app requested isolated split loading.
433 if (aInfo.splitSourceDirs != null && !aInfo.requestsIsolatedSplitLoading()) {
434 Collections.addAll(outZipPaths, aInfo.splitSourceDirs);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800435 }
436
437 if (outLibPaths != null) {
438 outLibPaths.clear();
439 }
440
441 /*
442 * The following is a bit of a hack to inject
443 * instrumentation into the system: If the app
444 * being started matches one of the instrumentation names,
445 * then we combine both the "instrumentation" and
446 * "instrumented" app into the path, along with the
447 * concatenation of both apps' shared library lists.
448 */
449
Todd Kennedy39bfee52016-02-24 10:28:21 -0800450 String[] instrumentationLibs = null;
Torne (Richard Coles)3b6ca992016-10-10 15:11:36 +0100451 // activityThread will be null when called from the WebView zygote; just assume
452 // no instrumentation applies in this case.
453 if (activityThread != null) {
454 String instrumentationPackageName = activityThread.mInstrumentationPackageName;
455 String instrumentationAppDir = activityThread.mInstrumentationAppDir;
456 String[] instrumentationSplitAppDirs = activityThread.mInstrumentationSplitAppDirs;
457 String instrumentationLibDir = activityThread.mInstrumentationLibDir;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800458
Torne (Richard Coles)3b6ca992016-10-10 15:11:36 +0100459 String instrumentedAppDir = activityThread.mInstrumentedAppDir;
460 String[] instrumentedSplitAppDirs = activityThread.mInstrumentedSplitAppDirs;
461 String instrumentedLibDir = activityThread.mInstrumentedLibDir;
462
463 if (appDir.equals(instrumentationAppDir)
464 || appDir.equals(instrumentedAppDir)) {
465 outZipPaths.clear();
466 outZipPaths.add(instrumentationAppDir);
Adam Lesinski4e862812016-11-21 16:02:24 -0800467
468 // Only add splits if the app did not request isolated split loading.
469 if (!aInfo.requestsIsolatedSplitLoading()) {
470 if (instrumentationSplitAppDirs != null) {
471 Collections.addAll(outZipPaths, instrumentationSplitAppDirs);
472 }
473
474 if (!instrumentationAppDir.equals(instrumentedAppDir)) {
475 outZipPaths.add(instrumentedAppDir);
476 if (instrumentedSplitAppDirs != null) {
477 Collections.addAll(outZipPaths, instrumentedSplitAppDirs);
478 }
Torne (Richard Coles)3b6ca992016-10-10 15:11:36 +0100479 }
Jeff Haoc7b94822016-03-16 15:56:07 -0700480 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800481
Torne (Richard Coles)3b6ca992016-10-10 15:11:36 +0100482 if (outLibPaths != null) {
483 outLibPaths.add(instrumentationLibDir);
484 if (!instrumentationLibDir.equals(instrumentedLibDir)) {
485 outLibPaths.add(instrumentedLibDir);
486 }
487 }
488
489 if (!instrumentedAppDir.equals(instrumentationAppDir)) {
490 instrumentationLibs = getLibrariesFor(instrumentationPackageName);
491 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800492 }
493 }
494
495 if (outLibPaths != null) {
496 if (outLibPaths.isEmpty()) {
497 outLibPaths.add(libDir);
498 }
499
500 // Add path to libraries in apk for current abi. Do this now because more entries
501 // will be added to zipPaths that shouldn't be part of the library path.
502 if (aInfo.primaryCpuAbi != null) {
Alex Light20ed24f2016-04-20 14:07:43 -0700503 // Add fake libs into the library search path if we target prior to N.
Adam Lesinski4e862812016-11-21 16:02:24 -0800504 if (aInfo.targetSdkVersion < Build.VERSION_CODES.N) {
Alex Light20ed24f2016-04-20 14:07:43 -0700505 outLibPaths.add("/system/fake-libs" +
506 (VMRuntime.is64BitAbi(aInfo.primaryCpuAbi) ? "64" : ""));
507 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800508 for (String apk : outZipPaths) {
509 outLibPaths.add(apk + "!/lib/" + aInfo.primaryCpuAbi);
510 }
511 }
512
Dimitry Ivanov638d8102017-02-22 15:39:42 -0800513 if (isBundledApp) {
Todd Kennedy39bfee52016-02-24 10:28:21 -0800514 // Add path to system libraries to libPaths;
515 // Access to system libs should be limited
516 // to bundled applications; this is why updated
517 // system apps are not included.
518 outLibPaths.add(System.getProperty("java.library.path"));
519 }
520 }
521
Nicolas Geoffray972b39e2018-11-15 12:59:52 +0000522 // Add the shared libraries native paths. The dex files in shared libraries will
523 // be resolved through shared library loaders, which are setup later.
524 Set<String> outSeenPaths = new LinkedHashSet<>();
525 appendSharedLibrariesLibPathsIfNeeded(
526 aInfo.sharedLibraryInfos, aInfo, outSeenPaths, outLibPaths);
527
528 // ApplicationInfo.sharedLibraryFiles is a public API, so anyone can change it.
529 // We prepend shared libraries that the package manager hasn't seen, maintaining their
530 // original order where possible.
531 if (aInfo.sharedLibraryFiles != null) {
Jeff Hao090892f2017-04-24 17:37:31 -0700532 int index = 0;
Nicolas Geoffray972b39e2018-11-15 12:59:52 +0000533 for (String lib : aInfo.sharedLibraryFiles) {
534 if (!outSeenPaths.contains(lib) && !outZipPaths.contains(lib)) {
Jeff Hao090892f2017-04-24 17:37:31 -0700535 outZipPaths.add(index, lib);
536 index++;
Svetoslav Ganov40610e32017-06-20 19:35:51 -0700537 appendApkLibPathIfNeeded(lib, aInfo, outLibPaths);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800538 }
539 }
540 }
541
542 if (instrumentationLibs != null) {
543 for (String lib : instrumentationLibs) {
544 if (!outZipPaths.contains(lib)) {
545 outZipPaths.add(0, lib);
Svetoslav Ganov40610e32017-06-20 19:35:51 -0700546 appendApkLibPathIfNeeded(lib, aInfo, outLibPaths);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800547 }
548 }
549 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800550 }
551
Svetoslav Ganov40610e32017-06-20 19:35:51 -0700552 /**
553 * This method appends a path to the appropriate native library folder of a
554 * library if this library is hosted in an APK. This allows support for native
555 * shared libraries. The library API is determined based on the application
556 * ABI.
557 *
558 * @param path Path to the library.
559 * @param applicationInfo The application depending on the library.
560 * @param outLibPaths List to which to add the native lib path if needed.
561 */
562 private static void appendApkLibPathIfNeeded(@NonNull String path,
563 @NonNull ApplicationInfo applicationInfo, @Nullable List<String> outLibPaths) {
564 // Looking at the suffix is a little hacky but a safe and simple solution.
565 // We will be revisiting code in the next release and clean this up.
566 if (outLibPaths != null && applicationInfo.primaryCpuAbi != null && path.endsWith(".apk")) {
567 if (applicationInfo.targetSdkVersion >= Build.VERSION_CODES.O) {
568 outLibPaths.add(path + "!/lib/" + applicationInfo.primaryCpuAbi);
569 }
570 }
571 }
572
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800573 /*
574 * All indices received by the super class should be shifted by 1 when accessing mSplitNames,
575 * etc. The super class assumes the base APK is index 0, while the PackageManager APIs don't
576 * include the base APK in the list of splits.
577 */
578 private class SplitDependencyLoaderImpl extends SplitDependencyLoader<NameNotFoundException> {
Adam Lesinski4e862812016-11-21 16:02:24 -0800579 private final String[][] mCachedResourcePaths;
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800580 private final ClassLoader[] mCachedClassLoaders;
Adam Lesinski4e862812016-11-21 16:02:24 -0800581
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800582 SplitDependencyLoaderImpl(@NonNull SparseArray<int[]> dependencies) {
Adam Lesinski4e862812016-11-21 16:02:24 -0800583 super(dependencies);
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800584 mCachedResourcePaths = new String[mSplitNames.length + 1][];
585 mCachedClassLoaders = new ClassLoader[mSplitNames.length + 1];
Adam Lesinski4e862812016-11-21 16:02:24 -0800586 }
587
588 @Override
589 protected boolean isSplitCached(int splitIdx) {
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800590 return mCachedClassLoaders[splitIdx] != null;
Adam Lesinski4e862812016-11-21 16:02:24 -0800591 }
592
593 @Override
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800594 protected void constructSplit(int splitIdx, @NonNull int[] configSplitIndices,
595 int parentSplitIdx) throws NameNotFoundException {
Adam Lesinski4e862812016-11-21 16:02:24 -0800596 final ArrayList<String> splitPaths = new ArrayList<>();
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800597 if (splitIdx == 0) {
Adam Lesinski4e862812016-11-21 16:02:24 -0800598 createOrUpdateClassLoaderLocked(null);
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800599 mCachedClassLoaders[0] = mClassLoader;
600
601 // Never add the base resources here, they always get added no matter what.
602 for (int configSplitIdx : configSplitIndices) {
603 splitPaths.add(mSplitResDirs[configSplitIdx - 1]);
604 }
605 mCachedResourcePaths[0] = splitPaths.toArray(new String[splitPaths.size()]);
Adam Lesinski4e862812016-11-21 16:02:24 -0800606 return;
607 }
608
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800609 // Since we handled the special base case above, parentSplitIdx is always valid.
610 final ClassLoader parent = mCachedClassLoaders[parentSplitIdx];
611 mCachedClassLoaders[splitIdx] = ApplicationLoaders.getDefault().getClassLoader(
Narayan Kamathf9419f02017-06-15 11:35:38 +0100612 mSplitAppDirs[splitIdx - 1], getTargetSdkVersion(), false, null, null, parent,
613 mSplitClassLoaderNames[splitIdx - 1]);
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800614
615 Collections.addAll(splitPaths, mCachedResourcePaths[parentSplitIdx]);
616 splitPaths.add(mSplitResDirs[splitIdx - 1]);
617 for (int configSplitIdx : configSplitIndices) {
618 splitPaths.add(mSplitResDirs[configSplitIdx - 1]);
Adam Lesinski4e862812016-11-21 16:02:24 -0800619 }
Adam Lesinski4e862812016-11-21 16:02:24 -0800620 mCachedResourcePaths[splitIdx] = splitPaths.toArray(new String[splitPaths.size()]);
621 }
622
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800623 private int ensureSplitLoaded(String splitName) throws NameNotFoundException {
624 int idx = 0;
625 if (splitName != null) {
Adam Lesinski4e862812016-11-21 16:02:24 -0800626 idx = Arrays.binarySearch(mSplitNames, splitName);
627 if (idx < 0) {
628 throw new PackageManager.NameNotFoundException(
629 "Split name '" + splitName + "' is not installed");
630 }
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800631 idx += 1;
Adam Lesinski4e862812016-11-21 16:02:24 -0800632 }
Adam Lesinski4e862812016-11-21 16:02:24 -0800633 loadDependenciesForSplit(idx);
634 return idx;
635 }
636
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800637 ClassLoader getClassLoaderForSplit(String splitName) throws NameNotFoundException {
638 return mCachedClassLoaders[ensureSplitLoaded(splitName)];
Adam Lesinski4e862812016-11-21 16:02:24 -0800639 }
640
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800641 String[] getSplitPathsForSplit(String splitName) throws NameNotFoundException {
642 return mCachedResourcePaths[ensureSplitLoaded(splitName)];
Adam Lesinski4e862812016-11-21 16:02:24 -0800643 }
644 }
645
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800646 private SplitDependencyLoaderImpl mSplitLoader;
Adam Lesinski4e862812016-11-21 16:02:24 -0800647
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800648 ClassLoader getSplitClassLoader(String splitName) throws NameNotFoundException {
Adam Lesinski4e862812016-11-21 16:02:24 -0800649 if (mSplitLoader == null) {
650 return mClassLoader;
651 }
652 return mSplitLoader.getClassLoaderForSplit(splitName);
653 }
654
Adam Lesinski1665d0f2017-03-10 14:46:57 -0800655 String[] getSplitPaths(String splitName) throws NameNotFoundException {
Adam Lesinski4e862812016-11-21 16:02:24 -0800656 if (mSplitLoader == null) {
657 return mSplitResDirs;
658 }
659 return mSplitLoader.getSplitPathsForSplit(splitName);
660 }
661
Nicolas Geoffray972b39e2018-11-15 12:59:52 +0000662 /**
663 * Create a class loader for the {@code sharedLibrary}. Shared libraries are canonicalized,
664 * so if we already created a class loader with that shared library, we return it.
665 *
666 * Implementation notes: the canonicalization of shared libraries is something dex2oat
667 * also does.
668 */
669 ClassLoader createSharedLibraryLoader(SharedLibraryInfo sharedLibrary,
670 boolean isBundledApp, String librarySearchPath, String libraryPermittedPath) {
671 List<String> paths = sharedLibrary.getAllCodePaths();
672 List<ClassLoader> sharedLibraries = createSharedLibrariesLoaders(
673 sharedLibrary.getDependencies(), isBundledApp, librarySearchPath,
674 libraryPermittedPath);
675 final String jars = (paths.size() == 1) ? paths.get(0) :
676 TextUtils.join(File.pathSeparator, paths);
677
678 // Shared libraries get a null parent: this has the side effect of having canonicalized
679 // shared libraries using ApplicationLoaders cache, which is the behavior we want.
680 return ApplicationLoaders.getDefault().getClassLoaderWithSharedLibraries(jars,
681 mApplicationInfo.targetSdkVersion, isBundledApp, librarySearchPath,
682 libraryPermittedPath, /* parent */ null,
683 /* classLoaderName */ null, sharedLibraries);
684 }
685
686 private List<ClassLoader> createSharedLibrariesLoaders(List<SharedLibraryInfo> sharedLibraries,
687 boolean isBundledApp, String librarySearchPath, String libraryPermittedPath) {
688 if (sharedLibraries == null) {
689 return null;
690 }
691 List<ClassLoader> loaders = new ArrayList<>();
692 for (SharedLibraryInfo info : sharedLibraries) {
693 loaders.add(createSharedLibraryLoader(
694 info, isBundledApp, librarySearchPath, libraryPermittedPath));
695 }
696 return loaders;
697 }
698
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700699 private void createOrUpdateClassLoaderLocked(List<String> addedPaths) {
700 if (mPackageName.equals("android")) {
Calin Juravle430ef452016-04-22 17:43:07 +0100701 // Note: This branch is taken for system server and we don't need to setup
702 // jit profiling support.
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700703 if (mClassLoader != null) {
704 // nothing to update
705 return;
Dimitry Ivanovb9c90262016-02-19 14:09:20 -0800706 }
707
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700708 if (mBaseClassLoader != null) {
David Brazdilb319ccf2018-10-25 14:07:51 +0100709 mDefaultClassLoader = mBaseClassLoader;
Todd Kennedy39bfee52016-02-24 10:28:21 -0800710 } else {
David Brazdilb319ccf2018-10-25 14:07:51 +0100711 mDefaultClassLoader = ClassLoader.getSystemClassLoader();
Todd Kennedy39bfee52016-02-24 10:28:21 -0800712 }
David Brazdilb319ccf2018-10-25 14:07:51 +0100713 mAppComponentFactory = createAppFactory(mApplicationInfo, mDefaultClassLoader);
714 mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader);
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700715
716 return;
717 }
718
719 // Avoid the binder call when the package is the current application package.
720 // The activity manager will perform ensure that dexopt is performed before
721 // spinning up the process.
Narayan Kamathbf07e2a2017-03-15 11:37:32 +0000722 if (!Objects.equals(mPackageName, ActivityThread.currentPackageName()) && mIncludeCode) {
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700723 try {
Brian Carlstromca82e612016-04-19 23:16:08 -0700724 ActivityThread.getPackageManager().notifyPackageUse(mPackageName,
725 PackageManager.NOTIFY_PACKAGE_USE_CROSS_PACKAGE);
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700726 } catch (RemoteException re) {
727 throw re.rethrowFromSystemServer();
Todd Kennedy39bfee52016-02-24 10:28:21 -0800728 }
729 }
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700730
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700731 if (mRegisterPackage) {
732 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -0800733 ActivityManager.getService().addPackageDependency(mPackageName);
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700734 } catch (RemoteException e) {
735 throw e.rethrowFromSystemServer();
736 }
737 }
738
Andreas Gampea8a58ff2016-05-18 11:58:39 -0700739 // Lists for the elements of zip/code and native libraries.
740 //
741 // Both lists are usually not empty. We expect on average one APK for the zip component,
742 // but shared libraries and splits are not uncommon. We expect at least three elements
743 // for native libraries (app-based, system, vendor). As such, give both some breathing
744 // space and initialize to a small value (instead of incurring growth code).
745 final List<String> zipPaths = new ArrayList<>(10);
746 final List<String> libPaths = new ArrayList<>(10);
Narayan Kamath8995b002016-05-11 20:31:09 +0100747
Jiyong Parkfcad6962017-08-22 10:24:28 +0900748 boolean isBundledApp = mApplicationInfo.isSystemApp()
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700749 && !mApplicationInfo.isUpdatedSystemApp();
Dimitry Ivanovbf3b5f72016-05-03 11:34:58 -0700750
Jiyong Parkfcad6962017-08-22 10:24:28 +0900751 // Vendor apks are treated as bundled only when /vendor/lib is in the default search
752 // paths. If not, they are treated as unbundled; access to system libs is limited.
753 // Having /vendor/lib in the default search paths means that all system processes
754 // are allowed to use any vendor library, which in turn means that system is dependent
755 // on vendor partition. In the contrary, not having /vendor/lib in the default search
756 // paths mean that the two partitions are separated and thus we can treat vendor apks
757 // as unbundled.
758 final String defaultSearchPaths = System.getProperty("java.library.path");
759 final boolean treatVendorApkAsUnbundled = !defaultSearchPaths.contains("/vendor/lib");
Jiyong Park63495c22017-09-15 07:48:06 +0900760 if (mApplicationInfo.getCodePath() != null
Jiyong Park002fdbd2017-02-13 20:50:31 +0900761 && mApplicationInfo.isVendor() && treatVendorApkAsUnbundled) {
Jiyong Parkfcad6962017-08-22 10:24:28 +0900762 isBundledApp = false;
763 }
764
Dimitry Ivanov638d8102017-02-22 15:39:42 -0800765 makePaths(mActivityThread, isBundledApp, mApplicationInfo, zipPaths, libPaths);
766
Dimitry Ivanoveb96b002016-05-10 10:51:40 -0700767 String libraryPermittedPath = mDataDir;
Jiyong Park29d9eba2018-05-04 12:44:38 +0900768
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700769 if (isBundledApp) {
Jiyong Park29d9eba2018-05-04 12:44:38 +0900770 // For bundled apps, add the base directory of the app (e.g.,
771 // /system/app/Foo/) to the permitted paths so that it can load libraries
772 // embedded in module apks under the directory. For now, GmsCore is relying
773 // on this, but this isn't specific to the app. Also note that, we don't
774 // need to do this for unbundled apps as entire /data is already set to
775 // the permitted paths for them.
776 libraryPermittedPath += File.pathSeparator
777 + Paths.get(getAppDir()).getParent().toString();
778
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700779 // This is necessary to grant bundled apps access to
780 // libraries located in subdirectories of /system/lib
Jiyong Parkfcad6962017-08-22 10:24:28 +0900781 libraryPermittedPath += File.pathSeparator + defaultSearchPaths;
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700782 }
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700783
784 final String librarySearchPath = TextUtils.join(File.pathSeparator, libPaths);
785
Narayan Kamath8995b002016-05-11 20:31:09 +0100786 // If we're not asked to include code, we construct a classloader that has
787 // no code path included. We still need to set up the library search paths
788 // and permitted path because NativeActivity relies on it (it attempts to
789 // call System.loadLibrary() on a classloader from a LoadedApk with
790 // mIncludeCode == false).
791 if (!mIncludeCode) {
David Brazdilb319ccf2018-10-25 14:07:51 +0100792 if (mDefaultClassLoader == null) {
Narayan Kamath8995b002016-05-11 20:31:09 +0100793 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
David Brazdilb319ccf2018-10-25 14:07:51 +0100794 mDefaultClassLoader = ApplicationLoaders.getDefault().getClassLoader(
Narayan Kamathf9419f02017-06-15 11:35:38 +0100795 "" /* codePath */, mApplicationInfo.targetSdkVersion, isBundledApp,
796 librarySearchPath, libraryPermittedPath, mBaseClassLoader,
797 null /* classLoaderName */);
Narayan Kamath8995b002016-05-11 20:31:09 +0100798 StrictMode.setThreadPolicy(oldPolicy);
Jason Monk2544c692018-05-15 11:30:09 -0400799 mAppComponentFactory = AppComponentFactory.DEFAULT;
Narayan Kamath8995b002016-05-11 20:31:09 +0100800 }
801
David Brazdilb319ccf2018-10-25 14:07:51 +0100802 if (mClassLoader == null) {
803 mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader);
804 }
805
Narayan Kamath8995b002016-05-11 20:31:09 +0100806 return;
807 }
808
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700809 /*
Narayan Kamath8995b002016-05-11 20:31:09 +0100810 * With all the combination done (if necessary, actually create the java class
811 * loader and set up JIT profiling support if necessary.
Andreas Gampea8a58ff2016-05-18 11:58:39 -0700812 *
813 * In many cases this is a single APK, so try to avoid the StringBuilder in TextUtils.
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700814 */
Andreas Gampea8a58ff2016-05-18 11:58:39 -0700815 final String zip = (zipPaths.size() == 1) ? zipPaths.get(0) :
816 TextUtils.join(File.pathSeparator, zipPaths);
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700817
Dianne Hackborn94846032017-03-31 17:55:23 -0700818 if (DEBUG) Slog.v(ActivityThread.TAG, "Class path: " + zip +
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700819 ", JNI path: " + librarySearchPath);
820
Calin Juravle430ef452016-04-22 17:43:07 +0100821 boolean needToSetupJitProfiles = false;
David Brazdilb319ccf2018-10-25 14:07:51 +0100822 if (mDefaultClassLoader == null) {
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700823 // Temporarily disable logging of disk reads on the Looper thread
824 // as this is early and necessary.
825 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
826
Nicolas Geoffray972b39e2018-11-15 12:59:52 +0000827 List<ClassLoader> sharedLibraries = createSharedLibrariesLoaders(
828 mApplicationInfo.sharedLibraryInfos, isBundledApp, librarySearchPath,
829 libraryPermittedPath);
830
831 mDefaultClassLoader = ApplicationLoaders.getDefault().getClassLoaderWithSharedLibraries(
832 zip, mApplicationInfo.targetSdkVersion, isBundledApp, librarySearchPath,
Narayan Kamathf9419f02017-06-15 11:35:38 +0100833 libraryPermittedPath, mBaseClassLoader,
Nicolas Geoffray972b39e2018-11-15 12:59:52 +0000834 mApplicationInfo.classLoaderName, sharedLibraries);
David Brazdilb319ccf2018-10-25 14:07:51 +0100835 mAppComponentFactory = createAppFactory(mApplicationInfo, mDefaultClassLoader);
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700836
837 StrictMode.setThreadPolicy(oldPolicy);
Calin Juravle430ef452016-04-22 17:43:07 +0100838 // Setup the class loader paths for profiling.
839 needToSetupJitProfiles = true;
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700840 }
841
Patrick Baumann1bea2372018-03-13 14:26:58 -0700842 if (!libPaths.isEmpty() && SystemProperties.getBoolean(PROPERTY_NAME_APPEND_NATIVE, true)) {
Patrick Baumann5c5daa42018-05-09 11:12:49 -0700843 // Temporarily disable logging of disk reads on the Looper thread as this is necessary
844 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
845 try {
David Brazdilb319ccf2018-10-25 14:07:51 +0100846 ApplicationLoaders.getDefault().addNative(mDefaultClassLoader, libPaths);
Patrick Baumann5c5daa42018-05-09 11:12:49 -0700847 } finally {
848 StrictMode.setThreadPolicy(oldPolicy);
849 }
Patrick Baumann1bea2372018-03-13 14:26:58 -0700850 }
851
Jiyong Parkcfe38cd2018-06-04 15:05:29 +0900852 // /vendor/lib, /odm/lib and /product/lib are added to the native lib search
853 // paths of the classloader. Note that this is done AFTER the classloader is
854 // created by ApplicationLoaders.getDefault().getClassLoader(...). The
855 // reason is because if we have added the paths when creating the classloader
856 // above, the paths are also added to the search path of the linker namespace
857 // 'classloader-namespace', which will allow ALL libs in the paths to apps.
858 // Since only the libs listed in <partition>/etc/public.libraries.txt can be
859 // available to apps, we shouldn't add the paths then.
860 //
861 // However, we need to add the paths to the classloader (Java) though. This
862 // is because when a native lib is requested via System.loadLibrary(), the
863 // classloader first tries to find the requested lib in its own native libs
864 // search paths. If a lib is not found in one of the paths, dlopen() is not
865 // called at all. This can cause a problem that a vendor public native lib
866 // is accessible when directly opened via dlopen(), but inaccesible via
867 // System.loadLibrary(). In order to prevent the problem, we explicitly
868 // add the paths only to the classloader, and not to the native loader
869 // (linker namespace).
870 List<String> extraLibPaths = new ArrayList<>(3);
871 String abiSuffix = VMRuntime.getRuntime().is64Bit() ? "64" : "";
872 if (!defaultSearchPaths.contains("/vendor/lib")) {
873 extraLibPaths.add("/vendor/lib" + abiSuffix);
874 }
875 if (!defaultSearchPaths.contains("/odm/lib")) {
876 extraLibPaths.add("/odm/lib" + abiSuffix);
877 }
878 if (!defaultSearchPaths.contains("/product/lib")) {
879 extraLibPaths.add("/product/lib" + abiSuffix);
880 }
881 if (!extraLibPaths.isEmpty()) {
882 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
883 try {
David Brazdilb319ccf2018-10-25 14:07:51 +0100884 ApplicationLoaders.getDefault().addNative(mDefaultClassLoader, extraLibPaths);
Jiyong Parkcfe38cd2018-06-04 15:05:29 +0900885 } finally {
886 StrictMode.setThreadPolicy(oldPolicy);
887 }
888 }
889
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700890 if (addedPaths != null && addedPaths.size() > 0) {
891 final String add = TextUtils.join(File.pathSeparator, addedPaths);
David Brazdilb319ccf2018-10-25 14:07:51 +0100892 ApplicationLoaders.getDefault().addPath(mDefaultClassLoader, add);
Calin Juravle430ef452016-04-22 17:43:07 +0100893 // Setup the new code paths for profiling.
894 needToSetupJitProfiles = true;
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700895 }
Calin Juravle2a727d72016-04-15 19:33:46 +0100896
897 // Setup jit profile support.
Narayan Kamath2d4a2222016-04-25 19:16:56 +0100898 //
Calin Juravle2a727d72016-04-15 19:33:46 +0100899 // It is ok to call this multiple times if the application gets updated with new splits.
900 // The runtime only keeps track of unique code paths and can handle re-registration of
901 // the same code path. There's no need to pass `addedPaths` since any new code paths
902 // are already in `mApplicationInfo`.
Narayan Kamath2d4a2222016-04-25 19:16:56 +0100903 //
904 // It is NOT ok to call this function from the system_server (for any of the packages it
905 // loads code from) so we explicitly disallow it there.
906 if (needToSetupJitProfiles && !ActivityThread.isSystem()) {
Calin Juravle430ef452016-04-22 17:43:07 +0100907 setupJitProfileSupport();
Calin Juravle430ef452016-04-22 17:43:07 +0100908 }
David Brazdilb319ccf2018-10-25 14:07:51 +0100909
910 // Call AppComponentFactory to select/create the main class loader of this app.
911 // Since this may call code in the app, mDefaultClassLoader must be fully set up
912 // before invoking the factory.
913 if (mClassLoader == null) {
914 mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader);
915 }
Todd Kennedy39bfee52016-02-24 10:28:21 -0800916 }
917
Mathew Inwood4fb17d12018-08-14 14:25:44 +0100918 @UnsupportedAppUsage
Todd Kennedy39bfee52016-02-24 10:28:21 -0800919 public ClassLoader getClassLoader() {
920 synchronized (this) {
921 if (mClassLoader == null) {
Dimitry Ivanov43b28b12016-03-14 17:15:38 -0700922 createOrUpdateClassLoaderLocked(null /*addedPaths*/);
Todd Kennedy39bfee52016-02-24 10:28:21 -0800923 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700924 return mClassLoader;
925 }
926 }
927
Calin Juravle2a727d72016-04-15 19:33:46 +0100928 private void setupJitProfileSupport() {
929 if (!SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false)) {
930 return;
931 }
Calin Juravle126f7802016-05-24 15:23:47 +0100932 // Only set up profile support if the loaded apk has the same uid as the
933 // current process.
934 // Currently, we do not support profiling across different apps.
935 // (e.g. application's uid might be different when the code is
936 // loaded by another app via createApplicationContext)
937 if (mApplicationInfo.uid != Process.myUid()) {
938 return;
939 }
940
Calin Juravle2a727d72016-04-15 19:33:46 +0100941 final List<String> codePaths = new ArrayList<>();
942 if ((mApplicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0) {
943 codePaths.add(mApplicationInfo.sourceDir);
944 }
945 if (mApplicationInfo.splitSourceDirs != null) {
946 Collections.addAll(codePaths, mApplicationInfo.splitSourceDirs);
947 }
948
949 if (codePaths.isEmpty()) {
950 // If there are no code paths there's no need to setup a profile file and register with
951 // the runtime,
952 return;
953 }
954
Calin Juravle6ae39fc2018-01-19 20:32:47 -0800955 for (int i = codePaths.size() - 1; i >= 0; i--) {
956 String splitName = i == 0 ? null : mApplicationInfo.splitNames[i - 1];
957 String profileFile = ArtManager.getCurrentProfilePath(
958 mPackageName, UserHandle.myUserId(), splitName);
959 VMRuntime.registerAppInfo(profileFile, new String[] {codePaths.get(i)});
960 }
Calin Juravlef5a7bfc2017-03-13 23:30:30 -0700961
962 // Register the app data directory with the reporter. It will
963 // help deciding whether or not a dex file is the primary apk or a
964 // secondary dex.
965 DexLoadReporter.getInstance().registerAppDataDir(mPackageName, mDataDir);
Calin Juravle2a727d72016-04-15 19:33:46 +0100966 }
967
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700968 /**
969 * Setup value for Thread.getContextClassLoader(). If the
970 * package will not run in in a VM with other packages, we set
971 * the Java context ClassLoader to the
972 * PackageInfo.getClassLoader value. However, if this VM can
973 * contain multiple packages, we intead set the Java context
974 * ClassLoader to a proxy that will warn about the use of Java
975 * context ClassLoaders and then fall through to use the
976 * system ClassLoader.
977 *
978 * <p> Note that this is similar to but not the same as the
979 * android.content.Context.getClassLoader(). While both
980 * context class loaders are typically set to the
981 * PathClassLoader used to load the package archive in the
982 * single application per VM case, a single Android process
983 * may contain several Contexts executing on one thread with
984 * their own logical ClassLoaders while the Java context
985 * ClassLoader is a thread local. This is why in the case when
986 * we have multiple packages per VM we do not set the Java
987 * context ClassLoader to an arbitrary but instead warn the
988 * user to set their own if we detect that they are using a
989 * Java library that expects it to be set.
990 */
991 private void initializeJavaContextClassLoader() {
992 IPackageManager pm = ActivityThread.getPackageManager();
993 android.content.pm.PackageInfo pi;
994 try {
Jeff Sharkeyc7bacab2016-02-09 15:56:11 -0700995 pi = pm.getPackageInfo(mPackageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
996 UserHandle.myUserId());
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700997 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -0700998 throw e.rethrowFromSystemServer();
Dianne Hackborn208d9372013-02-25 13:17:54 -0800999 }
1000 if (pi == null) {
1001 throw new IllegalStateException("Unable to get package info for "
1002 + mPackageName + "; is package not installed?");
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001003 }
1004 /*
1005 * Two possible indications that this package could be
1006 * sharing its virtual machine with other packages:
1007 *
1008 * 1.) the sharedUserId attribute is set in the manifest,
1009 * indicating a request to share a VM with other
1010 * packages with the same sharedUserId.
1011 *
1012 * 2.) the application element of the manifest has an
1013 * attribute specifying a non-default process name,
1014 * indicating the desire to run in another packages VM.
1015 */
1016 boolean sharedUserIdSet = (pi.sharedUserId != null);
1017 boolean processNameNotDefault =
1018 (pi.applicationInfo != null &&
1019 !mPackageName.equals(pi.applicationInfo.processName));
1020 boolean sharable = (sharedUserIdSet || processNameNotDefault);
1021 ClassLoader contextClassLoader =
1022 (sharable)
1023 ? new WarningContextClassLoader()
1024 : mClassLoader;
1025 Thread.currentThread().setContextClassLoader(contextClassLoader);
1026 }
1027
1028 private static class WarningContextClassLoader extends ClassLoader {
1029
1030 private static boolean warned = false;
1031
1032 private void warn(String methodName) {
1033 if (warned) {
1034 return;
1035 }
1036 warned = true;
1037 Thread.currentThread().setContextClassLoader(getParent());
1038 Slog.w(ActivityThread.TAG, "ClassLoader." + methodName + ": " +
1039 "The class loader returned by " +
1040 "Thread.getContextClassLoader() may fail for processes " +
1041 "that host multiple applications. You should explicitly " +
1042 "specify a context class loader. For example: " +
1043 "Thread.setContextClassLoader(getClass().getClassLoader());");
1044 }
1045
1046 @Override public URL getResource(String resName) {
1047 warn("getResource");
1048 return getParent().getResource(resName);
1049 }
1050
1051 @Override public Enumeration<URL> getResources(String resName) throws IOException {
1052 warn("getResources");
1053 return getParent().getResources(resName);
1054 }
1055
1056 @Override public InputStream getResourceAsStream(String resName) {
1057 warn("getResourceAsStream");
1058 return getParent().getResourceAsStream(resName);
1059 }
1060
1061 @Override public Class<?> loadClass(String className) throws ClassNotFoundException {
1062 warn("loadClass");
1063 return getParent().loadClass(className);
1064 }
1065
1066 @Override public void setClassAssertionStatus(String cname, boolean enable) {
1067 warn("setClassAssertionStatus");
1068 getParent().setClassAssertionStatus(cname, enable);
1069 }
1070
1071 @Override public void setPackageAssertionStatus(String pname, boolean enable) {
1072 warn("setPackageAssertionStatus");
1073 getParent().setPackageAssertionStatus(pname, enable);
1074 }
1075
1076 @Override public void setDefaultAssertionStatus(boolean enable) {
1077 warn("setDefaultAssertionStatus");
1078 getParent().setDefaultAssertionStatus(enable);
1079 }
1080
1081 @Override public void clearAssertionStatus() {
1082 warn("clearAssertionStatus");
1083 getParent().clearAssertionStatus();
1084 }
1085 }
1086
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001087 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001088 public String getAppDir() {
1089 return mAppDir;
1090 }
1091
Brian Carlstromd893a892012-04-01 21:30:26 -07001092 public String getLibDir() {
1093 return mLibDir;
1094 }
1095
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001096 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001097 public String getResDir() {
1098 return mResDir;
1099 }
1100
Jeff Sharkey8a4c9722014-06-16 13:48:42 -07001101 public String[] getSplitAppDirs() {
1102 return mSplitAppDirs;
1103 }
1104
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001105 @UnsupportedAppUsage
Jeff Sharkey8a4c9722014-06-16 13:48:42 -07001106 public String[] getSplitResDirs() {
1107 return mSplitResDirs;
1108 }
1109
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001110 @UnsupportedAppUsage
MÃ¥rten Kongstad48d22322014-01-31 14:43:27 +01001111 public String[] getOverlayDirs() {
1112 return mOverlayDirs;
1113 }
1114
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001115 public String getDataDir() {
1116 return mDataDir;
1117 }
1118
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001119 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001120 public File getDataDirFile() {
1121 return mDataDirFile;
1122 }
1123
Jeff Sharkey8a372a02016-03-16 16:25:45 -06001124 public File getDeviceProtectedDataDirFile() {
1125 return mDeviceProtectedDataDirFile;
Jeff Sharkey15447792015-11-05 16:18:51 -08001126 }
1127
Jeff Sharkey8a372a02016-03-16 16:25:45 -06001128 public File getCredentialProtectedDataDirFile() {
1129 return mCredentialProtectedDataDirFile;
Jeff Sharkey15447792015-11-05 16:18:51 -08001130 }
1131
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001132 @UnsupportedAppUsage
Adam Lesinski4e862812016-11-21 16:02:24 -08001133 public AssetManager getAssets() {
1134 return getResources().getAssets();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001135 }
1136
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001137 @UnsupportedAppUsage
Adam Lesinski4e862812016-11-21 16:02:24 -08001138 public Resources getResources() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001139 if (mResources == null) {
Adam Lesinski4e862812016-11-21 16:02:24 -08001140 final String[] splitPaths;
1141 try {
1142 splitPaths = getSplitPaths(null);
Adam Lesinski1665d0f2017-03-10 14:46:57 -08001143 } catch (NameNotFoundException e) {
Adam Lesinski4e862812016-11-21 16:02:24 -08001144 // This should never fail.
1145 throw new AssertionError("null split not found");
1146 }
1147
Todd Kennedy233a0b12018-01-29 20:30:24 +00001148 mResources = ResourcesManager.getInstance().getResources(null, mResDir,
1149 splitPaths, mOverlayDirs, mApplicationInfo.sharedLibraryFiles,
1150 Display.DEFAULT_DISPLAY, null, getCompatibilityInfo(),
Adam Lesinski4e862812016-11-21 16:02:24 -08001151 getClassLoader());
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001152 }
1153 return mResources;
1154 }
1155
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001156 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001157 public Application makeApplication(boolean forceDefaultAppClass,
1158 Instrumentation instrumentation) {
1159 if (mApplication != null) {
1160 return mApplication;
1161 }
1162
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001163 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");
1164
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001165 Application app = null;
1166
1167 String appClass = mApplicationInfo.className;
1168 if (forceDefaultAppClass || (appClass == null)) {
1169 appClass = "android.app.Application";
1170 }
1171
1172 try {
1173 java.lang.ClassLoader cl = getClassLoader();
Narayan Kamath8091edb2014-10-15 11:38:44 +01001174 if (!mPackageName.equals("android")) {
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001175 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
1176 "initializeJavaContextClassLoader");
Narayan Kamath8091edb2014-10-15 11:38:44 +01001177 initializeJavaContextClassLoader();
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001178 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Narayan Kamath8091edb2014-10-15 11:38:44 +01001179 }
Jeff Browndefd4a62014-03-10 21:24:37 -07001180 ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001181 app = mActivityThread.mInstrumentation.newApplication(
1182 cl, appClass, appContext);
1183 appContext.setOuterContext(app);
1184 } catch (Exception e) {
1185 if (!mActivityThread.mInstrumentation.onException(app, e)) {
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001186 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001187 throw new RuntimeException(
1188 "Unable to instantiate application " + appClass
1189 + ": " + e.toString(), e);
1190 }
1191 }
1192 mActivityThread.mAllApplications.add(app);
1193 mApplication = app;
1194
1195 if (instrumentation != null) {
1196 try {
1197 instrumentation.callApplicationOnCreate(app);
1198 } catch (Exception e) {
1199 if (!instrumentation.onException(app, e)) {
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001200 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001201 throw new RuntimeException(
1202 "Unable to create application " + app.getClass().getName()
1203 + ": " + e.toString(), e);
1204 }
1205 }
1206 }
Adam Lesinskide898ff2014-01-29 18:20:45 -08001207
1208 // Rewrite the R 'constants' for all library apks.
Adam Lesinski4e862812016-11-21 16:02:24 -08001209 SparseArray<String> packageIdentifiers = getAssets().getAssignedPackageIdentifiers();
Adam Lesinskide898ff2014-01-29 18:20:45 -08001210 final int N = packageIdentifiers.size();
1211 for (int i = 0; i < N; i++) {
1212 final int id = packageIdentifiers.keyAt(i);
1213 if (id == 0x01 || id == 0x7f) {
1214 continue;
1215 }
1216
1217 rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);
1218 }
1219
Andreas Gampe4c8e5422016-05-18 11:58:47 -07001220 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1221
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001222 return app;
1223 }
1224
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001225 @UnsupportedAppUsage
Adam Lesinskide898ff2014-01-29 18:20:45 -08001226 private void rewriteRValues(ClassLoader cl, String packageName, int id) {
Adam Lesinski2cb761e2014-08-15 13:59:02 -07001227 final Class<?> rClazz;
Adam Lesinskide898ff2014-01-29 18:20:45 -08001228 try {
Adam Lesinski2cb761e2014-08-15 13:59:02 -07001229 rClazz = cl.loadClass(packageName + ".R");
1230 } catch (ClassNotFoundException e) {
1231 // This is not necessarily an error, as some packages do not ship with resources
1232 // (or they do not need rewriting).
Adam Lesinski1e4663852014-08-15 14:47:28 -07001233 Log.i(TAG, "No resource references to update in package " + packageName);
Adam Lesinski2cb761e2014-08-15 13:59:02 -07001234 return;
1235 }
1236
Adam Lesinski1e4663852014-08-15 14:47:28 -07001237 final Method callback;
Adam Lesinski2cb761e2014-08-15 13:59:02 -07001238 try {
Adam Lesinski1e4663852014-08-15 14:47:28 -07001239 callback = rClazz.getMethod("onResourcesLoaded", int.class);
1240 } catch (NoSuchMethodException e) {
1241 // No rewriting to be done.
1242 return;
Adam Lesinskide898ff2014-01-29 18:20:45 -08001243 }
Adam Lesinski1e4663852014-08-15 14:47:28 -07001244
1245 Throwable cause;
1246 try {
1247 callback.invoke(null, id);
1248 return;
1249 } catch (IllegalAccessException e) {
1250 cause = e;
1251 } catch (InvocationTargetException e) {
1252 cause = e.getCause();
1253 }
1254
1255 throw new RuntimeException("Failed to rewrite resource references for " + packageName,
1256 cause);
Adam Lesinskide898ff2014-01-29 18:20:45 -08001257 }
1258
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001259 public void removeContextRegistrations(Context context,
1260 String who, String what) {
Jeff Sharkeyd7026f12012-03-01 20:50:32 -08001261 final boolean reportRegistrationLeaks = StrictMode.vmRegistrationLeaksEnabled();
Adam Lesinski23d40c42014-11-20 11:58:21 -08001262 synchronized (mReceivers) {
1263 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> rmap =
1264 mReceivers.remove(context);
1265 if (rmap != null) {
1266 for (int i = 0; i < rmap.size(); i++) {
1267 LoadedApk.ReceiverDispatcher rd = rmap.valueAt(i);
1268 IntentReceiverLeaked leak = new IntentReceiverLeaked(
1269 what + " " + who + " has leaked IntentReceiver "
1270 + rd.getIntentReceiver() + " that was " +
1271 "originally registered here. Are you missing a " +
1272 "call to unregisterReceiver()?");
1273 leak.setStackTrace(rd.getLocation().getStackTrace());
1274 Slog.e(ActivityThread.TAG, leak.getMessage(), leak);
1275 if (reportRegistrationLeaks) {
1276 StrictMode.onIntentReceiverLeaked(leak);
1277 }
1278 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001279 ActivityManager.getService().unregisterReceiver(
Adam Lesinski23d40c42014-11-20 11:58:21 -08001280 rd.getIIntentReceiver());
1281 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001282 throw e.rethrowFromSystemServer();
Adam Lesinski23d40c42014-11-20 11:58:21 -08001283 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001284 }
1285 }
Adam Lesinski23d40c42014-11-20 11:58:21 -08001286 mUnregisteredReceivers.remove(context);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001287 }
Adam Lesinski23d40c42014-11-20 11:58:21 -08001288
1289 synchronized (mServices) {
1290 //Slog.i(TAG, "Receiver registrations: " + mReceivers);
1291 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> smap =
1292 mServices.remove(context);
1293 if (smap != null) {
1294 for (int i = 0; i < smap.size(); i++) {
1295 LoadedApk.ServiceDispatcher sd = smap.valueAt(i);
1296 ServiceConnectionLeaked leak = new ServiceConnectionLeaked(
1297 what + " " + who + " has leaked ServiceConnection "
1298 + sd.getServiceConnection() + " that was originally bound here");
1299 leak.setStackTrace(sd.getLocation().getStackTrace());
1300 Slog.e(ActivityThread.TAG, leak.getMessage(), leak);
1301 if (reportRegistrationLeaks) {
1302 StrictMode.onServiceConnectionLeaked(leak);
1303 }
1304 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001305 ActivityManager.getService().unbindService(
Adam Lesinski23d40c42014-11-20 11:58:21 -08001306 sd.getIServiceConnection());
1307 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001308 throw e.rethrowFromSystemServer();
Adam Lesinski23d40c42014-11-20 11:58:21 -08001309 }
1310 sd.doForget();
Jeff Sharkeyd7026f12012-03-01 20:50:32 -08001311 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001312 }
Adam Lesinski23d40c42014-11-20 11:58:21 -08001313 mUnboundServices.remove(context);
1314 //Slog.i(TAG, "Service registrations: " + mServices);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001315 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001316 }
1317
1318 public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r,
1319 Context context, Handler handler,
1320 Instrumentation instrumentation, boolean registered) {
1321 synchronized (mReceivers) {
1322 LoadedApk.ReceiverDispatcher rd = null;
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001323 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001324 if (registered) {
1325 map = mReceivers.get(context);
1326 if (map != null) {
1327 rd = map.get(r);
1328 }
1329 }
1330 if (rd == null) {
1331 rd = new ReceiverDispatcher(r, context, handler,
1332 instrumentation, registered);
1333 if (registered) {
1334 if (map == null) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001335 map = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001336 mReceivers.put(context, map);
1337 }
1338 map.put(r, rd);
1339 }
1340 } else {
1341 rd.validate(context, handler);
1342 }
Dianne Hackbornc2d9c8e2011-01-24 21:59:21 -08001343 rd.mForgotten = false;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001344 return rd.getIIntentReceiver();
1345 }
1346 }
1347
1348 public IIntentReceiver forgetReceiverDispatcher(Context context,
1349 BroadcastReceiver r) {
1350 synchronized (mReceivers) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001351 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = mReceivers.get(context);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001352 LoadedApk.ReceiverDispatcher rd = null;
1353 if (map != null) {
1354 rd = map.get(r);
1355 if (rd != null) {
1356 map.remove(r);
1357 if (map.size() == 0) {
1358 mReceivers.remove(context);
1359 }
1360 if (r.getDebugUnregister()) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001361 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> holder
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001362 = mUnregisteredReceivers.get(context);
1363 if (holder == null) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001364 holder = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001365 mUnregisteredReceivers.put(context, holder);
1366 }
1367 RuntimeException ex = new IllegalArgumentException(
1368 "Originally unregistered here:");
1369 ex.fillInStackTrace();
1370 rd.setUnregisterLocation(ex);
1371 holder.put(r, rd);
1372 }
Dianne Hackbornc2d9c8e2011-01-24 21:59:21 -08001373 rd.mForgotten = true;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001374 return rd.getIIntentReceiver();
1375 }
1376 }
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001377 ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> holder
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001378 = mUnregisteredReceivers.get(context);
1379 if (holder != null) {
1380 rd = holder.get(r);
1381 if (rd != null) {
1382 RuntimeException ex = rd.getUnregisterLocation();
1383 throw new IllegalArgumentException(
1384 "Unregistering Receiver " + r
1385 + " that was already unregistered", ex);
1386 }
1387 }
1388 if (context == null) {
1389 throw new IllegalStateException("Unbinding Receiver " + r
1390 + " from Context that is no longer in use: " + context);
1391 } else {
1392 throw new IllegalArgumentException("Receiver not registered: " + r);
1393 }
1394
1395 }
1396 }
1397
1398 static final class ReceiverDispatcher {
1399
1400 final static class InnerReceiver extends IIntentReceiver.Stub {
1401 final WeakReference<LoadedApk.ReceiverDispatcher> mDispatcher;
1402 final LoadedApk.ReceiverDispatcher mStrongRef;
1403
1404 InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) {
1405 mDispatcher = new WeakReference<LoadedApk.ReceiverDispatcher>(rd);
1406 mStrongRef = strong ? rd : null;
1407 }
Jeff Sharkeyd136e512016-03-09 22:30:56 -07001408
1409 @Override
Dianne Hackborn20e80982012-08-31 19:00:44 -07001410 public void performReceive(Intent intent, int resultCode, String data,
1411 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
Dianne Hackborn26756162016-05-17 13:40:44 -07001412 final LoadedApk.ReceiverDispatcher rd;
1413 if (intent == null) {
1414 Log.wtf(TAG, "Null intent received");
1415 rd = null;
1416 } else {
1417 rd = mDispatcher.get();
1418 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001419 if (ActivityThread.DEBUG_BROADCAST) {
1420 int seq = intent.getIntExtra("seq", -1);
Dianne Hackborn26756162016-05-17 13:40:44 -07001421 Slog.i(ActivityThread.TAG, "Receiving broadcast " + intent.getAction()
1422 + " seq=" + seq + " to " + (rd != null ? rd.mReceiver : null));
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001423 }
1424 if (rd != null) {
1425 rd.performReceive(intent, resultCode, data, extras,
Dianne Hackborn20e80982012-08-31 19:00:44 -07001426 ordered, sticky, sendingUser);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001427 } else {
1428 // The activity manager dispatched a broadcast to a registered
1429 // receiver in this process, but before it could be delivered the
1430 // receiver was unregistered. Acknowledge the broadcast on its
1431 // behalf so that the system's broadcast sequence can continue.
1432 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1433 "Finishing broadcast to unregistered receiver");
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001434 IActivityManager mgr = ActivityManager.getService();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001435 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001436 if (extras != null) {
1437 extras.setAllowFds(false);
1438 }
riddle_hsu1f5ac4d2015-01-03 15:38:21 +08001439 mgr.finishReceiver(this, resultCode, data, extras, false, intent.getFlags());
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001440 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07001441 throw e.rethrowFromSystemServer();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001442 }
1443 }
1444 }
1445 }
1446
1447 final IIntentReceiver.Stub mIIntentReceiver;
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001448 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001449 final BroadcastReceiver mReceiver;
Mathew Inwood45d2c252018-09-14 12:35:36 +01001450 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001451 final Context mContext;
1452 final Handler mActivityThread;
1453 final Instrumentation mInstrumentation;
1454 final boolean mRegistered;
1455 final IntentReceiverLeaked mLocation;
1456 RuntimeException mUnregisterLocation;
Dianne Hackbornc2d9c8e2011-01-24 21:59:21 -08001457 boolean mForgotten;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001458
Makoto Onuki08408b92017-05-09 13:48:53 -07001459 final class Args extends BroadcastReceiver.PendingResult {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001460 private Intent mCurIntent;
Dianne Hackborne829fef2010-10-26 17:44:01 -07001461 private final boolean mOrdered;
Dianne Hackborn17c77532016-06-22 16:49:14 -07001462 private boolean mDispatched;
Makoto Onukif3bb6f32017-05-02 12:02:23 -07001463 private Throwable mPreviousRunStacktrace; // To investigate b/37809561. STOPSHIP remove.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001464
Dianne Hackborne829fef2010-10-26 17:44:01 -07001465 public Args(Intent intent, int resultCode, String resultData, Bundle resultExtras,
Dianne Hackborn20e80982012-08-31 19:00:44 -07001466 boolean ordered, boolean sticky, int sendingUser) {
Dianne Hackborne829fef2010-10-26 17:44:01 -07001467 super(resultCode, resultData, resultExtras,
riddle_hsu1f5ac4d2015-01-03 15:38:21 +08001468 mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED, ordered,
1469 sticky, mIIntentReceiver.asBinder(), sendingUser, intent.getFlags());
Dianne Hackborne829fef2010-10-26 17:44:01 -07001470 mCurIntent = intent;
1471 mOrdered = ordered;
1472 }
Dianne Hackborn17c77532016-06-22 16:49:14 -07001473
Makoto Onuki08408b92017-05-09 13:48:53 -07001474 public final Runnable getRunnable() {
1475 return () -> {
1476 final BroadcastReceiver receiver = mReceiver;
1477 final boolean ordered = mOrdered;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001478
Makoto Onuki08408b92017-05-09 13:48:53 -07001479 if (ActivityThread.DEBUG_BROADCAST) {
1480 int seq = mCurIntent.getIntExtra("seq", -1);
1481 Slog.i(ActivityThread.TAG, "Dispatching broadcast " + mCurIntent.getAction()
1482 + " seq=" + seq + " to " + mReceiver);
1483 Slog.i(ActivityThread.TAG, " mRegistered=" + mRegistered
1484 + " mOrderedHint=" + ordered);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001485 }
Makoto Onuki08408b92017-05-09 13:48:53 -07001486
1487 final IActivityManager mgr = ActivityManager.getService();
1488 final Intent intent = mCurIntent;
1489 if (intent == null) {
1490 Log.wtf(TAG, "Null intent being dispatched, mDispatched=" + mDispatched
1491 + ": run() previously called at "
1492 + Log.getStackTraceString(mPreviousRunStacktrace));
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001493 }
Makoto Onuki08408b92017-05-09 13:48:53 -07001494
1495 mCurIntent = null;
1496 mDispatched = true;
1497 mPreviousRunStacktrace = new Throwable("Previous stacktrace");
1498 if (receiver == null || intent == null || mForgotten) {
1499 if (mRegistered && ordered) {
1500 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1501 "Finishing null broadcast to " + mReceiver);
1502 sendFinished(mgr);
1503 }
1504 return;
1505 }
1506
1507 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveReg");
1508 try {
1509 ClassLoader cl = mReceiver.getClass().getClassLoader();
1510 intent.setExtrasClassLoader(cl);
1511 intent.prepareToEnterProcess();
1512 setExtrasClassLoader(cl);
1513 receiver.setPendingResult(this);
1514 receiver.onReceive(mContext, intent);
1515 } catch (Exception e) {
1516 if (mRegistered && ordered) {
1517 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1518 "Finishing failed broadcast to " + mReceiver);
1519 sendFinished(mgr);
1520 }
1521 if (mInstrumentation == null ||
1522 !mInstrumentation.onException(mReceiver, e)) {
1523 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1524 throw new RuntimeException(
1525 "Error receiving broadcast " + intent
1526 + " in " + mReceiver, e);
1527 }
1528 }
1529
1530 if (receiver.getPendingResult() != null) {
1531 finish();
1532 }
1533 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1534 };
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001535 }
1536 }
1537
1538 ReceiverDispatcher(BroadcastReceiver receiver, Context context,
1539 Handler activityThread, Instrumentation instrumentation,
1540 boolean registered) {
1541 if (activityThread == null) {
1542 throw new NullPointerException("Handler must not be null");
1543 }
1544
1545 mIIntentReceiver = new InnerReceiver(this, !registered);
1546 mReceiver = receiver;
1547 mContext = context;
1548 mActivityThread = activityThread;
1549 mInstrumentation = instrumentation;
1550 mRegistered = registered;
1551 mLocation = new IntentReceiverLeaked(null);
1552 mLocation.fillInStackTrace();
1553 }
1554
1555 void validate(Context context, Handler activityThread) {
1556 if (mContext != context) {
1557 throw new IllegalStateException(
1558 "Receiver " + mReceiver +
1559 " registered with differing Context (was " +
1560 mContext + " now " + context + ")");
1561 }
1562 if (mActivityThread != activityThread) {
1563 throw new IllegalStateException(
1564 "Receiver " + mReceiver +
1565 " registered with differing handler (was " +
1566 mActivityThread + " now " + activityThread + ")");
1567 }
1568 }
1569
1570 IntentReceiverLeaked getLocation() {
1571 return mLocation;
1572 }
1573
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001574 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001575 BroadcastReceiver getIntentReceiver() {
1576 return mReceiver;
1577 }
1578
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001579 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001580 IIntentReceiver getIIntentReceiver() {
1581 return mIIntentReceiver;
1582 }
1583
1584 void setUnregisterLocation(RuntimeException ex) {
1585 mUnregisterLocation = ex;
1586 }
1587
1588 RuntimeException getUnregisterLocation() {
1589 return mUnregisterLocation;
1590 }
1591
Dianne Hackborn20e80982012-08-31 19:00:44 -07001592 public void performReceive(Intent intent, int resultCode, String data,
1593 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
Dianne Hackborn41bfaf82016-06-08 16:33:29 -07001594 final Args args = new Args(intent, resultCode, data, extras, ordered,
Dianne Hackborn20e80982012-08-31 19:00:44 -07001595 sticky, sendingUser);
Dianne Hackborn41bfaf82016-06-08 16:33:29 -07001596 if (intent == null) {
1597 Log.wtf(TAG, "Null intent received");
1598 } else {
1599 if (ActivityThread.DEBUG_BROADCAST) {
1600 int seq = intent.getIntExtra("seq", -1);
1601 Slog.i(ActivityThread.TAG, "Enqueueing broadcast " + intent.getAction()
1602 + " seq=" + seq + " to " + mReceiver);
1603 }
1604 }
Makoto Onuki08408b92017-05-09 13:48:53 -07001605 if (intent == null || !mActivityThread.post(args.getRunnable())) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001606 if (mRegistered && ordered) {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001607 IActivityManager mgr = ActivityManager.getService();
Dianne Hackborne829fef2010-10-26 17:44:01 -07001608 if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
1609 "Finishing sync broadcast to " + mReceiver);
1610 args.sendFinished(mgr);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001611 }
1612 }
1613 }
1614
1615 }
1616
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001617 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001618 public final IServiceConnection getServiceDispatcher(ServiceConnection c,
1619 Context context, Handler handler, int flags) {
1620 synchronized (mServices) {
1621 LoadedApk.ServiceDispatcher sd = null;
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001622 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001623 if (map != null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001624 if (DEBUG) Slog.d(TAG, "Returning existing dispatcher " + sd + " for conn " + c);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001625 sd = map.get(c);
1626 }
1627 if (sd == null) {
1628 sd = new ServiceDispatcher(c, context, handler, flags);
Dianne Hackborn94846032017-03-31 17:55:23 -07001629 if (DEBUG) Slog.d(TAG, "Creating new dispatcher " + sd + " for conn " + c);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001630 if (map == null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001631 map = new ArrayMap<>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001632 mServices.put(context, map);
1633 }
1634 map.put(c, sd);
1635 } else {
1636 sd.validate(context, handler);
1637 }
1638 return sd.getIServiceConnection();
1639 }
1640 }
1641
1642 public final IServiceConnection forgetServiceDispatcher(Context context,
1643 ServiceConnection c) {
1644 synchronized (mServices) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001645 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001646 = mServices.get(context);
1647 LoadedApk.ServiceDispatcher sd = null;
1648 if (map != null) {
1649 sd = map.get(c);
1650 if (sd != null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001651 if (DEBUG) Slog.d(TAG, "Removing dispatcher " + sd + " for conn " + c);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001652 map.remove(c);
1653 sd.doForget();
1654 if (map.size() == 0) {
1655 mServices.remove(context);
1656 }
1657 if ((sd.getFlags()&Context.BIND_DEBUG_UNBIND) != 0) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001658 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> holder
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001659 = mUnboundServices.get(context);
1660 if (holder == null) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001661 holder = new ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001662 mUnboundServices.put(context, holder);
1663 }
1664 RuntimeException ex = new IllegalArgumentException(
1665 "Originally unbound here:");
1666 ex.fillInStackTrace();
1667 sd.setUnbindLocation(ex);
1668 holder.put(c, sd);
1669 }
1670 return sd.getIServiceConnection();
1671 }
1672 }
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001673 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> holder
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001674 = mUnboundServices.get(context);
1675 if (holder != null) {
1676 sd = holder.get(c);
1677 if (sd != null) {
1678 RuntimeException ex = sd.getUnbindLocation();
1679 throw new IllegalArgumentException(
1680 "Unbinding Service " + c
1681 + " that was already unbound", ex);
1682 }
1683 }
1684 if (context == null) {
1685 throw new IllegalStateException("Unbinding Service " + c
1686 + " from Context that is no longer in use: " + context);
1687 } else {
1688 throw new IllegalArgumentException("Service not registered: " + c);
1689 }
1690 }
1691 }
1692
1693 static final class ServiceDispatcher {
1694 private final ServiceDispatcher.InnerConnection mIServiceConnection;
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001695 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001696 private final ServiceConnection mConnection;
Mathew Inwood45d2c252018-09-14 12:35:36 +01001697 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001698 private final Context mContext;
1699 private final Handler mActivityThread;
1700 private final ServiceConnectionLeaked mLocation;
1701 private final int mFlags;
1702
1703 private RuntimeException mUnbindLocation;
1704
Dianne Hackborn5a6ef732011-11-11 12:31:52 -08001705 private boolean mForgotten;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001706
1707 private static class ConnectionInfo {
1708 IBinder binder;
1709 IBinder.DeathRecipient deathMonitor;
1710 }
1711
1712 private static class InnerConnection extends IServiceConnection.Stub {
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001713 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001714 final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;
1715
1716 InnerConnection(LoadedApk.ServiceDispatcher sd) {
1717 mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
1718 }
1719
Dianne Hackborn94846032017-03-31 17:55:23 -07001720 public void connected(ComponentName name, IBinder service, boolean dead)
1721 throws RemoteException {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001722 LoadedApk.ServiceDispatcher sd = mDispatcher.get();
1723 if (sd != null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001724 sd.connected(name, service, dead);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001725 }
1726 }
1727 }
1728
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001729 private final ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo> mActiveConnections
1730 = new ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001731
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001732 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001733 ServiceDispatcher(ServiceConnection conn,
1734 Context context, Handler activityThread, int flags) {
1735 mIServiceConnection = new InnerConnection(this);
1736 mConnection = conn;
1737 mContext = context;
1738 mActivityThread = activityThread;
1739 mLocation = new ServiceConnectionLeaked(null);
1740 mLocation.fillInStackTrace();
1741 mFlags = flags;
1742 }
1743
1744 void validate(Context context, Handler activityThread) {
1745 if (mContext != context) {
1746 throw new RuntimeException(
1747 "ServiceConnection " + mConnection +
1748 " registered with differing Context (was " +
1749 mContext + " now " + context + ")");
1750 }
1751 if (mActivityThread != activityThread) {
1752 throw new RuntimeException(
1753 "ServiceConnection " + mConnection +
1754 " registered with differing handler (was " +
1755 mActivityThread + " now " + activityThread + ")");
1756 }
1757 }
1758
1759 void doForget() {
1760 synchronized(this) {
Dianne Hackbornadd005c2013-07-17 18:43:12 -07001761 for (int i=0; i<mActiveConnections.size(); i++) {
1762 ServiceDispatcher.ConnectionInfo ci = mActiveConnections.valueAt(i);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001763 ci.binder.unlinkToDeath(ci.deathMonitor, 0);
1764 }
1765 mActiveConnections.clear();
Dianne Hackborn5a6ef732011-11-11 12:31:52 -08001766 mForgotten = true;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001767 }
1768 }
1769
1770 ServiceConnectionLeaked getLocation() {
1771 return mLocation;
1772 }
1773
1774 ServiceConnection getServiceConnection() {
1775 return mConnection;
1776 }
1777
Mathew Inwood4fb17d12018-08-14 14:25:44 +01001778 @UnsupportedAppUsage
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001779 IServiceConnection getIServiceConnection() {
1780 return mIServiceConnection;
1781 }
1782
1783 int getFlags() {
1784 return mFlags;
1785 }
1786
1787 void setUnbindLocation(RuntimeException ex) {
1788 mUnbindLocation = ex;
1789 }
1790
1791 RuntimeException getUnbindLocation() {
1792 return mUnbindLocation;
1793 }
1794
Dianne Hackborn94846032017-03-31 17:55:23 -07001795 public void connected(ComponentName name, IBinder service, boolean dead) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001796 if (mActivityThread != null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001797 mActivityThread.post(new RunConnection(name, service, 0, dead));
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001798 } else {
Dianne Hackborn94846032017-03-31 17:55:23 -07001799 doConnected(name, service, dead);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001800 }
1801 }
1802
1803 public void death(ComponentName name, IBinder service) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001804 if (mActivityThread != null) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001805 mActivityThread.post(new RunConnection(name, service, 1, false));
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001806 } else {
1807 doDeath(name, service);
1808 }
1809 }
1810
Dianne Hackborn94846032017-03-31 17:55:23 -07001811 public void doConnected(ComponentName name, IBinder service, boolean dead) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001812 ServiceDispatcher.ConnectionInfo old;
1813 ServiceDispatcher.ConnectionInfo info;
1814
1815 synchronized (this) {
Dianne Hackborn5a6ef732011-11-11 12:31:52 -08001816 if (mForgotten) {
1817 // We unbound before receiving the connection; ignore
1818 // any connection received.
1819 return;
1820 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001821 old = mActiveConnections.get(name);
1822 if (old != null && old.binder == service) {
1823 // Huh, already have this one. Oh well!
1824 return;
1825 }
1826
1827 if (service != null) {
1828 // A new service is being connected... set it all up.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001829 info = new ConnectionInfo();
1830 info.binder = service;
1831 info.deathMonitor = new DeathMonitor(name, service);
1832 try {
1833 service.linkToDeath(info.deathMonitor, 0);
1834 mActiveConnections.put(name, info);
1835 } catch (RemoteException e) {
1836 // This service was dead before we got it... just
1837 // don't do anything with it.
1838 mActiveConnections.remove(name);
1839 return;
1840 }
1841
1842 } else {
1843 // The named service is being disconnected... clean up.
1844 mActiveConnections.remove(name);
1845 }
1846
1847 if (old != null) {
1848 old.binder.unlinkToDeath(old.deathMonitor, 0);
1849 }
1850 }
1851
Adrian Roosa9b43182016-07-21 13:20:38 -07001852 // If there was an old service, it is now disconnected.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001853 if (old != null) {
1854 mConnection.onServiceDisconnected(name);
1855 }
Dianne Hackborn94846032017-03-31 17:55:23 -07001856 if (dead) {
Dianne Hackbornac265342017-04-19 14:53:18 -07001857 mConnection.onBindingDied(name);
Dianne Hackborn94846032017-03-31 17:55:23 -07001858 }
Christopher Tate5d73b6d2017-10-06 16:15:34 -07001859 // If there is a new viable service, it is now connected.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001860 if (service != null) {
1861 mConnection.onServiceConnected(name, service);
Christopher Tate5d73b6d2017-10-06 16:15:34 -07001862 } else {
1863 // The binding machinery worked, but the remote returned null from onBind().
1864 mConnection.onNullBinding(name);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001865 }
1866 }
1867
1868 public void doDeath(ComponentName name, IBinder service) {
Adrian Roosa9b43182016-07-21 13:20:38 -07001869 synchronized (this) {
1870 ConnectionInfo old = mActiveConnections.get(name);
1871 if (old == null || old.binder != service) {
1872 // Death for someone different than who we last
1873 // reported... just ignore it.
1874 return;
1875 }
1876 mActiveConnections.remove(name);
1877 old.binder.unlinkToDeath(old.deathMonitor, 0);
1878 }
1879
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001880 mConnection.onServiceDisconnected(name);
1881 }
1882
1883 private final class RunConnection implements Runnable {
Dianne Hackborn94846032017-03-31 17:55:23 -07001884 RunConnection(ComponentName name, IBinder service, int command, boolean dead) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001885 mName = name;
1886 mService = service;
1887 mCommand = command;
Dianne Hackborn94846032017-03-31 17:55:23 -07001888 mDead = dead;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001889 }
1890
1891 public void run() {
1892 if (mCommand == 0) {
Dianne Hackborn94846032017-03-31 17:55:23 -07001893 doConnected(mName, mService, mDead);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001894 } else if (mCommand == 1) {
1895 doDeath(mName, mService);
1896 }
1897 }
1898
1899 final ComponentName mName;
1900 final IBinder mService;
1901 final int mCommand;
Dianne Hackborn94846032017-03-31 17:55:23 -07001902 final boolean mDead;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001903 }
1904
1905 private final class DeathMonitor implements IBinder.DeathRecipient
1906 {
1907 DeathMonitor(ComponentName name, IBinder service) {
1908 mName = name;
1909 mService = service;
1910 }
1911
1912 public void binderDied() {
1913 death(mName, mService);
1914 }
1915
1916 final ComponentName mName;
1917 final IBinder mService;
1918 }
1919 }
1920}