Merge "Minor LoadedApk refactoring." am: 6ca155f8c2

am: e6fee297a2

Change-Id: I919f7e7e11b64f6155919f7ea631f3f6fd84ce03
This commit is contained in:
Jeff Hamilton
2018-01-12 21:43:44 +00:00
committed by android-build-merger
5 changed files with 246 additions and 211 deletions

View File

@@ -366,7 +366,7 @@ public final class ActivityThread {
ActivityInfo activityInfo; ActivityInfo activityInfo;
CompatibilityInfo compatInfo; CompatibilityInfo compatInfo;
LoadedApk packageInfo; LoadedApk loadedApk;
List<ResultInfo> pendingResults; List<ResultInfo> pendingResults;
List<ReferrerIntent> pendingIntents; List<ReferrerIntent> pendingIntents;
@@ -542,7 +542,7 @@ public final class ActivityThread {
} }
static final class AppBindData { static final class AppBindData {
LoadedApk info; LoadedApk loadedApk;
String processName; String processName;
ApplicationInfo appInfo; ApplicationInfo appInfo;
List<ProviderInfo> providers; List<ProviderInfo> providers;
@@ -1584,7 +1584,7 @@ public final class ActivityThread {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj; final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck( r.loadedApk = getLoadedApkNoCheck(
r.activityInfo.applicationInfo, r.compatInfo); r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY"); handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
@@ -1971,13 +1971,13 @@ public final class ActivityThread {
return mH; return mH;
} }
public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo, public final LoadedApk getLoadedApkForPackageName(String packageName,
int flags) { CompatibilityInfo compatInfo, int flags) {
return getPackageInfo(packageName, compatInfo, flags, UserHandle.myUserId()); return getLoadedApkForPackageName(packageName, compatInfo, flags, UserHandle.myUserId());
} }
public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo, public final LoadedApk getLoadedApkForPackageName(String packageName,
int flags, int userId) { CompatibilityInfo compatInfo, int flags, int userId) {
final boolean differentUser = (UserHandle.myUserId() != userId); final boolean differentUser = (UserHandle.myUserId() != userId);
synchronized (mResourcesManager) { synchronized (mResourcesManager) {
WeakReference<LoadedApk> ref; WeakReference<LoadedApk> ref;
@@ -1990,13 +1990,13 @@ public final class ActivityThread {
ref = mResourcePackages.get(packageName); ref = mResourcePackages.get(packageName);
} }
LoadedApk packageInfo = ref != null ? ref.get() : null; LoadedApk loadedApk = ref != null ? ref.get() : null;
//Slog.i(TAG, "getPackageInfo " + packageName + ": " + packageInfo); //Slog.i(TAG, "getLoadedApkForPackageName " + packageName + ": " + loadedApk);
//if (packageInfo != null) Slog.i(TAG, "isUptoDate " + packageInfo.mResDir //if (loadedApk != null) Slog.i(TAG, "isUptoDate " + loadedApk.mResDir
// + ": " + packageInfo.mResources.getAssets().isUpToDate()); // + ": " + loadedApk.mResources.getAssets().isUpToDate());
if (packageInfo != null && (packageInfo.mResources == null if (loadedApk != null && (loadedApk.mResources == null
|| packageInfo.mResources.getAssets().isUpToDate())) { || loadedApk.mResources.getAssets().isUpToDate())) {
if (packageInfo.isSecurityViolation() if (loadedApk.isSecurityViolation()
&& (flags&Context.CONTEXT_IGNORE_SECURITY) == 0) { && (flags&Context.CONTEXT_IGNORE_SECURITY) == 0) {
throw new SecurityException( throw new SecurityException(
"Requesting code from " + packageName "Requesting code from " + packageName
@@ -2004,7 +2004,7 @@ public final class ActivityThread {
+ mBoundApplication.processName + mBoundApplication.processName
+ "/" + mBoundApplication.appInfo.uid); + "/" + mBoundApplication.appInfo.uid);
} }
return packageInfo; return loadedApk;
} }
} }
@@ -2019,13 +2019,13 @@ public final class ActivityThread {
} }
if (ai != null) { if (ai != null) {
return getPackageInfo(ai, compatInfo, flags); return getLoadedApk(ai, compatInfo, flags);
} }
return null; return null;
} }
public final LoadedApk getPackageInfo(ApplicationInfo ai, CompatibilityInfo compatInfo, public final LoadedApk getLoadedApk(ApplicationInfo ai, CompatibilityInfo compatInfo,
int flags) { int flags) {
boolean includeCode = (flags&Context.CONTEXT_INCLUDE_CODE) != 0; boolean includeCode = (flags&Context.CONTEXT_INCLUDE_CODE) != 0;
boolean securityViolation = includeCode && ai.uid != 0 boolean securityViolation = includeCode && ai.uid != 0
@@ -2047,16 +2047,16 @@ public final class ActivityThread {
throw new SecurityException(msg); throw new SecurityException(msg);
} }
} }
return getPackageInfo(ai, compatInfo, null, securityViolation, includeCode, return getLoadedApk(ai, compatInfo, null, securityViolation, includeCode,
registerPackage); registerPackage);
} }
public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai, public final LoadedApk getLoadedApkNoCheck(ApplicationInfo ai,
CompatibilityInfo compatInfo) { CompatibilityInfo compatInfo) {
return getPackageInfo(ai, compatInfo, null, false, true, false); return getLoadedApk(ai, compatInfo, null, false, true, false);
} }
public final LoadedApk peekPackageInfo(String packageName, boolean includeCode) { public final LoadedApk peekLoadedApk(String packageName, boolean includeCode) {
synchronized (mResourcesManager) { synchronized (mResourcesManager) {
WeakReference<LoadedApk> ref; WeakReference<LoadedApk> ref;
if (includeCode) { if (includeCode) {
@@ -2068,7 +2068,7 @@ public final class ActivityThread {
} }
} }
private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo, private LoadedApk getLoadedApk(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
ClassLoader baseLoader, boolean securityViolation, boolean includeCode, ClassLoader baseLoader, boolean securityViolation, boolean includeCode,
boolean registerPackage) { boolean registerPackage) {
final boolean differentUser = (UserHandle.myUserId() != UserHandle.getUserId(aInfo.uid)); final boolean differentUser = (UserHandle.myUserId() != UserHandle.getUserId(aInfo.uid));
@@ -2083,35 +2083,35 @@ public final class ActivityThread {
ref = mResourcePackages.get(aInfo.packageName); ref = mResourcePackages.get(aInfo.packageName);
} }
LoadedApk packageInfo = ref != null ? ref.get() : null; LoadedApk loadedApk = ref != null ? ref.get() : null;
if (packageInfo == null || (packageInfo.mResources != null if (loadedApk == null || (loadedApk.mResources != null
&& !packageInfo.mResources.getAssets().isUpToDate())) { && !loadedApk.mResources.getAssets().isUpToDate())) {
if (localLOGV) Slog.v(TAG, (includeCode ? "Loading code package " if (localLOGV) Slog.v(TAG, (includeCode ? "Loading code package "
: "Loading resource-only package ") + aInfo.packageName : "Loading resource-only package ") + aInfo.packageName
+ " (in " + (mBoundApplication != null + " (in " + (mBoundApplication != null
? mBoundApplication.processName : null) ? mBoundApplication.processName : null)
+ ")"); + ")");
packageInfo = loadedApk =
new LoadedApk(this, aInfo, compatInfo, baseLoader, new LoadedApk(this, aInfo, compatInfo, baseLoader,
securityViolation, includeCode && securityViolation, includeCode &&
(aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage); (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage);
if (mSystemThread && "android".equals(aInfo.packageName)) { if (mSystemThread && "android".equals(aInfo.packageName)) {
packageInfo.installSystemApplicationInfo(aInfo, loadedApk.installSystemApplicationInfo(aInfo,
getSystemContext().mPackageInfo.getClassLoader()); getSystemContext().mLoadedApk.getClassLoader());
} }
if (differentUser) { if (differentUser) {
// Caching not supported across users // Caching not supported across users
} else if (includeCode) { } else if (includeCode) {
mPackages.put(aInfo.packageName, mPackages.put(aInfo.packageName,
new WeakReference<LoadedApk>(packageInfo)); new WeakReference<LoadedApk>(loadedApk));
} else { } else {
mResourcePackages.put(aInfo.packageName, mResourcePackages.put(aInfo.packageName,
new WeakReference<LoadedApk>(packageInfo)); new WeakReference<LoadedApk>(loadedApk));
} }
} }
return packageInfo; return loadedApk;
} }
} }
@@ -2645,8 +2645,8 @@ public final class ActivityThread {
// System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")"); // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
ActivityInfo aInfo = r.activityInfo; ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) { if (r.loadedApk == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo, r.loadedApk = getLoadedApk(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE); Context.CONTEXT_INCLUDE_CODE);
} }
@@ -2683,15 +2683,15 @@ public final class ActivityThread {
} }
try { try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation); Application app = r.loadedApk.makeApplication(false, mInstrumentation);
if (localLOGV) Slog.v(TAG, "Performing launch of " + r); if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
if (localLOGV) Slog.v( if (localLOGV) Slog.v(
TAG, r + ": app=" + app TAG, r + ": app=" + app
+ ", appName=" + app.getPackageName() + ", appName=" + app.getPackageName()
+ ", pkg=" + r.packageInfo.getPackageName() + ", pkg=" + r.loadedApk.getPackageName()
+ ", comp=" + r.intent.getComponent().toShortString() + ", comp=" + r.intent.getComponent().toShortString()
+ ", dir=" + r.packageInfo.getAppDir()); + ", dir=" + r.loadedApk.getAppDir());
if (activity != null) { if (activity != null) {
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager()); CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
@@ -2809,7 +2809,7 @@ public final class ActivityThread {
} }
ContextImpl appContext = ContextImpl.createActivityContext( ContextImpl appContext = ContextImpl.createActivityContext(
this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig); this, r.loadedApk, r.activityInfo, r.token, displayId, r.overrideConfig);
final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
// For debugging purposes, if the activity's package name contains the value of // For debugging purposes, if the activity's package name contains the value of
@@ -2817,7 +2817,7 @@ public final class ActivityThread {
// its content on a secondary display if there is one. // its content on a secondary display if there is one.
String pkgName = SystemProperties.get("debug.second-display.pkg"); String pkgName = SystemProperties.get("debug.second-display.pkg");
if (pkgName != null && !pkgName.isEmpty() if (pkgName != null && !pkgName.isEmpty()
&& r.packageInfo.mPackageName.contains(pkgName)) { && r.loadedApk.mPackageName.contains(pkgName)) {
for (int id : dm.getDisplayIds()) { for (int id : dm.getDisplayIds()) {
if (id != Display.DEFAULT_DISPLAY) { if (id != Display.DEFAULT_DISPLAY) {
Display display = Display display =
@@ -3145,7 +3145,7 @@ public final class ActivityThread {
String component = data.intent.getComponent().getClassName(); String component = data.intent.getComponent().getClassName();
LoadedApk packageInfo = getPackageInfoNoCheck( LoadedApk loadedApk = getLoadedApkNoCheck(
data.info.applicationInfo, data.compatInfo); data.info.applicationInfo, data.compatInfo);
IActivityManager mgr = ActivityManager.getService(); IActivityManager mgr = ActivityManager.getService();
@@ -3154,7 +3154,7 @@ public final class ActivityThread {
BroadcastReceiver receiver; BroadcastReceiver receiver;
ContextImpl context; ContextImpl context;
try { try {
app = packageInfo.makeApplication(false, mInstrumentation); app = loadedApk.makeApplication(false, mInstrumentation);
context = (ContextImpl) app.getBaseContext(); context = (ContextImpl) app.getBaseContext();
if (data.info.splitName != null) { if (data.info.splitName != null) {
context = (ContextImpl) context.createContextForSplit(data.info.splitName); context = (ContextImpl) context.createContextForSplit(data.info.splitName);
@@ -3178,9 +3178,9 @@ public final class ActivityThread {
TAG, "Performing receive of " + data.intent TAG, "Performing receive of " + data.intent
+ ": app=" + app + ": app=" + app
+ ", appName=" + app.getPackageName() + ", appName=" + app.getPackageName()
+ ", pkg=" + packageInfo.getPackageName() + ", pkg=" + loadedApk.getPackageName()
+ ", comp=" + data.intent.getComponent().toShortString() + ", comp=" + data.intent.getComponent().toShortString()
+ ", dir=" + packageInfo.getAppDir()); + ", dir=" + loadedApk.getAppDir());
sCurrentBroadcastIntent.set(data.intent); sCurrentBroadcastIntent.set(data.intent);
receiver.setPendingResult(data); receiver.setPendingResult(data);
@@ -3225,8 +3225,8 @@ public final class ActivityThread {
unscheduleGcIdler(); unscheduleGcIdler();
// instantiate the BackupAgent class named in the manifest // instantiate the BackupAgent class named in the manifest
LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo); LoadedApk loadedApk = getLoadedApkNoCheck(data.appInfo, data.compatInfo);
String packageName = packageInfo.mPackageName; String packageName = loadedApk.mPackageName;
if (packageName == null) { if (packageName == null) {
Slog.d(TAG, "Asked to create backup agent for nonexistent package"); Slog.d(TAG, "Asked to create backup agent for nonexistent package");
return; return;
@@ -3252,11 +3252,11 @@ public final class ActivityThread {
try { try {
if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname); if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname);
java.lang.ClassLoader cl = packageInfo.getClassLoader(); java.lang.ClassLoader cl = loadedApk.getClassLoader();
agent = (BackupAgent) cl.loadClass(classname).newInstance(); agent = (BackupAgent) cl.loadClass(classname).newInstance();
// set up the agent's context // set up the agent's context
ContextImpl context = ContextImpl.createAppContext(this, packageInfo); ContextImpl context = ContextImpl.createAppContext(this, loadedApk);
context.setOuterContext(agent); context.setOuterContext(agent);
agent.attach(context); agent.attach(context);
@@ -3292,8 +3292,8 @@ public final class ActivityThread {
private void handleDestroyBackupAgent(CreateBackupAgentData data) { private void handleDestroyBackupAgent(CreateBackupAgentData data) {
if (DEBUG_BACKUP) Slog.v(TAG, "handleDestroyBackupAgent: " + data); if (DEBUG_BACKUP) Slog.v(TAG, "handleDestroyBackupAgent: " + data);
LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo); LoadedApk loadedApk = getLoadedApkNoCheck(data.appInfo, data.compatInfo);
String packageName = packageInfo.mPackageName; String packageName = loadedApk.mPackageName;
BackupAgent agent = mBackupAgents.get(packageName); BackupAgent agent = mBackupAgents.get(packageName);
if (agent != null) { if (agent != null) {
try { try {
@@ -3313,11 +3313,11 @@ public final class ActivityThread {
// we are back active so skip it. // we are back active so skip it.
unscheduleGcIdler(); unscheduleGcIdler();
LoadedApk packageInfo = getPackageInfoNoCheck( LoadedApk loadedApk = getLoadedApkNoCheck(
data.info.applicationInfo, data.compatInfo); data.info.applicationInfo, data.compatInfo);
Service service = null; Service service = null;
try { try {
java.lang.ClassLoader cl = packageInfo.getClassLoader(); java.lang.ClassLoader cl = loadedApk.getClassLoader();
service = (Service) cl.loadClass(data.info.name).newInstance(); service = (Service) cl.loadClass(data.info.name).newInstance();
} catch (Exception e) { } catch (Exception e) {
if (!mInstrumentation.onException(service, e)) { if (!mInstrumentation.onException(service, e)) {
@@ -3330,10 +3330,10 @@ public final class ActivityThread {
try { try {
if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name); if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
ContextImpl context = ContextImpl.createAppContext(this, packageInfo); ContextImpl context = ContextImpl.createAppContext(this, loadedApk);
context.setOuterContext(service); context.setOuterContext(service);
Application app = packageInfo.makeApplication(false, mInstrumentation); Application app = loadedApk.makeApplication(false, mInstrumentation);
service.attach(context, this, data.info.name, data.token, app, service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService()); ActivityManager.getService());
service.onCreate(); service.onCreate();
@@ -3943,7 +3943,7 @@ public final class ActivityThread {
Bundle.dumpStats(pw, persistentState); Bundle.dumpStats(pw, persistentState);
if (ex instanceof TransactionTooLargeException if (ex instanceof TransactionTooLargeException
&& activity.packageInfo.getTargetSdkVersion() < Build.VERSION_CODES.N) { && activity.loadedApk.getTargetSdkVersion() < Build.VERSION_CODES.N) {
Log.e(TAG, "App sent too much data in instance state, so it was ignored", ex); Log.e(TAG, "App sent too much data in instance state, so it was ignored", ex);
return; return;
} }
@@ -4238,11 +4238,11 @@ public final class ActivityThread {
} }
private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) { private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) {
LoadedApk apk = peekPackageInfo(data.pkg, false); LoadedApk apk = peekLoadedApk(data.pkg, false);
if (apk != null) { if (apk != null) {
apk.setCompatibilityInfo(data.info); apk.setCompatibilityInfo(data.info);
} }
apk = peekPackageInfo(data.pkg, true); apk = peekLoadedApk(data.pkg, true);
if (apk != null) { if (apk != null) {
apk.setCompatibilityInfo(data.info); apk.setCompatibilityInfo(data.info);
} }
@@ -4739,7 +4739,7 @@ public final class ActivityThread {
if (a != null) { if (a != null) {
Configuration thisConfig = applyConfigCompatMainThread( Configuration thisConfig = applyConfigCompatMainThread(
mCurDefaultDisplayDpi, newConfig, mCurDefaultDisplayDpi, newConfig,
ar.packageInfo.getCompatibilityInfo()); ar.loadedApk.getCompatibilityInfo());
if (!ar.activity.mFinished && (allActivities || !ar.paused)) { if (!ar.activity.mFinished && (allActivities || !ar.paused)) {
// If the activity is currently resumed, its configuration // If the activity is currently resumed, its configuration
// needs to change right now. // needs to change right now.
@@ -5209,7 +5209,7 @@ public final class ActivityThread {
} }
final void handleDispatchPackageBroadcast(int cmd, String[] packages) { final void handleDispatchPackageBroadcast(int cmd, String[] packages) {
boolean hasPkgInfo = false; boolean hasLoadedApk = false;
switch (cmd) { switch (cmd) {
case ApplicationThreadConstants.PACKAGE_REMOVED: case ApplicationThreadConstants.PACKAGE_REMOVED:
case ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL: case ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL:
@@ -5220,14 +5220,14 @@ public final class ActivityThread {
} }
synchronized (mResourcesManager) { synchronized (mResourcesManager) {
for (int i = packages.length - 1; i >= 0; i--) { for (int i = packages.length - 1; i >= 0; i--) {
if (!hasPkgInfo) { if (!hasLoadedApk) {
WeakReference<LoadedApk> ref = mPackages.get(packages[i]); WeakReference<LoadedApk> ref = mPackages.get(packages[i]);
if (ref != null && ref.get() != null) { if (ref != null && ref.get() != null) {
hasPkgInfo = true; hasLoadedApk = true;
} else { } else {
ref = mResourcePackages.get(packages[i]); ref = mResourcePackages.get(packages[i]);
if (ref != null && ref.get() != null) { if (ref != null && ref.get() != null) {
hasPkgInfo = true; hasLoadedApk = true;
} }
} }
} }
@@ -5247,21 +5247,21 @@ public final class ActivityThread {
synchronized (mResourcesManager) { synchronized (mResourcesManager) {
for (int i = packages.length - 1; i >= 0; i--) { for (int i = packages.length - 1; i >= 0; i--) {
WeakReference<LoadedApk> ref = mPackages.get(packages[i]); WeakReference<LoadedApk> ref = mPackages.get(packages[i]);
LoadedApk pkgInfo = ref != null ? ref.get() : null; LoadedApk loadedApk = ref != null ? ref.get() : null;
if (pkgInfo != null) { if (loadedApk != null) {
hasPkgInfo = true; hasLoadedApk = true;
} else { } else {
ref = mResourcePackages.get(packages[i]); ref = mResourcePackages.get(packages[i]);
pkgInfo = ref != null ? ref.get() : null; loadedApk = ref != null ? ref.get() : null;
if (pkgInfo != null) { if (loadedApk != null) {
hasPkgInfo = true; hasLoadedApk = true;
} }
} }
// If the package is being replaced, yet it still has a valid // If the package is being replaced, yet it still has a valid
// LoadedApk object, the package was updated with _DONT_KILL. // LoadedApk object, the package was updated with _DONT_KILL.
// Adjust it's internal references to the application info and // Adjust it's internal references to the application info and
// resources. // resources.
if (pkgInfo != null) { if (loadedApk != null) {
try { try {
final String packageName = packages[i]; final String packageName = packages[i];
final ApplicationInfo aInfo = final ApplicationInfo aInfo =
@@ -5275,13 +5275,13 @@ public final class ActivityThread {
if (ar.activityInfo.applicationInfo.packageName if (ar.activityInfo.applicationInfo.packageName
.equals(packageName)) { .equals(packageName)) {
ar.activityInfo.applicationInfo = aInfo; ar.activityInfo.applicationInfo = aInfo;
ar.packageInfo = pkgInfo; ar.loadedApk = loadedApk;
} }
} }
} }
final List<String> oldPaths = final List<String> oldPaths =
sPackageManager.getPreviousCodePaths(packageName); sPackageManager.getPreviousCodePaths(packageName);
pkgInfo.updateApplicationInfo(aInfo, oldPaths); loadedApk.updateApplicationInfo(aInfo, oldPaths);
} catch (RemoteException e) { } catch (RemoteException e) {
} }
} }
@@ -5290,7 +5290,7 @@ public final class ActivityThread {
break; break;
} }
} }
ApplicationPackageManager.handlePackageBroadcast(cmd, packages, hasPkgInfo); ApplicationPackageManager.handlePackageBroadcast(cmd, packages, hasLoadedApk);
} }
final void handleLowMemory() { final void handleLowMemory() {
@@ -5494,7 +5494,7 @@ public final class ActivityThread {
applyCompatConfiguration(mCurDefaultDisplayDpi); applyCompatConfiguration(mCurDefaultDisplayDpi);
} }
data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo); data.loadedApk = getLoadedApkNoCheck(data.appInfo, data.compatInfo);
/** /**
* Switch this process to density compatibility mode if needed. * Switch this process to density compatibility mode if needed.
@@ -5562,7 +5562,7 @@ public final class ActivityThread {
// XXX should have option to change the port. // XXX should have option to change the port.
Debug.changeDebugPort(8100); Debug.changeDebugPort(8100);
if (data.debugMode == ApplicationThreadConstants.DEBUG_WAIT) { if (data.debugMode == ApplicationThreadConstants.DEBUG_WAIT) {
Slog.w(TAG, "Application " + data.info.getPackageName() Slog.w(TAG, "Application " + data.loadedApk.getPackageName()
+ " is waiting for the debugger on port 8100..."); + " is waiting for the debugger on port 8100...");
IActivityManager mgr = ActivityManager.getService(); IActivityManager mgr = ActivityManager.getService();
@@ -5581,7 +5581,7 @@ public final class ActivityThread {
} }
} else { } else {
Slog.w(TAG, "Application " + data.info.getPackageName() Slog.w(TAG, "Application " + data.loadedApk.getPackageName()
+ " can be debugged on port 8100..."); + " can be debugged on port 8100...");
} }
} }
@@ -5629,14 +5629,14 @@ public final class ActivityThread {
mInstrumentationAppDir = ii.sourceDir; mInstrumentationAppDir = ii.sourceDir;
mInstrumentationSplitAppDirs = ii.splitSourceDirs; mInstrumentationSplitAppDirs = ii.splitSourceDirs;
mInstrumentationLibDir = getInstrumentationLibrary(data.appInfo, ii); mInstrumentationLibDir = getInstrumentationLibrary(data.appInfo, ii);
mInstrumentedAppDir = data.info.getAppDir(); mInstrumentedAppDir = data.loadedApk.getAppDir();
mInstrumentedSplitAppDirs = data.info.getSplitAppDirs(); mInstrumentedSplitAppDirs = data.loadedApk.getSplitAppDirs();
mInstrumentedLibDir = data.info.getLibDir(); mInstrumentedLibDir = data.loadedApk.getLibDir();
} else { } else {
ii = null; ii = null;
} }
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info); final ContextImpl appContext = ContextImpl.createAppContext(this, data.loadedApk);
updateLocaleListFromAppContext(appContext, updateLocaleListFromAppContext(appContext,
mResourcesManager.getConfiguration().getLocales()); mResourcesManager.getConfiguration().getLocales());
@@ -5666,9 +5666,9 @@ public final class ActivityThread {
final ApplicationInfo instrApp = new ApplicationInfo(); final ApplicationInfo instrApp = new ApplicationInfo();
ii.copyTo(instrApp); ii.copyTo(instrApp);
instrApp.initForUser(UserHandle.myUserId()); instrApp.initForUser(UserHandle.myUserId());
final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo, final LoadedApk loadedApk = getLoadedApk(instrApp, data.compatInfo,
appContext.getClassLoader(), false, true, false); appContext.getClassLoader(), false, true, false);
final ContextImpl instrContext = ContextImpl.createAppContext(this, pi); final ContextImpl instrContext = ContextImpl.createAppContext(this, loadedApk);
try { try {
final ClassLoader cl = instrContext.getClassLoader(); final ClassLoader cl = instrContext.getClassLoader();
@@ -5712,7 +5712,7 @@ public final class ActivityThread {
try { try {
// If the app is being launched for full backup or restore, bring it up in // If the app is being launched for full backup or restore, bring it up in
// a restricted environment with the base application class. // a restricted environment with the base application class.
app = data.info.makeApplication(data.restrictedBackupMode, null); app = data.loadedApk.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app; mInitialApplication = app;
// don't bring up providers in restricted mode; they may depend on the // don't bring up providers in restricted mode; they may depend on the
@@ -5766,7 +5766,7 @@ public final class ActivityThread {
final int preloadedFontsResource = info.metaData.getInt( final int preloadedFontsResource = info.metaData.getInt(
ApplicationInfo.METADATA_PRELOADED_FONTS, 0); ApplicationInfo.METADATA_PRELOADED_FONTS, 0);
if (preloadedFontsResource != 0) { if (preloadedFontsResource != 0) {
data.info.getResources().preloadFonts(preloadedFontsResource); data.loadedApk.getResources().preloadFonts(preloadedFontsResource);
} }
} }
} catch (RemoteException e) { } catch (RemoteException e) {
@@ -6361,8 +6361,8 @@ public final class ActivityThread {
try { try {
mInstrumentation = new Instrumentation(); mInstrumentation = new Instrumentation();
ContextImpl context = ContextImpl.createAppContext( ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo); this, getSystemContext().mLoadedApk);
mInitialApplication = context.mPackageInfo.makeApplication(true, null); mInitialApplication = context.mLoadedApk.makeApplication(true, null);
mInitialApplication.onCreate(); mInitialApplication.onCreate();
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException( throw new RuntimeException(

View File

@@ -187,7 +187,7 @@ public class Application extends ContextWrapper implements ComponentCallbacks2 {
*/ */
/* package */ final void attach(Context context) { /* package */ final void attach(Context context) {
attachBaseContext(context); attachBaseContext(context);
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo; mLoadedApk = ContextImpl.getImpl(context).mLoadedApk;
} }
/* package */ void dispatchActivityCreated(Activity activity, Bundle savedInstanceState) { /* package */ void dispatchActivityCreated(Activity activity, Bundle savedInstanceState) {

View File

@@ -1379,7 +1379,7 @@ public class ApplicationPackageManager extends PackageManager {
sameUid ? app.sourceDir : app.publicSourceDir, sameUid ? app.sourceDir : app.publicSourceDir,
sameUid ? app.splitSourceDirs : app.splitPublicSourceDirs, sameUid ? app.splitSourceDirs : app.splitPublicSourceDirs,
app.resourceDirs, app.sharedLibraryFiles, Display.DEFAULT_DISPLAY, app.resourceDirs, app.sharedLibraryFiles, Display.DEFAULT_DISPLAY,
mContext.mPackageInfo); mContext.mLoadedApk);
if (r != null) { if (r != null) {
return r; return r;
} }

View File

@@ -159,7 +159,7 @@ class ContextImpl extends Context {
private ArrayMap<String, File> mSharedPrefsPaths; private ArrayMap<String, File> mSharedPrefsPaths;
final @NonNull ActivityThread mMainThread; final @NonNull ActivityThread mMainThread;
final @NonNull LoadedApk mPackageInfo; final @NonNull LoadedApk mLoadedApk;
private @Nullable ClassLoader mClassLoader; private @Nullable ClassLoader mClassLoader;
private final @Nullable IBinder mActivityToken; private final @Nullable IBinder mActivityToken;
@@ -252,8 +252,8 @@ class ContextImpl extends Context {
@Override @Override
public Context getApplicationContext() { public Context getApplicationContext() {
return (mPackageInfo != null) ? return (mLoadedApk != null) ?
mPackageInfo.getApplication() : mMainThread.getApplication(); mLoadedApk.getApplication() : mMainThread.getApplication();
} }
@Override @Override
@@ -297,15 +297,15 @@ class ContextImpl extends Context {
@Override @Override
public ClassLoader getClassLoader() { public ClassLoader getClassLoader() {
return mClassLoader != null ? mClassLoader : (mPackageInfo != null ? mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader()); return mClassLoader != null ? mClassLoader : (mLoadedApk != null ? mLoadedApk.getClassLoader() : ClassLoader.getSystemClassLoader());
} }
@Override @Override
public String getPackageName() { public String getPackageName() {
if (mPackageInfo != null) { if (mLoadedApk != null) {
return mPackageInfo.getPackageName(); return mLoadedApk.getPackageName();
} }
// No mPackageInfo means this is a Context for the system itself, // No mLoadedApk means this is a Context for the system itself,
// and this here is its name. // and this here is its name.
return "android"; return "android";
} }
@@ -324,24 +324,24 @@ class ContextImpl extends Context {
@Override @Override
public ApplicationInfo getApplicationInfo() { public ApplicationInfo getApplicationInfo() {
if (mPackageInfo != null) { if (mLoadedApk != null) {
return mPackageInfo.getApplicationInfo(); return mLoadedApk.getApplicationInfo();
} }
throw new RuntimeException("Not supported in system context"); throw new RuntimeException("Not supported in system context");
} }
@Override @Override
public String getPackageResourcePath() { public String getPackageResourcePath() {
if (mPackageInfo != null) { if (mLoadedApk != null) {
return mPackageInfo.getResDir(); return mLoadedApk.getResDir();
} }
throw new RuntimeException("Not supported in system context"); throw new RuntimeException("Not supported in system context");
} }
@Override @Override
public String getPackageCodePath() { public String getPackageCodePath() {
if (mPackageInfo != null) { if (mLoadedApk != null) {
return mPackageInfo.getAppDir(); return mLoadedApk.getAppDir();
} }
throw new RuntimeException("Not supported in system context"); throw new RuntimeException("Not supported in system context");
} }
@@ -351,7 +351,7 @@ class ContextImpl extends Context {
// At least one application in the world actually passes in a null // At least one application in the world actually passes in a null
// name. This happened to work because when we generated the file name // name. This happened to work because when we generated the file name
// we would stringify it to "null.xml". Nice. // we would stringify it to "null.xml". Nice.
if (mPackageInfo.getApplicationInfo().targetSdkVersion < if (mLoadedApk.getApplicationInfo().targetSdkVersion <
Build.VERSION_CODES.KITKAT) { Build.VERSION_CODES.KITKAT) {
if (name == null) { if (name == null) {
name = "null"; name = "null";
@@ -1093,11 +1093,11 @@ class ContextImpl extends Context {
warnIfCallingFromSystemProcess(); warnIfCallingFromSystemProcess();
IIntentReceiver rd = null; IIntentReceiver rd = null;
if (resultReceiver != null) { if (resultReceiver != null) {
if (mPackageInfo != null) { if (mLoadedApk != null) {
if (scheduler == null) { if (scheduler == null) {
scheduler = mMainThread.getHandler(); scheduler = mMainThread.getHandler();
} }
rd = mPackageInfo.getReceiverDispatcher( rd = mLoadedApk.getReceiverDispatcher(
resultReceiver, getOuterContext(), scheduler, resultReceiver, getOuterContext(), scheduler,
mMainThread.getInstrumentation(), false); mMainThread.getInstrumentation(), false);
} else { } else {
@@ -1197,11 +1197,11 @@ class ContextImpl extends Context {
Handler scheduler, int initialCode, String initialData, Bundle initialExtras) { Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
IIntentReceiver rd = null; IIntentReceiver rd = null;
if (resultReceiver != null) { if (resultReceiver != null) {
if (mPackageInfo != null) { if (mLoadedApk != null) {
if (scheduler == null) { if (scheduler == null) {
scheduler = mMainThread.getHandler(); scheduler = mMainThread.getHandler();
} }
rd = mPackageInfo.getReceiverDispatcher( rd = mLoadedApk.getReceiverDispatcher(
resultReceiver, getOuterContext(), scheduler, resultReceiver, getOuterContext(), scheduler,
mMainThread.getInstrumentation(), false); mMainThread.getInstrumentation(), false);
} else { } else {
@@ -1251,11 +1251,11 @@ class ContextImpl extends Context {
warnIfCallingFromSystemProcess(); warnIfCallingFromSystemProcess();
IIntentReceiver rd = null; IIntentReceiver rd = null;
if (resultReceiver != null) { if (resultReceiver != null) {
if (mPackageInfo != null) { if (mLoadedApk != null) {
if (scheduler == null) { if (scheduler == null) {
scheduler = mMainThread.getHandler(); scheduler = mMainThread.getHandler();
} }
rd = mPackageInfo.getReceiverDispatcher( rd = mLoadedApk.getReceiverDispatcher(
resultReceiver, getOuterContext(), scheduler, resultReceiver, getOuterContext(), scheduler,
mMainThread.getInstrumentation(), false); mMainThread.getInstrumentation(), false);
} else { } else {
@@ -1333,11 +1333,11 @@ class ContextImpl extends Context {
Bundle initialExtras) { Bundle initialExtras) {
IIntentReceiver rd = null; IIntentReceiver rd = null;
if (resultReceiver != null) { if (resultReceiver != null) {
if (mPackageInfo != null) { if (mLoadedApk != null) {
if (scheduler == null) { if (scheduler == null) {
scheduler = mMainThread.getHandler(); scheduler = mMainThread.getHandler();
} }
rd = mPackageInfo.getReceiverDispatcher( rd = mLoadedApk.getReceiverDispatcher(
resultReceiver, getOuterContext(), scheduler, resultReceiver, getOuterContext(), scheduler,
mMainThread.getInstrumentation(), false); mMainThread.getInstrumentation(), false);
} else { } else {
@@ -1414,11 +1414,11 @@ class ContextImpl extends Context {
Handler scheduler, Context context, int flags) { Handler scheduler, Context context, int flags) {
IIntentReceiver rd = null; IIntentReceiver rd = null;
if (receiver != null) { if (receiver != null) {
if (mPackageInfo != null && context != null) { if (mLoadedApk != null && context != null) {
if (scheduler == null) { if (scheduler == null) {
scheduler = mMainThread.getHandler(); scheduler = mMainThread.getHandler();
} }
rd = mPackageInfo.getReceiverDispatcher( rd = mLoadedApk.getReceiverDispatcher(
receiver, context, scheduler, receiver, context, scheduler,
mMainThread.getInstrumentation(), true); mMainThread.getInstrumentation(), true);
} else { } else {
@@ -1445,8 +1445,8 @@ class ContextImpl extends Context {
@Override @Override
public void unregisterReceiver(BroadcastReceiver receiver) { public void unregisterReceiver(BroadcastReceiver receiver) {
if (mPackageInfo != null) { if (mLoadedApk != null) {
IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher( IIntentReceiver rd = mLoadedApk.forgetReceiverDispatcher(
getOuterContext(), receiver); getOuterContext(), receiver);
try { try {
ActivityManager.getService().unregisterReceiver(rd); ActivityManager.getService().unregisterReceiver(rd);
@@ -1579,7 +1579,7 @@ class ContextImpl extends Context {
@Override @Override
public IServiceConnection getServiceDispatcher(ServiceConnection conn, Handler handler, public IServiceConnection getServiceDispatcher(ServiceConnection conn, Handler handler,
int flags) { int flags) {
return mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags); return mLoadedApk.getServiceDispatcher(conn, getOuterContext(), handler, flags);
} }
/** @hide */ /** @hide */
@@ -1601,16 +1601,16 @@ class ContextImpl extends Context {
if (conn == null) { if (conn == null) {
throw new IllegalArgumentException("connection is null"); throw new IllegalArgumentException("connection is null");
} }
if (mPackageInfo != null) { if (mLoadedApk != null) {
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags); sd = mLoadedApk.getServiceDispatcher(conn, getOuterContext(), handler, flags);
} else { } else {
throw new RuntimeException("Not supported in system context"); throw new RuntimeException("Not supported in system context");
} }
validateServiceIntent(service); validateServiceIntent(service);
try { try {
IBinder token = getActivityToken(); IBinder token = getActivityToken();
if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mLoadedApk != null
&& mPackageInfo.getApplicationInfo().targetSdkVersion && mLoadedApk.getApplicationInfo().targetSdkVersion
< android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) { < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
flags |= BIND_WAIVE_PRIORITY; flags |= BIND_WAIVE_PRIORITY;
} }
@@ -1634,8 +1634,8 @@ class ContextImpl extends Context {
if (conn == null) { if (conn == null) {
throw new IllegalArgumentException("connection is null"); throw new IllegalArgumentException("connection is null");
} }
if (mPackageInfo != null) { if (mLoadedApk != null) {
IServiceConnection sd = mPackageInfo.forgetServiceDispatcher( IServiceConnection sd = mLoadedApk.forgetServiceDispatcher(
getOuterContext(), conn); getOuterContext(), conn);
try { try {
ActivityManager.getService().unbindService(sd); ActivityManager.getService().unbindService(sd);
@@ -1980,40 +1980,20 @@ class ContextImpl extends Context {
} }
} }
private static Resources createResources(IBinder activityToken, LoadedApk pi, String splitName,
int displayId, Configuration overrideConfig, CompatibilityInfo compatInfo) {
final String[] splitResDirs;
final ClassLoader classLoader;
try {
splitResDirs = pi.getSplitPaths(splitName);
classLoader = pi.getSplitClassLoader(splitName);
} catch (NameNotFoundException e) {
throw new RuntimeException(e);
}
return ResourcesManager.getInstance().getResources(activityToken,
pi.getResDir(),
splitResDirs,
pi.getOverlayDirs(),
pi.getApplicationInfo().sharedLibraryFiles,
displayId,
overrideConfig,
compatInfo,
classLoader);
}
@Override @Override
public Context createApplicationContext(ApplicationInfo application, int flags) public Context createApplicationContext(ApplicationInfo application, int flags)
throws NameNotFoundException { throws NameNotFoundException {
LoadedApk pi = mMainThread.getPackageInfo(application, mResources.getCompatibilityInfo(), LoadedApk loadedApk = mMainThread.getLoadedApk(application,
mResources.getCompatibilityInfo(),
flags | CONTEXT_REGISTER_PACKAGE); flags | CONTEXT_REGISTER_PACKAGE);
if (pi != null) { if (loadedApk != null) {
ContextImpl c = new ContextImpl(this, mMainThread, pi, null, mActivityToken, ContextImpl c = new ContextImpl(this, mMainThread, loadedApk, null, mActivityToken,
new UserHandle(UserHandle.getUserId(application.uid)), flags, null); new UserHandle(UserHandle.getUserId(application.uid)), flags, null);
final int displayId = mDisplay != null final int displayId = mDisplay != null
? mDisplay.getDisplayId() : Display.DEFAULT_DISPLAY; ? mDisplay.getDisplayId() : Display.DEFAULT_DISPLAY;
c.setResources(createResources(mActivityToken, pi, null, displayId, null, c.setResources(loadedApk.createResources(mActivityToken, null, displayId, null,
getDisplayAdjustments(displayId).getCompatibilityInfo())); getDisplayAdjustments(displayId).getCompatibilityInfo()));
if (c.mResources != null) { if (c.mResources != null) {
return c; return c;
@@ -2037,20 +2017,21 @@ class ContextImpl extends Context {
if (packageName.equals("system") || packageName.equals("android")) { if (packageName.equals("system") || packageName.equals("android")) {
// The system resources are loaded in every application, so we can safely copy // The system resources are loaded in every application, so we can safely copy
// the context without reloading Resources. // the context without reloading Resources.
return new ContextImpl(this, mMainThread, mPackageInfo, null, mActivityToken, user, return new ContextImpl(this, mMainThread, mLoadedApk, null, mActivityToken, user,
flags, null); flags, null);
} }
LoadedApk pi = mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), LoadedApk loadedApk = mMainThread.getLoadedApkForPackageName(packageName,
mResources.getCompatibilityInfo(),
flags | CONTEXT_REGISTER_PACKAGE, user.getIdentifier()); flags | CONTEXT_REGISTER_PACKAGE, user.getIdentifier());
if (pi != null) { if (loadedApk != null) {
ContextImpl c = new ContextImpl(this, mMainThread, pi, null, mActivityToken, user, ContextImpl c = new ContextImpl(this, mMainThread, loadedApk, null, mActivityToken, user,
flags, null); flags, null);
final int displayId = mDisplay != null final int displayId = mDisplay != null
? mDisplay.getDisplayId() : Display.DEFAULT_DISPLAY; ? mDisplay.getDisplayId() : Display.DEFAULT_DISPLAY;
c.setResources(createResources(mActivityToken, pi, null, displayId, null, c.setResources(loadedApk.createResources(mActivityToken, null, displayId, null,
getDisplayAdjustments(displayId).getCompatibilityInfo())); getDisplayAdjustments(displayId).getCompatibilityInfo()));
if (c.mResources != null) { if (c.mResources != null) {
return c; return c;
@@ -2064,30 +2045,21 @@ class ContextImpl extends Context {
@Override @Override
public Context createContextForSplit(String splitName) throws NameNotFoundException { public Context createContextForSplit(String splitName) throws NameNotFoundException {
if (!mPackageInfo.getApplicationInfo().requestsIsolatedSplitLoading()) { if (!mLoadedApk.getApplicationInfo().requestsIsolatedSplitLoading()) {
// All Splits are always loaded. // All Splits are always loaded.
return this; return this;
} }
final ClassLoader classLoader = mPackageInfo.getSplitClassLoader(splitName); final ClassLoader classLoader = mLoadedApk.getSplitClassLoader(splitName);
final String[] paths = mPackageInfo.getSplitPaths(splitName);
final ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, splitName, final ContextImpl context = new ContextImpl(this, mMainThread, mLoadedApk, splitName,
mActivityToken, mUser, mFlags, classLoader); mActivityToken, mUser, mFlags, classLoader);
final int displayId = mDisplay != null final int displayId = mDisplay != null
? mDisplay.getDisplayId() : Display.DEFAULT_DISPLAY; ? mDisplay.getDisplayId() : Display.DEFAULT_DISPLAY;
context.setResources(ResourcesManager.getInstance().getResources( context.setResources(mLoadedApk.getOrCreateResourcesForSplit(splitName,
mActivityToken, mActivityToken, displayId));
mPackageInfo.getResDir(),
paths,
mPackageInfo.getOverlayDirs(),
mPackageInfo.getApplicationInfo().sharedLibraryFiles,
displayId,
null,
mPackageInfo.getCompatibilityInfo(),
classLoader));
return context; return context;
} }
@@ -2097,11 +2069,11 @@ class ContextImpl extends Context {
throw new IllegalArgumentException("overrideConfiguration must not be null"); throw new IllegalArgumentException("overrideConfiguration must not be null");
} }
ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mSplitName, ContextImpl context = new ContextImpl(this, mMainThread, mLoadedApk, mSplitName,
mActivityToken, mUser, mFlags, mClassLoader); mActivityToken, mUser, mFlags, mClassLoader);
final int displayId = mDisplay != null ? mDisplay.getDisplayId() : Display.DEFAULT_DISPLAY; final int displayId = mDisplay != null ? mDisplay.getDisplayId() : Display.DEFAULT_DISPLAY;
context.setResources(createResources(mActivityToken, mPackageInfo, mSplitName, displayId, context.setResources(mLoadedApk.createResources(mActivityToken, mSplitName, displayId,
overrideConfiguration, getDisplayAdjustments(displayId).getCompatibilityInfo())); overrideConfiguration, getDisplayAdjustments(displayId).getCompatibilityInfo()));
return context; return context;
} }
@@ -2112,11 +2084,11 @@ class ContextImpl extends Context {
throw new IllegalArgumentException("display must not be null"); throw new IllegalArgumentException("display must not be null");
} }
ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mSplitName, ContextImpl context = new ContextImpl(this, mMainThread, mLoadedApk, mSplitName,
mActivityToken, mUser, mFlags, mClassLoader); mActivityToken, mUser, mFlags, mClassLoader);
final int displayId = display.getDisplayId(); final int displayId = display.getDisplayId();
context.setResources(createResources(mActivityToken, mPackageInfo, mSplitName, displayId, context.setResources(mLoadedApk.createResources(mActivityToken, mSplitName, displayId,
null, getDisplayAdjustments(displayId).getCompatibilityInfo())); null, getDisplayAdjustments(displayId).getCompatibilityInfo()));
context.mDisplay = display; context.mDisplay = display;
return context; return context;
@@ -2126,7 +2098,7 @@ class ContextImpl extends Context {
public Context createDeviceProtectedStorageContext() { public Context createDeviceProtectedStorageContext() {
final int flags = (mFlags & ~Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE) final int flags = (mFlags & ~Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE)
| Context.CONTEXT_DEVICE_PROTECTED_STORAGE; | Context.CONTEXT_DEVICE_PROTECTED_STORAGE;
return new ContextImpl(this, mMainThread, mPackageInfo, mSplitName, mActivityToken, mUser, return new ContextImpl(this, mMainThread, mLoadedApk, mSplitName, mActivityToken, mUser,
flags, mClassLoader); flags, mClassLoader);
} }
@@ -2134,7 +2106,7 @@ class ContextImpl extends Context {
public Context createCredentialProtectedStorageContext() { public Context createCredentialProtectedStorageContext() {
final int flags = (mFlags & ~Context.CONTEXT_DEVICE_PROTECTED_STORAGE) final int flags = (mFlags & ~Context.CONTEXT_DEVICE_PROTECTED_STORAGE)
| Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE; | Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE;
return new ContextImpl(this, mMainThread, mPackageInfo, mSplitName, mActivityToken, mUser, return new ContextImpl(this, mMainThread, mLoadedApk, mSplitName, mActivityToken, mUser,
flags, mClassLoader); flags, mClassLoader);
} }
@@ -2183,14 +2155,14 @@ class ContextImpl extends Context {
@Override @Override
public File getDataDir() { public File getDataDir() {
if (mPackageInfo != null) { if (mLoadedApk != null) {
File res = null; File res = null;
if (isCredentialProtectedStorage()) { if (isCredentialProtectedStorage()) {
res = mPackageInfo.getCredentialProtectedDataDirFile(); res = mLoadedApk.getCredentialProtectedDataDirFile();
} else if (isDeviceProtectedStorage()) { } else if (isDeviceProtectedStorage()) {
res = mPackageInfo.getDeviceProtectedDataDirFile(); res = mLoadedApk.getDeviceProtectedDataDirFile();
} else { } else {
res = mPackageInfo.getDataDirFile(); res = mLoadedApk.getDataDirFile();
} }
if (res != null) { if (res != null) {
@@ -2241,10 +2213,10 @@ class ContextImpl extends Context {
} }
static ContextImpl createSystemContext(ActivityThread mainThread) { static ContextImpl createSystemContext(ActivityThread mainThread) {
LoadedApk packageInfo = new LoadedApk(mainThread); LoadedApk loadedApk = new LoadedApk(mainThread);
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0, ContextImpl context = new ContextImpl(null, mainThread, loadedApk, null, null, null, 0,
null); null);
context.setResources(packageInfo.getResources()); context.setResources(loadedApk.getResources());
context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(), context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
context.mResourcesManager.getDisplayMetrics()); context.mResourcesManager.getDisplayMetrics());
return context; return context;
@@ -2255,35 +2227,35 @@ class ContextImpl extends Context {
* Make sure that the created system UI context shares the same LoadedApk as the system context. * Make sure that the created system UI context shares the same LoadedApk as the system context.
*/ */
static ContextImpl createSystemUiContext(ContextImpl systemContext) { static ContextImpl createSystemUiContext(ContextImpl systemContext) {
final LoadedApk packageInfo = systemContext.mPackageInfo; final LoadedApk loadedApk = systemContext.mLoadedApk;
ContextImpl context = new ContextImpl(null, systemContext.mMainThread, packageInfo, null, ContextImpl context = new ContextImpl(null, systemContext.mMainThread, loadedApk, null,
null, null, 0, null); null, null, 0, null);
context.setResources(createResources(null, packageInfo, null, Display.DEFAULT_DISPLAY, null, context.setResources(loadedApk.createResources(null, null, Display.DEFAULT_DISPLAY, null,
packageInfo.getCompatibilityInfo())); loadedApk.getCompatibilityInfo()));
return context; return context;
} }
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) { static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk loadedApk) {
if (packageInfo == null) throw new IllegalArgumentException("packageInfo"); if (loadedApk == null) throw new IllegalArgumentException("loadedApk");
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0, ContextImpl context = new ContextImpl(null, mainThread, loadedApk, null, null, null, 0,
null); null);
context.setResources(packageInfo.getResources()); context.setResources(loadedApk.getResources());
return context; return context;
} }
static ContextImpl createActivityContext(ActivityThread mainThread, static ContextImpl createActivityContext(ActivityThread mainThread,
LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId, LoadedApk loadedApk, ActivityInfo activityInfo, IBinder activityToken, int displayId,
Configuration overrideConfiguration) { Configuration overrideConfiguration) {
if (packageInfo == null) throw new IllegalArgumentException("packageInfo"); if (loadedApk == null) throw new IllegalArgumentException("loadedApk");
String[] splitDirs = packageInfo.getSplitResDirs(); String[] splitDirs = loadedApk.getSplitResDirs();
ClassLoader classLoader = packageInfo.getClassLoader(); ClassLoader classLoader = loadedApk.getClassLoader();
if (packageInfo.getApplicationInfo().requestsIsolatedSplitLoading()) { if (loadedApk.getApplicationInfo().requestsIsolatedSplitLoading()) {
Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "SplitDependencies"); Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "SplitDependencies");
try { try {
classLoader = packageInfo.getSplitClassLoader(activityInfo.splitName); classLoader = loadedApk.getSplitClassLoader(activityInfo.splitName);
splitDirs = packageInfo.getSplitPaths(activityInfo.splitName); splitDirs = loadedApk.getSplitPaths(activityInfo.splitName);
} catch (NameNotFoundException e) { } catch (NameNotFoundException e) {
// Nothing above us can handle a NameNotFoundException, better crash. // Nothing above us can handle a NameNotFoundException, better crash.
throw new RuntimeException(e); throw new RuntimeException(e);
@@ -2292,14 +2264,14 @@ class ContextImpl extends Context {
} }
} }
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, activityInfo.splitName, ContextImpl context = new ContextImpl(null, mainThread, loadedApk, activityInfo.splitName,
activityToken, null, 0, classLoader); activityToken, null, 0, classLoader);
// Clamp display ID to DEFAULT_DISPLAY if it is INVALID_DISPLAY. // Clamp display ID to DEFAULT_DISPLAY if it is INVALID_DISPLAY.
displayId = (displayId != Display.INVALID_DISPLAY) ? displayId : Display.DEFAULT_DISPLAY; displayId = (displayId != Display.INVALID_DISPLAY) ? displayId : Display.DEFAULT_DISPLAY;
final CompatibilityInfo compatInfo = (displayId == Display.DEFAULT_DISPLAY) final CompatibilityInfo compatInfo = (displayId == Display.DEFAULT_DISPLAY)
? packageInfo.getCompatibilityInfo() ? loadedApk.getCompatibilityInfo()
: CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO; : CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
final ResourcesManager resourcesManager = ResourcesManager.getInstance(); final ResourcesManager resourcesManager = ResourcesManager.getInstance();
@@ -2307,10 +2279,10 @@ class ContextImpl extends Context {
// Create the base resources for which all configuration contexts for this Activity // Create the base resources for which all configuration contexts for this Activity
// will be rebased upon. // will be rebased upon.
context.setResources(resourcesManager.createBaseActivityResources(activityToken, context.setResources(resourcesManager.createBaseActivityResources(activityToken,
packageInfo.getResDir(), loadedApk.getResDir(),
splitDirs, splitDirs,
packageInfo.getOverlayDirs(), loadedApk.getOverlayDirs(),
packageInfo.getApplicationInfo().sharedLibraryFiles, loadedApk.getApplicationInfo().sharedLibraryFiles,
displayId, displayId,
overrideConfiguration, overrideConfiguration,
compatInfo, compatInfo,
@@ -2321,7 +2293,7 @@ class ContextImpl extends Context {
} }
private ContextImpl(@Nullable ContextImpl container, @NonNull ActivityThread mainThread, private ContextImpl(@Nullable ContextImpl container, @NonNull ActivityThread mainThread,
@NonNull LoadedApk packageInfo, @Nullable String splitName, @NonNull LoadedApk loadedApk, @Nullable String splitName,
@Nullable IBinder activityToken, @Nullable UserHandle user, int flags, @Nullable IBinder activityToken, @Nullable UserHandle user, int flags,
@Nullable ClassLoader classLoader) { @Nullable ClassLoader classLoader) {
mOuterContext = this; mOuterContext = this;
@@ -2330,10 +2302,10 @@ class ContextImpl extends Context {
// location for application. // location for application.
if ((flags & (Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE if ((flags & (Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE
| Context.CONTEXT_DEVICE_PROTECTED_STORAGE)) == 0) { | Context.CONTEXT_DEVICE_PROTECTED_STORAGE)) == 0) {
final File dataDir = packageInfo.getDataDirFile(); final File dataDir = loadedApk.getDataDirFile();
if (Objects.equals(dataDir, packageInfo.getCredentialProtectedDataDirFile())) { if (Objects.equals(dataDir, loadedApk.getCredentialProtectedDataDirFile())) {
flags |= Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE; flags |= Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE;
} else if (Objects.equals(dataDir, packageInfo.getDeviceProtectedDataDirFile())) { } else if (Objects.equals(dataDir, loadedApk.getDeviceProtectedDataDirFile())) {
flags |= Context.CONTEXT_DEVICE_PROTECTED_STORAGE; flags |= Context.CONTEXT_DEVICE_PROTECTED_STORAGE;
} }
} }
@@ -2347,7 +2319,7 @@ class ContextImpl extends Context {
} }
mUser = user; mUser = user;
mPackageInfo = packageInfo; mLoadedApk = loadedApk;
mSplitName = splitName; mSplitName = splitName;
mClassLoader = classLoader; mClassLoader = classLoader;
mResourcesManager = ResourcesManager.getInstance(); mResourcesManager = ResourcesManager.getInstance();
@@ -2358,8 +2330,8 @@ class ContextImpl extends Context {
setResources(container.mResources); setResources(container.mResources);
mDisplay = container.mDisplay; mDisplay = container.mDisplay;
} else { } else {
mBasePackageName = packageInfo.mPackageName; mBasePackageName = loadedApk.mPackageName;
ApplicationInfo ainfo = packageInfo.getApplicationInfo(); ApplicationInfo ainfo = loadedApk.getApplicationInfo();
if (ainfo.uid == Process.SYSTEM_UID && ainfo.uid != Process.myUid()) { if (ainfo.uid == Process.SYSTEM_UID && ainfo.uid != Process.myUid()) {
// Special case: system components allow themselves to be loaded in to other // Special case: system components allow themselves to be loaded in to other
// processes. For purposes of app ops, we must then consider the context as // processes. For purposes of app ops, we must then consider the context as
@@ -2382,7 +2354,7 @@ class ContextImpl extends Context {
} }
void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) { void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
mPackageInfo.installSystemApplicationInfo(info, classLoader); mLoadedApk.installSystemApplicationInfo(info, classLoader);
} }
final void scheduleFinalCleanup(String who, String what) { final void scheduleFinalCleanup(String who, String what) {
@@ -2391,7 +2363,7 @@ class ContextImpl extends Context {
final void performFinalCleanup(String who, String what) { final void performFinalCleanup(String who, String what) {
//Log.i(TAG, "Cleanup up context: " + this); //Log.i(TAG, "Cleanup up context: " + this);
mPackageInfo.removeContextRegistrations(getOuterContext(), who, what); mLoadedApk.removeContextRegistrations(getOuterContext(), who, what);
} }
final Context getReceiverRestrictedContext() { final Context getReceiverRestrictedContext() {

View File

@@ -31,6 +31,7 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.split.SplitDependencyLoader; import android.content.pm.split.SplitDependencyLoader;
import android.content.res.AssetManager; import android.content.res.AssetManager;
import android.content.res.CompatibilityInfo; import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
@@ -48,15 +49,13 @@ import android.text.TextUtils;
import android.util.AndroidRuntimeException; import android.util.AndroidRuntimeException;
import android.util.ArrayMap; import android.util.ArrayMap;
import android.util.Log; import android.util.Log;
import android.util.LogPrinter;
import android.util.Slog; import android.util.Slog;
import android.util.SparseArray; import android.util.SparseArray;
import android.view.Display; import android.view.Display;
import android.view.DisplayAdjustments; import android.view.DisplayAdjustments;
import com.android.internal.util.ArrayUtils; import com.android.internal.util.ArrayUtils;
import dalvik.system.VMRuntime; import dalvik.system.VMRuntime;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@@ -948,14 +947,78 @@ public final class LoadedApk {
throw new AssertionError("null split not found"); throw new AssertionError("null split not found");
} }
mResources = ResourcesManager.getInstance().getResources(null, mResDir, mResources = ResourcesManager.getInstance().getResources(
splitPaths, mOverlayDirs, mApplicationInfo.sharedLibraryFiles, null,
Display.DEFAULT_DISPLAY, null, getCompatibilityInfo(), mResDir,
splitPaths,
mOverlayDirs,
mApplicationInfo.sharedLibraryFiles,
Display.DEFAULT_DISPLAY,
null,
getCompatibilityInfo(),
getClassLoader()); getClassLoader());
} }
return mResources; return mResources;
} }
public Resources getOrCreateResourcesForSplit(@NonNull String splitName,
@Nullable IBinder activityToken, int displayId) throws NameNotFoundException {
return ResourcesManager.getInstance().getResources(
activityToken,
mResDir,
getSplitPaths(splitName),
mOverlayDirs,
mApplicationInfo.sharedLibraryFiles,
displayId,
null,
getCompatibilityInfo(),
getSplitClassLoader(splitName));
}
/**
* Creates the top level resources for the given package. Will return an existing
* Resources if one has already been created.
*/
public Resources getOrCreateTopLevelResources(@NonNull ApplicationInfo appInfo) {
// Request for this app, short circuit
if (appInfo.uid == Process.myUid()) {
return getResources();
}
// Get resources for a different package
return ResourcesManager.getInstance().getResources(
null,
appInfo.publicSourceDir,
appInfo.splitPublicSourceDirs,
appInfo.resourceDirs,
appInfo.sharedLibraryFiles,
Display.DEFAULT_DISPLAY,
null,
getCompatibilityInfo(),
getClassLoader());
}
public Resources createResources(IBinder activityToken, String splitName,
int displayId, Configuration overrideConfig, CompatibilityInfo compatInfo) {
final String[] splitResDirs;
final ClassLoader classLoader;
try {
splitResDirs = getSplitPaths(splitName);
classLoader = getSplitClassLoader(splitName);
} catch (NameNotFoundException e) {
throw new RuntimeException(e);
}
return ResourcesManager.getInstance().getResources(activityToken,
mResDir,
splitResDirs,
mOverlayDirs,
mApplicationInfo.sharedLibraryFiles,
displayId,
overrideConfig,
compatInfo,
classLoader);
}
public Application makeApplication(boolean forceDefaultAppClass, public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) { Instrumentation instrumentation) {
if (mApplication != null) { if (mApplication != null) {