Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 723714ed authored by Roman Birg's avatar Roman Birg Committed by Clark Scheff
Browse files

Resources: cache themed resources



Change-Id: I408665180d19eb422386fc69bc9afa4bbe0d05d6
Signed-off-by: default avatarRoman Birg <roman@cyngn.com>
parent 690777ee
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -1709,7 +1709,8 @@ public final class ActivityThread {
    /**
    /**
     * Creates the top level resources for the given package.
     * 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) {
                                         String pkgName, String themePkgName) {
        return mResourcesManager.getTopLevelThemedResources(resDir, displayId, pkgName,
        return mResourcesManager.getTopLevelThemedResources(resDir, displayId, pkgName,
                themePkgName, pkgInfo.getCompatibilityInfo(),
                themePkgName, pkgInfo.getCompatibilityInfo(),
+2 −1
Original line number Original line Diff line number Diff line
@@ -1080,7 +1080,8 @@ final class ApplicationPackageManager extends PackageManager {


        Resources r = mContext.mMainThread.getTopLevelThemedResources(
        Resources r = mContext.mMainThread.getTopLevelThemedResources(
                app.uid == Process.myUid() ? app.sourceDir : app.publicSourceDir,
                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) {
        if (r != null) {
            return r;
            return r;
        }
        }
+55 −10
Original line number Original line Diff line number Diff line
@@ -183,7 +183,7 @@ public class ResourcesManager {
            Configuration overrideConfiguration, CompatibilityInfo compatInfo, Context context,
            Configuration overrideConfiguration, CompatibilityInfo compatInfo, Context context,
            boolean isThemeable) {
            boolean isThemeable) {
        final float scale = compatInfo.applicationScale;
        final float scale = compatInfo.applicationScale;
        final ThemeConfig themeConfig = getThemeConfig();
        final ThemeConfig themeConfig = isThemeable ? getThemeConfig() : null;
        Configuration overrideConfigCopy = (overrideConfiguration != null)
        Configuration overrideConfigCopy = (overrideConfiguration != null)
                ? new Configuration(overrideConfiguration) : null;
                ? new Configuration(overrideConfiguration) : null;
        ResourcesKey key = new ResourcesKey(resDir, displayId, overrideConfiguration, scale,
        ResourcesKey key = new ResourcesKey(resDir, displayId, overrideConfiguration, scale,
@@ -324,6 +324,32 @@ public class ResourcesManager {
            String themePackageName, CompatibilityInfo compatInfo, boolean isThemeable) {
            String themePackageName, CompatibilityInfo compatInfo, boolean isThemeable) {
        Resources r;
        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();
        AssetManager assets = new AssetManager();
        assets.setAppName(packageName);
        assets.setAppName(packageName);
        assets.setThemeSupport(isThemeable);
        assets.setThemeSupport(isThemeable);
@@ -335,9 +361,15 @@ public class ResourcesManager {
        DisplayMetrics dm = getDisplayMetricsLocked(displayId);
        DisplayMetrics dm = getDisplayMetricsLocked(displayId);
        Configuration config;
        Configuration config;
        boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
        boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
        if (!isDefaultDisplay) {
        final boolean hasOverrideConfig = key.hasOverrideConfiguration();
        if (!isDefaultDisplay || hasOverrideConfig) {
            config = new Configuration(getConfiguration());
            config = new Configuration(getConfiguration());
            if (!isDefaultDisplay) {
                applyNonDefaultDisplayMetricsToConfigurationLocked(dm, config);
                applyNonDefaultDisplayMetricsToConfigurationLocked(dm, config);
            }
            if (hasOverrideConfig) {
                config.updateFrom(key.mOverrideConfiguration);
            }
        } else {
        } else {
            config = getConfiguration();
            config = getConfiguration();
        }
        }
@@ -345,12 +377,6 @@ public class ResourcesManager {
        boolean iconsAttached = false;
        boolean iconsAttached = false;
        if (isThemeable) {
        if (isThemeable) {
            /* Attach theme information to the resulting AssetManager when appropriate. */
            /* 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);
            attachThemeAssets(assets, themeConfig);
            attachCommonAssets(assets, themeConfig);
            attachCommonAssets(assets, themeConfig);
            iconsAttached = attachIconAssets(assets, themeConfig);
            iconsAttached = attachIconAssets(assets, themeConfig);
@@ -358,8 +384,27 @@ public class ResourcesManager {
        r = new Resources(assets, dm, config, compatInfo);
        r = new Resources(assets, dm, config, compatInfo);
        if (iconsAttached) setActivityIcons(r);
        if (iconsAttached) setActivityIcons(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;
            return r;
        }
        }
    }


    /**
    /**
     * Creates a map between an activity & app's icon ids to its component info. This map
     * Creates a map between an activity & app's icon ids to its component info. This map
+14 −1
Original line number Original line Diff line number Diff line
@@ -26,6 +26,7 @@ public final class ResourcesKey {
    private final float mScale;
    private final float mScale;
    private final boolean mIsThemeable;
    private final boolean mIsThemeable;
    private final int mHash;
    private final int mHash;
    private final ThemeConfig mThemeConfig;


    public final int mDisplayId;
    public final int mDisplayId;
    @NonNull
    @NonNull
@@ -39,6 +40,7 @@ public final class ResourcesKey {
                ? overrideConfiguration : Configuration.EMPTY;
                ? overrideConfiguration : Configuration.EMPTY;
        mScale = scale;
        mScale = scale;
        mIsThemeable = isThemeable;
        mIsThemeable = isThemeable;
        mThemeConfig = themeConfig;


        int hash = 17;
        int hash = 17;
        hash = 31 * hash + (mResDir == null ? 0 : mResDir.hashCode());
        hash = 31 * hash + (mResDir == null ? 0 : mResDir.hashCode());
@@ -78,7 +80,18 @@ public final class ResourcesKey {
        if (mScale != peer.mScale) {
        if (mScale != peer.mScale) {
            return false;
            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
    @Override
+1 −0
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@ import android.content.ContentResolver;
import android.content.res.ThemeChangeRequest.RequestType;
import android.content.res.ThemeChangeRequest.RequestType;
import android.os.Parcel;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Parcelable;
import android.os.UserHandle;
import android.provider.Settings;
import android.provider.Settings;
import android.text.TextUtils;
import android.text.TextUtils;
import android.util.JsonReader;
import android.util.JsonReader;