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.java6
-rw-r--r--core/java/android/app/ApplicationPackageManager.java2
-rw-r--r--core/java/android/app/ContextImpl.java9
-rw-r--r--core/java/android/app/LoadedApk.java9
-rw-r--r--core/java/android/app/ResourcesManager.java8
-rw-r--r--core/java/android/content/pm/PackageInfo.java10
-rw-r--r--core/java/android/content/pm/PackageParser.java41
-rw-r--r--core/java/android/content/res/AssetManager.java16
8 files changed, 85 insertions, 16 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 9f21a36..4b86b0c 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1541,11 +1541,11 @@ public final class ActivityThread {
/**
* Creates the top level resources for the given package.
*/
- Resources getTopLevelResources(String resDir,
+ Resources getTopLevelResources(String resDir, String[] overlayDirs,
int displayId, Configuration overrideConfiguration,
LoadedApk pkgInfo) {
- return mResourcesManager.getTopLevelResources(resDir, displayId, overrideConfiguration,
- pkgInfo.getCompatibilityInfo(), null);
+ return mResourcesManager.getTopLevelResources(resDir, overlayDirs, displayId,
+ overrideConfiguration, pkgInfo.getCompatibilityInfo(), null);
}
final Handler getHandler() {
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index b505d4f..a280448 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -774,7 +774,7 @@ final class ApplicationPackageManager extends PackageManager {
}
Resources r = mContext.mMainThread.getTopLevelResources(
app.uid == Process.myUid() ? app.sourceDir : app.publicSourceDir,
- Display.DEFAULT_DISPLAY, null, mContext.mPackageInfo);
+ app.resourceDirs, 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 190ddb4..8d127c6 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1911,8 +1911,8 @@ class ContextImpl extends Context {
ContextImpl c = new ContextImpl();
c.init(mPackageInfo, null, mMainThread);
c.mResources = mResourcesManager.getTopLevelResources(mPackageInfo.getResDir(),
- getDisplayId(), overrideConfiguration, mResources.getCompatibilityInfo(),
- mActivityToken);
+ mPackageInfo.getOverlayDirs(), getDisplayId(), overrideConfiguration,
+ mResources.getCompatibilityInfo(), mActivityToken);
return c;
}
@@ -1929,7 +1929,7 @@ class ContextImpl extends Context {
context.mDisplay = display;
DisplayAdjustments daj = getDisplayAdjustments(displayId);
context.mResources = mResourcesManager.getTopLevelResources(mPackageInfo.getResDir(),
- displayId, null, daj.getCompatibilityInfo(), null);
+ mPackageInfo.getOverlayDirs(), displayId, null, daj.getCompatibilityInfo(), null);
return context;
}
@@ -2041,7 +2041,8 @@ class ContextImpl extends Context {
mDisplayAdjustments.setCompatibilityInfo(compatInfo);
mDisplayAdjustments.setActivityToken(activityToken);
mResources = mResourcesManager.getTopLevelResources(mPackageInfo.getResDir(),
- Display.DEFAULT_DISPLAY, null, compatInfo, activityToken);
+ mPackageInfo.getOverlayDirs(), Display.DEFAULT_DISPLAY, null, compatInfo,
+ activityToken);
} else {
mDisplayAdjustments.setCompatibilityInfo(packageInfo.getCompatibilityInfo());
mDisplayAdjustments.setActivityToken(activityToken);
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 4239a5d..0115d1b 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -76,6 +76,7 @@ public final class LoadedApk {
final String mPackageName;
private final String mAppDir;
private final String mResDir;
+ private final String[] mOverlayDirs;
private final String[] mSharedLibraries;
private final String mDataDir;
private final String mLibDir;
@@ -120,6 +121,7 @@ public final class LoadedApk {
final int myUid = Process.myUid();
mResDir = aInfo.uid == myUid ? aInfo.sourceDir
: aInfo.publicSourceDir;
+ mOverlayDirs = aInfo.resourceDirs;
if (!UserHandle.isSameUser(aInfo.uid, myUid) && !Process.isIsolated()) {
aInfo.dataDir = PackageManager.getDataDirForUser(UserHandle.getUserId(myUid),
mPackageName);
@@ -159,6 +161,7 @@ public final class LoadedApk {
mPackageName = name;
mAppDir = null;
mResDir = null;
+ mOverlayDirs = null;
mSharedLibraries = null;
mDataDir = null;
mDataDirFile = null;
@@ -471,6 +474,10 @@ public final class LoadedApk {
return mResDir;
}
+ public String[] getOverlayDirs() {
+ return mOverlayDirs;
+ }
+
public String getDataDir() {
return mDataDir;
}
@@ -485,7 +492,7 @@ public final class LoadedApk {
public Resources getResources(ActivityThread mainThread) {
if (mResources == null) {
- mResources = mainThread.getTopLevelResources(mResDir,
+ mResources = mainThread.getTopLevelResources(mResDir, mOverlayDirs,
Display.DEFAULT_DISPLAY, null, this);
}
return mResources;
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index f55dba4..728f372 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -147,7 +147,7 @@ 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, int displayId,
+ public Resources getTopLevelResources(String resDir, String[] overlayDirs, int displayId,
Configuration overrideConfiguration, CompatibilityInfo compatInfo, IBinder token) {
final float scale = compatInfo.applicationScale;
ResourcesKey key = new ResourcesKey(resDir, displayId, overrideConfiguration, scale,
@@ -180,6 +180,12 @@ public class ResourcesManager {
return null;
}
+ if (overlayDirs != null) {
+ for (String idmapPath : overlayDirs) {
+ assets.addOverlayPath(idmapPath);
+ }
+ }
+
//Slog.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
DisplayMetrics dm = getDisplayMetricsLocked(displayId);
Configuration config;
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
index af1a6d5..785f2b4 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -227,6 +227,14 @@ public class PackageInfo implements Parcelable {
/** @hide */
public String requiredAccountType;
+ /**
+ * What package, if any, this package will overlay.
+ *
+ * Package name of target package, or null.
+ * @hide
+ */
+ public String overlayTarget;
+
public PackageInfo() {
}
@@ -270,6 +278,7 @@ public class PackageInfo implements Parcelable {
dest.writeInt(requiredForAllUsers ? 1 : 0);
dest.writeString(restrictedAccountType);
dest.writeString(requiredAccountType);
+ dest.writeString(overlayTarget);
}
public static final Parcelable.Creator<PackageInfo> CREATOR
@@ -311,5 +320,6 @@ public class PackageInfo implements Parcelable {
requiredForAllUsers = source.readInt() != 0;
restrictedAccountType = source.readString();
requiredAccountType = source.readString();
+ overlayTarget = source.readString();
}
}
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 4607902..52564eb 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -307,6 +307,7 @@ public class PackageParser {
}
pi.restrictedAccountType = p.mRestrictedAccountType;
pi.requiredAccountType = p.mRequiredAccountType;
+ pi.overlayTarget = p.mOverlayTarget;
pi.firstInstallTime = firstInstallTime;
pi.lastUpdateTime = lastUpdateTime;
if ((flags&PackageManager.GET_GIDS) != 0) {
@@ -490,6 +491,11 @@ public class PackageParser {
public Package parsePackage(File sourceFile, String destCodePath,
DisplayMetrics metrics, int flags) {
+ return parsePackage(sourceFile, destCodePath, metrics, flags, false);
+ }
+
+ public Package parsePackage(File sourceFile, String destCodePath,
+ DisplayMetrics metrics, int flags, boolean trustedOverlay) {
mParseError = PackageManager.INSTALL_SUCCEEDED;
mArchiveSourcePath = sourceFile.getPath();
@@ -542,7 +548,7 @@ public class PackageParser {
Exception errorException = null;
try {
// XXXX todo: need to figure out correct configuration.
- pkg = parsePackage(res, parser, flags, errorText);
+ pkg = parsePackage(res, parser, flags, trustedOverlay, errorText);
} catch (Exception e) {
errorException = e;
mParseError = PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION;
@@ -951,8 +957,8 @@ public class PackageParser {
}
private Package parsePackage(
- Resources res, XmlResourceParser parser, int flags, String[] outError)
- throws XmlPullParserException, IOException {
+ Resources res, XmlResourceParser parser, int flags, boolean trustedOverlay,
+ String[] outError) throws XmlPullParserException, IOException {
AttributeSet attrs = parser;
mParseInstrumentationArgs = null;
@@ -1051,6 +1057,31 @@ public class PackageParser {
if (!parseApplication(pkg, res, parser, attrs, flags, outError)) {
return null;
}
+ } else if (tagName.equals("overlay")) {
+ pkg.mTrustedOverlay = trustedOverlay;
+
+ sa = res.obtainAttributes(attrs,
+ com.android.internal.R.styleable.AndroidManifestResourceOverlay);
+ pkg.mOverlayTarget = sa.getString(
+ com.android.internal.R.styleable.AndroidManifestResourceOverlay_targetPackage);
+ pkg.mOverlayPriority = sa.getInt(
+ com.android.internal.R.styleable.AndroidManifestResourceOverlay_priority,
+ -1);
+ sa.recycle();
+
+ if (pkg.mOverlayTarget == null) {
+ outError[0] = "<overlay> does not specify a target package";
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+ return null;
+ }
+ if (pkg.mOverlayPriority < 0 || pkg.mOverlayPriority > 9999) {
+ outError[0] = "<overlay> priority must be between 0 and 9999";
+ mParseError =
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+ return null;
+ }
+ XmlUtils.skipCurrentTag(parser);
+
} else if (tagName.equals("keys")) {
if (!parseKeys(pkg, res, parser, attrs, outError)) {
return null;
@@ -3546,6 +3577,10 @@ public class PackageParser {
*/
public ManifestDigest manifestDigest;
+ public String mOverlayTarget;
+ public int mOverlayPriority;
+ public boolean mTrustedOverlay;
+
/**
* Data used to feed the KeySetManager
*/
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index 780c4be..418bdda 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -90,7 +90,7 @@ public final class AssetManager {
mNumRefs = 0;
incRefsLocked(this.hashCode());
}
- init();
+ init(false);
if (localLOGV) Log.v(TAG, "New asset manager: " + this);
ensureSystemAssets();
}
@@ -113,7 +113,7 @@ public final class AssetManager {
incRefsLocked(this.hashCode());
}
}
- init();
+ init(true);
if (localLOGV) Log.v(TAG, "New asset manager: " + this);
}
@@ -615,6 +615,16 @@ public final class AssetManager {
private native final int addAssetPathNative(String path);
+ /**
+ * Add a set of assets to overlay an already added set of assets.
+ *
+ * This is only intended for application resources. System wide resources
+ * are handled before any Java code is executed.
+ *
+ * {@hide}
+ */
+ public native final int addOverlayPath(String idmapPath);
+
/**
* Add multiple sets of assets to the asset manager at once. See
* {@link #addAssetPath(String)} for more information. Returns array of
@@ -752,7 +762,7 @@ public final class AssetManager {
private native final int[] getArrayStringInfo(int arrayRes);
/*package*/ native final int[] getArrayIntResource(int arrayRes);
- private native final void init();
+ private native final void init(boolean isSystem);
private native final void destroy();
private final void incRefsLocked(long id) {