summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/ActivityThread.java3
-rw-r--r--core/java/android/app/ApplicationPackageManager.java3
-rw-r--r--core/java/android/app/ResourcesManager.java65
-rw-r--r--core/java/android/content/res/ResourcesKey.java15
-rw-r--r--core/java/android/content/res/ThemeConfig.java1
5 files changed, 74 insertions, 13 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 1383c13..c302647 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1709,7 +1709,8 @@ public final class ActivityThread {
/**
* Creates the top level resources for the given package.
*/
- Resources getTopLevelThemedResources(String resDir, int displayId, LoadedApk pkgInfo,
+ Resources getTopLevelThemedResources(String resDir, int displayId,
+ Configuration overrideConfiguration, LoadedApk pkgInfo,
String pkgName, String themePkgName) {
return mResourcesManager.getTopLevelThemedResources(resDir, displayId, pkgName,
themePkgName, pkgInfo.getCompatibilityInfo(),
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 992310c..1b89a38 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1080,7 +1080,8 @@ final class ApplicationPackageManager extends PackageManager {
Resources r = mContext.mMainThread.getTopLevelThemedResources(
app.uid == Process.myUid() ? app.sourceDir : app.publicSourceDir,
- Display.DEFAULT_DISPLAY, mContext.mPackageInfo, app.packageName, themePkgName);
+ Display.DEFAULT_DISPLAY, null, mContext.mPackageInfo, app.packageName,
+ themePkgName);
if (r != null) {
return r;
}
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index b30df45..5699427 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -183,7 +183,7 @@ public class ResourcesManager {
Configuration overrideConfiguration, CompatibilityInfo compatInfo, Context context,
boolean isThemeable) {
final float scale = compatInfo.applicationScale;
- final ThemeConfig themeConfig = getThemeConfig();
+ final ThemeConfig themeConfig = isThemeable ? getThemeConfig() : null;
Configuration overrideConfigCopy = (overrideConfiguration != null)
? new Configuration(overrideConfiguration) : null;
ResourcesKey key = new ResourcesKey(resDir, displayId, overrideConfiguration, scale,
@@ -324,6 +324,32 @@ public class ResourcesManager {
String themePackageName, CompatibilityInfo compatInfo, boolean isThemeable) {
Resources r;
+ ThemeConfig themeConfig;
+ if (isThemeable) {
+ ThemeConfig.Builder builder = new ThemeConfig.Builder();
+ builder.defaultOverlay(themePackageName);
+ builder.defaultIcon(themePackageName);
+ builder.defaultFont(themePackageName);
+ themeConfig = builder.build();
+ } else {
+ themeConfig = null;
+ }
+
+ ResourcesKey key = new ResourcesKey(resDir, displayId, null, compatInfo.applicationScale,
+ isThemeable, isThemeable ? themeConfig : null);
+
+ synchronized (this) {
+ WeakReference<Resources> wr = mActiveResources.get(key);
+ r = wr != null ? wr.get() : null;
+ if (r != null && r.getAssets().isUpToDate()) {
+ if (false) {
+ Slog.w(TAG, "Returning cached resources " + r + " " + resDir
+ + ": appScale=" + r.getCompatibilityInfo().applicationScale);
+ }
+ return r;
+ }
+ }
+
AssetManager assets = new AssetManager();
assets.setAppName(packageName);
assets.setThemeSupport(isThemeable);
@@ -335,9 +361,15 @@ public class ResourcesManager {
DisplayMetrics dm = getDisplayMetricsLocked(displayId);
Configuration config;
boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
- if (!isDefaultDisplay) {
+ final boolean hasOverrideConfig = key.hasOverrideConfiguration();
+ if (!isDefaultDisplay || hasOverrideConfig) {
config = new Configuration(getConfiguration());
- applyNonDefaultDisplayMetricsToConfigurationLocked(dm, config);
+ if (!isDefaultDisplay) {
+ applyNonDefaultDisplayMetricsToConfigurationLocked(dm, config);
+ }
+ if (hasOverrideConfig) {
+ config.updateFrom(key.mOverrideConfiguration);
+ }
} else {
config = getConfiguration();
}
@@ -345,12 +377,6 @@ public class ResourcesManager {
boolean iconsAttached = false;
if (isThemeable) {
/* Attach theme information to the resulting AssetManager when appropriate. */
- ThemeConfig.Builder builder = new ThemeConfig.Builder();
- builder.defaultOverlay(themePackageName);
- builder.defaultIcon(themePackageName);
- builder.defaultFont(themePackageName);
-
- ThemeConfig themeConfig = builder.build();
attachThemeAssets(assets, themeConfig);
attachCommonAssets(assets, themeConfig);
iconsAttached = attachIconAssets(assets, themeConfig);
@@ -358,7 +384,26 @@ public class ResourcesManager {
r = new Resources(assets, dm, config, compatInfo);
if (iconsAttached) setActivityIcons(r);
- return r;
+ if (false) {
+ Slog.i(TAG, "Created THEMED app resources " + resDir + " " + r + ": "
+ + r.getConfiguration() + " appScale="
+ + r.getCompatibilityInfo().applicationScale);
+ }
+
+ synchronized (this) {
+ WeakReference<Resources> wr = mActiveResources.get(key);
+ Resources existing = wr != null ? wr.get() : null;
+ if (existing != null && existing.getAssets().isUpToDate()) {
+ // Someone else already created the resources while we were
+ // unlocked; go ahead and use theirs.
+ r.getAssets().close();
+ return existing;
+ }
+
+ // XXX need to remove entries when weak references go away
+ mActiveResources.put(key, new WeakReference<Resources>(r));
+ return r;
+ }
}
/**
diff --git a/core/java/android/content/res/ResourcesKey.java b/core/java/android/content/res/ResourcesKey.java
index 466d810..6cbf1d7 100644
--- a/core/java/android/content/res/ResourcesKey.java
+++ b/core/java/android/content/res/ResourcesKey.java
@@ -26,6 +26,7 @@ public final class ResourcesKey {
private final float mScale;
private final boolean mIsThemeable;
private final int mHash;
+ private final ThemeConfig mThemeConfig;
public final int mDisplayId;
@NonNull
@@ -39,6 +40,7 @@ public final class ResourcesKey {
? overrideConfiguration : Configuration.EMPTY;
mScale = scale;
mIsThemeable = isThemeable;
+ mThemeConfig = themeConfig;
int hash = 17;
hash = 31 * hash + (mResDir == null ? 0 : mResDir.hashCode());
@@ -78,7 +80,18 @@ public final class ResourcesKey {
if (mScale != peer.mScale) {
return false;
}
- return mIsThemeable == peer.mIsThemeable;
+ if (mIsThemeable != peer.mIsThemeable) {
+ return false;
+ }
+ if (mThemeConfig != peer.mThemeConfig) {
+ if (mThemeConfig == null || peer.mThemeConfig == null) {
+ return false;
+ }
+ if (!mThemeConfig.equals(peer.mThemeConfig)) {
+ return false;
+ }
+ }
+ return true;
}
@Override
diff --git a/core/java/android/content/res/ThemeConfig.java b/core/java/android/content/res/ThemeConfig.java
index 1791a72..602ef0a 100644
--- a/core/java/android/content/res/ThemeConfig.java
+++ b/core/java/android/content/res/ThemeConfig.java
@@ -20,6 +20,7 @@ import android.content.ContentResolver;
import android.content.res.ThemeChangeRequest.RequestType;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.UserHandle;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.JsonReader;