diff options
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/app/ActivityThread.java | 26 | ||||
| -rw-r--r-- | core/java/android/app/ApplicationPackageManager.java | 4 | ||||
| -rw-r--r-- | core/java/android/app/ContextImpl.java | 8 | ||||
| -rw-r--r-- | core/java/android/app/LoadedApk.java | 151 | ||||
| -rw-r--r-- | core/java/android/app/ResourcesManager.java | 14 | ||||
| -rw-r--r-- | core/java/android/content/pm/ApplicationInfo.java | 46 | ||||
| -rw-r--r-- | core/java/android/content/pm/InstrumentationInfo.java | 25 |
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. |
