summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/app/ActivityThread.java26
-rw-r--r--core/java/android/app/ApplicationPackageManager.java4
-rw-r--r--core/java/android/app/ContextImpl.java8
-rw-r--r--core/java/android/app/LoadedApk.java151
-rw-r--r--core/java/android/app/ResourcesManager.java14
-rw-r--r--core/java/android/content/pm/ApplicationInfo.java46
-rw-r--r--core/java/android/content/pm/InstrumentationInfo.java25
7 files changed, 163 insertions, 111 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index ea46044..b8f2089 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -191,11 +191,13 @@ public final class ActivityThread {
/** Reference to singleton {@link ActivityThread} */
private static ActivityThread sCurrentActivityThread;
Instrumentation mInstrumentation;
+ String mInstrumentationPackageName = null;
String mInstrumentationAppDir = null;
- String mInstrumentationAppLibraryDir = null;
- String mInstrumentationAppPackage = null;
+ String[] mInstrumentationSplitAppDirs = null;
+ String mInstrumentationLibDir = null;
String mInstrumentedAppDir = null;
- String mInstrumentedAppLibraryDir = null;
+ String[] mInstrumentedSplitAppDirs = null;
+ String mInstrumentedLibDir = null;
boolean mSystemThread = false;
boolean mJitEnabled = false;
@@ -1585,11 +1587,11 @@ public final class ActivityThread {
/**
* Creates the top level resources for the given package.
*/
- Resources getTopLevelResources(String resDir, String[] overlayDirs, String[] libDirs,
- int displayId, Configuration overrideConfiguration,
+ Resources getTopLevelResources(String resDir, String[] splitResDirs, String[] overlayDirs,
+ String[] libDirs, int displayId, Configuration overrideConfiguration,
LoadedApk pkgInfo) {
- return mResourcesManager.getTopLevelResources(resDir, overlayDirs, libDirs, displayId,
- overrideConfiguration, pkgInfo.getCompatibilityInfo(), null);
+ return mResourcesManager.getTopLevelResources(resDir, splitResDirs, overlayDirs, libDirs,
+ displayId, overrideConfiguration, pkgInfo.getCompatibilityInfo(), null);
}
final Handler getHandler() {
@@ -4315,16 +4317,20 @@ public final class ActivityThread {
+ data.instrumentationName);
}
+ mInstrumentationPackageName = ii.packageName;
mInstrumentationAppDir = ii.sourceDir;
- mInstrumentationAppLibraryDir = ii.nativeLibraryDir;
- mInstrumentationAppPackage = ii.packageName;
+ mInstrumentationSplitAppDirs = ii.splitSourceDirs;
+ mInstrumentationLibDir = ii.nativeLibraryDir;
mInstrumentedAppDir = data.info.getAppDir();
- mInstrumentedAppLibraryDir = data.info.getLibDir();
+ mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();
+ mInstrumentedLibDir = data.info.getLibDir();
ApplicationInfo instrApp = new ApplicationInfo();
instrApp.packageName = ii.packageName;
instrApp.sourceDir = ii.sourceDir;
instrApp.publicSourceDir = ii.publicSourceDir;
+ instrApp.splitSourceDirs = ii.splitSourceDirs;
+ instrApp.splitPublicSourceDirs = ii.splitPublicSourceDirs;
instrApp.dataDir = ii.dataDir;
instrApp.nativeLibraryDir = ii.nativeLibraryDir;
LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 84673d9..de0396e 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -823,8 +823,10 @@ final class ApplicationPackageManager extends PackageManager {
if (app.packageName.equals("system")) {
return mContext.mMainThread.getSystemContext().getResources();
}
+ final boolean sameUid = (app.uid == Process.myUid());
Resources r = mContext.mMainThread.getTopLevelResources(
- app.uid == Process.myUid() ? app.sourceDir : app.publicSourceDir,
+ sameUid ? app.sourceDir : app.publicSourceDir,
+ sameUid ? app.splitSourceDirs : app.splitPublicSourceDirs,
app.resourceDirs, null, Display.DEFAULT_DISPLAY, null, mContext.mPackageInfo);
if (r != null) {
return r;
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index a42bd3b..3e7d9b4 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -2190,10 +2190,10 @@ class ContextImpl extends Context {
|| overrideConfiguration != null
|| (compatInfo != null && compatInfo.applicationScale
!= resources.getCompatibilityInfo().applicationScale)) {
- resources = mResourcesManager.getTopLevelResources(
- packageInfo.getResDir(), packageInfo.getOverlayDirs(),
- packageInfo.getApplicationInfo().sharedLibraryFiles,
- displayId, overrideConfiguration, compatInfo, activityToken);
+ resources = mResourcesManager.getTopLevelResources(packageInfo.getResDir(),
+ packageInfo.getSplitResDirs(), packageInfo.getOverlayDirs(),
+ packageInfo.getApplicationInfo().sharedLibraryFiles, displayId,
+ overrideConfiguration, compatInfo, activityToken);
}
}
mResources = resources;
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 3ae8bfc..065e88d 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -16,8 +16,8 @@
package android.app;
+import android.text.TextUtils;
import android.util.ArrayMap;
-import com.android.internal.util.ArrayUtils;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -52,6 +52,8 @@ import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.Enumeration;
final class IntentReceiverLeaked extends AndroidRuntimeException {
@@ -79,6 +81,8 @@ public final class LoadedApk {
final String mPackageName;
private final String mAppDir;
private final String mResDir;
+ private final String[] mSplitAppDirs;
+ private final String[] mSplitResDirs;
private final String[] mOverlayDirs;
private final String[] mSharedLibraries;
private final String mDataDir;
@@ -116,13 +120,14 @@ public final class LoadedApk {
public LoadedApk(ActivityThread activityThread, ApplicationInfo aInfo,
CompatibilityInfo compatInfo, ClassLoader baseLoader,
boolean securityViolation, boolean includeCode) {
+ final int myUid = Process.myUid();
mActivityThread = activityThread;
mApplicationInfo = aInfo;
mPackageName = aInfo.packageName;
mAppDir = aInfo.sourceDir;
- final int myUid = Process.myUid();
- mResDir = aInfo.uid == myUid ? aInfo.sourceDir
- : aInfo.publicSourceDir;
+ mResDir = aInfo.uid == myUid ? aInfo.sourceDir : aInfo.publicSourceDir;
+ mSplitAppDirs = aInfo.splitSourceDirs;
+ mSplitResDirs = aInfo.uid == myUid ? aInfo.splitSourceDirs : aInfo.splitPublicSourceDirs;
mOverlayDirs = aInfo.resourceDirs;
if (!UserHandle.isSameUser(aInfo.uid, myUid) && !Process.isIsolated()) {
aInfo.dataDir = PackageManager.getDataDirForUser(UserHandle.getUserId(myUid),
@@ -149,6 +154,8 @@ public final class LoadedApk {
mPackageName = "android";
mAppDir = null;
mResDir = null;
+ mSplitAppDirs = null;
+ mSplitResDirs = null;
mOverlayDirs = null;
mSharedLibraries = null;
mDataDir = null;
@@ -214,53 +221,6 @@ public final class LoadedApk {
return ai.sharedLibraryFiles;
}
- /**
- * Combines two arrays (of library names) such that they are
- * concatenated in order but are devoid of duplicates. The
- * result is a single string with the names of the libraries
- * separated by colons, or <code>null</code> if both lists
- * were <code>null</code> or empty.
- *
- * @param list1 null-ok; the first list
- * @param list2 null-ok; the second list
- * @return null-ok; the combination
- */
- private static String combineLibs(String[] list1, String[] list2) {
- StringBuilder result = new StringBuilder(300);
- boolean first = true;
-
- if (list1 != null) {
- for (String s : list1) {
- if (first) {
- first = false;
- } else {
- result.append(':');
- }
- result.append(s);
- }
- }
-
- // Only need to check for duplicates if list1 was non-empty.
- boolean dupCheck = !first;
-
- if (list2 != null) {
- for (String s : list2) {
- if (dupCheck && ArrayUtils.contains(list1, s)) {
- continue;
- }
-
- if (first) {
- first = false;
- } else {
- result.append(':');
- }
- result.append(s);
- }
- }
-
- return result.toString();
- }
-
public ClassLoader getClassLoader() {
synchronized (this) {
if (mClassLoader != null) {
@@ -268,8 +228,15 @@ public final class LoadedApk {
}
if (mIncludeCode && !mPackageName.equals("android")) {
- String zip = mAppDir;
- String libraryPath = mLibDir;
+ final ArrayList<String> zipPaths = new ArrayList<>();
+ final ArrayList<String> libPaths = new ArrayList<>();
+
+ zipPaths.add(mAppDir);
+ if (mSplitAppDirs != null) {
+ Collections.addAll(zipPaths, mSplitAppDirs);
+ }
+
+ libPaths.add(mLibDir);
/*
* The following is a bit of a hack to inject
@@ -280,50 +247,70 @@ public final class LoadedApk {
* concatenation of both apps' shared library lists.
*/
- String instrumentationAppDir =
- mActivityThread.mInstrumentationAppDir;
- String instrumentationAppLibraryDir =
- mActivityThread.mInstrumentationAppLibraryDir;
- String instrumentationAppPackage =
- mActivityThread.mInstrumentationAppPackage;
- String instrumentedAppDir =
- mActivityThread.mInstrumentedAppDir;
- String instrumentedAppLibraryDir =
- mActivityThread.mInstrumentedAppLibraryDir;
+ String instrumentationPackageName = mActivityThread.mInstrumentationPackageName;
+ String instrumentationAppDir = mActivityThread.mInstrumentationAppDir;
+ String[] instrumentationSplitAppDirs = mActivityThread.mInstrumentationSplitAppDirs;
+ String instrumentationLibDir = mActivityThread.mInstrumentationLibDir;
+
+ String instrumentedAppDir = mActivityThread.mInstrumentedAppDir;
+ String[] instrumentedSplitAppDirs = mActivityThread.mInstrumentedSplitAppDirs;
+ String instrumentedLibDir = mActivityThread.mInstrumentedLibDir;
String[] instrumentationLibs = null;
if (mAppDir.equals(instrumentationAppDir)
|| mAppDir.equals(instrumentedAppDir)) {
- zip = instrumentationAppDir + ":" + instrumentedAppDir;
- libraryPath = instrumentationAppLibraryDir + ":" + instrumentedAppLibraryDir;
- if (! instrumentedAppDir.equals(instrumentationAppDir)) {
- instrumentationLibs =
- getLibrariesFor(instrumentationAppPackage);
+ zipPaths.clear();
+ zipPaths.add(instrumentationAppDir);
+ if (instrumentationSplitAppDirs != null) {
+ Collections.addAll(zipPaths, instrumentationSplitAppDirs);
+ }
+ zipPaths.add(instrumentedAppDir);
+ if (instrumentedSplitAppDirs != null) {
+ Collections.addAll(zipPaths, instrumentedSplitAppDirs);
+ }
+
+ libPaths.clear();
+ libPaths.add(instrumentationLibDir);
+ libPaths.add(instrumentedLibDir);
+
+ if (!instrumentedAppDir.equals(instrumentationAppDir)) {
+ instrumentationLibs = getLibrariesFor(instrumentationPackageName);
}
}
- if ((mSharedLibraries != null) ||
- (instrumentationLibs != null)) {
- zip =
- combineLibs(mSharedLibraries, instrumentationLibs)
- + ':' + zip;
+ if (mSharedLibraries != null) {
+ for (String lib : mSharedLibraries) {
+ if (!zipPaths.contains(lib)) {
+ zipPaths.add(0, lib);
+ }
+ }
}
+ if (instrumentationLibs != null) {
+ for (String lib : instrumentationLibs) {
+ if (!zipPaths.contains(lib)) {
+ zipPaths.add(0, lib);
+ }
+ }
+ }
+
+ final String zip = TextUtils.join(File.pathSeparator, zipPaths);
+ final String lib = TextUtils.join(File.pathSeparator, libPaths);
+
/*
* With all the combination done (if necessary, actually
* create the class loader.
*/
if (ActivityThread.localLOGV)
- Slog.v(ActivityThread.TAG, "Class path: " + zip + ", JNI path: " + libraryPath);
+ Slog.v(ActivityThread.TAG, "Class path: " + zip + ", JNI path: " + lib);
// Temporarily disable logging of disk reads on the Looper thread
// as this is early and necessary.
StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
- mClassLoader =
- ApplicationLoaders.getDefault().getClassLoader(
- zip, libraryPath, mBaseClassLoader);
+ mClassLoader = ApplicationLoaders.getDefault().getClassLoader(zip, lib,
+ mBaseClassLoader);
initializeJavaContextClassLoader();
StrictMode.setThreadPolicy(oldPolicy);
@@ -469,6 +456,14 @@ public final class LoadedApk {
return mResDir;
}
+ public String[] getSplitAppDirs() {
+ return mSplitAppDirs;
+ }
+
+ public String[] getSplitResDirs() {
+ return mSplitResDirs;
+ }
+
public String[] getOverlayDirs() {
return mOverlayDirs;
}
@@ -487,7 +482,7 @@ public final class LoadedApk {
public Resources getResources(ActivityThread mainThread) {
if (mResources == null) {
- mResources = mainThread.getTopLevelResources(mResDir, mOverlayDirs,
+ mResources = mainThread.getTopLevelResources(mResDir, mSplitResDirs, mOverlayDirs,
mApplicationInfo.sharedLibraryFiles, Display.DEFAULT_DISPLAY, null, this);
}
return mResources;
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index a67faa0..3c13115 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -149,9 +149,9 @@ public class ResourcesManager {
* @param compatInfo the compability info. Must not be null.
* @param token the application token for determining stack bounds.
*/
- public Resources getTopLevelResources(String resDir, String[] overlayDirs, String[] libDirs,
- int displayId, Configuration overrideConfiguration, CompatibilityInfo compatInfo,
- IBinder token) {
+ public Resources getTopLevelResources(String resDir, String[] splitResDirs,
+ String[] overlayDirs, String[] libDirs, int displayId,
+ Configuration overrideConfiguration, CompatibilityInfo compatInfo, IBinder token) {
final float scale = compatInfo.applicationScale;
ResourcesKey key = new ResourcesKey(resDir, displayId, overrideConfiguration, scale, token);
Resources r;
@@ -182,6 +182,14 @@ public class ResourcesManager {
return null;
}
+ if (splitResDirs != null) {
+ for (String splitResDir : splitResDirs) {
+ if (assets.addAssetPath(splitResDir) == 0) {
+ return null;
+ }
+ }
+ }
+
if (overlayDirs != null) {
for (String idmapPath : overlayDirs) {
assets.addOverlayPath(idmapPath);
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 6b44a11..06f4019 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -23,8 +23,12 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.util.Printer;
+import com.android.internal.util.ArrayUtils;
+
import java.text.Collator;
+import java.util.Arrays;
import java.util.Comparator;
+import java.util.Objects;
/**
* Information you can retrieve about a particular application. This
@@ -398,17 +402,30 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
public int largestWidthLimitDp = 0;
/**
- * Full path to the location of this package.
+ * Full path to the base APK for this application.
*/
public String sourceDir;
/**
- * Full path to the location of the publicly available parts of this
- * package (i.e. the primary resource package and manifest). For
- * non-forward-locked apps this will be the same as {@link #sourceDir).
+ * Full path to the publicly available parts of {@link #sourceDir},
+ * including resources and manifest. This may be different from
+ * {@link #sourceDir} if an application is forward locked.
*/
public String publicSourceDir;
-
+
+ /**
+ * Full paths to zero or more split APKs that, when combined with the base
+ * APK defined in {@link #sourceDir}, form a complete application.
+ */
+ public String[] splitSourceDirs;
+
+ /**
+ * Full path to the publicly available parts of {@link #splitSourceDirs},
+ * including resources and manifest. This may be different from
+ * {@link #splitSourceDirs} if an application is forward locked.
+ */
+ public String[] splitPublicSourceDirs;
+
/**
* Full paths to the locations of extra resource packages this application
* uses. This field is only used if there are extra resource packages,
@@ -512,13 +529,16 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
+ " compatibleWidthLimitDp=" + compatibleWidthLimitDp
+ " largestWidthLimitDp=" + largestWidthLimitDp);
pw.println(prefix + "sourceDir=" + sourceDir);
- if (sourceDir == null) {
- if (publicSourceDir != null) {
- pw.println(prefix + "publicSourceDir=" + publicSourceDir);
- }
- } else if (!sourceDir.equals(publicSourceDir)) {
+ if (!Objects.equals(sourceDir, publicSourceDir)) {
pw.println(prefix + "publicSourceDir=" + publicSourceDir);
}
+ if (!ArrayUtils.isEmpty(splitSourceDirs)) {
+ pw.println(prefix + "splitSourceDirs=" + Arrays.toString(splitSourceDirs));
+ }
+ if (!ArrayUtils.isEmpty(splitPublicSourceDirs)
+ && !Arrays.equals(splitSourceDirs, splitPublicSourceDirs)) {
+ pw.println(prefix + "splitPublicSourceDirs=" + Arrays.toString(splitPublicSourceDirs));
+ }
if (resourceDirs != null) {
pw.println(prefix + "resourceDirs=" + resourceDirs);
}
@@ -591,6 +611,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
largestWidthLimitDp = orig.largestWidthLimitDp;
sourceDir = orig.sourceDir;
publicSourceDir = orig.publicSourceDir;
+ splitSourceDirs = orig.splitSourceDirs;
+ splitPublicSourceDirs = orig.splitPublicSourceDirs;
nativeLibraryDir = orig.nativeLibraryDir;
cpuAbi = orig.cpuAbi;
resourceDirs = orig.resourceDirs;
@@ -633,6 +655,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
dest.writeInt(largestWidthLimitDp);
dest.writeString(sourceDir);
dest.writeString(publicSourceDir);
+ dest.writeStringArray(splitSourceDirs);
+ dest.writeStringArray(splitPublicSourceDirs);
dest.writeString(nativeLibraryDir);
dest.writeString(cpuAbi);
dest.writeStringArray(resourceDirs);
@@ -674,6 +698,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
largestWidthLimitDp = source.readInt();
sourceDir = source.readString();
publicSourceDir = source.readString();
+ splitSourceDirs = source.readStringArray();
+ splitPublicSourceDirs = source.readStringArray();
nativeLibraryDir = source.readString();
cpuAbi = source.readString();
resourceDirs = source.readStringArray();
diff --git a/core/java/android/content/pm/InstrumentationInfo.java b/core/java/android/content/pm/InstrumentationInfo.java
index a977e41..dab0caf 100644
--- a/core/java/android/content/pm/InstrumentationInfo.java
+++ b/core/java/android/content/pm/InstrumentationInfo.java
@@ -30,17 +30,32 @@ public class InstrumentationInfo extends PackageItemInfo implements Parcelable {
* "package" attribute.
*/
public String targetPackage;
-
+
/**
- * Full path to the location of this package.
+ * Full path to the base APK for this application.
*/
public String sourceDir;
-
+
/**
- * Full path to the location of the publicly available parts of this package (i.e. the resources
- * and manifest). For non-forward-locked apps this will be the same as {@link #sourceDir).
+ * Full path to the publicly available parts of {@link #sourceDir},
+ * including resources and manifest. This may be different from
+ * {@link #sourceDir} if an application is forward locked.
*/
public String publicSourceDir;
+
+ /**
+ * Full paths to zero or more split APKs that, when combined with the base
+ * APK defined in {@link #sourceDir}, form a complete application.
+ */
+ public String[] splitSourceDirs;
+
+ /**
+ * Full path to the publicly available parts of {@link #splitSourceDirs},
+ * including resources and manifest. This may be different from
+ * {@link #splitSourceDirs} if an application is forward locked.
+ */
+ public String[] splitPublicSourceDirs;
+
/**
* Full path to a directory assigned to the package for its persistent
* data.