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

Commit a62e3e4d authored by Mitsuru Oshima's avatar Mitsuru Oshima Committed by The Android Open Source Project
Browse files

am ba3ba579: * Use cached resources for widgets

Merge commit 'ba3ba579'

* commit 'ba3ba579':
  * Use cached resources for widgets
parents 602bee5b ba3ba579
Loading
Loading
Loading
Loading
+58 −19
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import android.content.pm.ProviderInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.PackageParser.Component;
import android.content.res.AssetManager;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.sqlite.SQLiteDatabase;
@@ -166,43 +167,52 @@ public final class ActivityThread {
        return metrics;
    }

    Resources getTopLevelResources(String appDir, PackageInfo pkgInfo) {
    /**
     * Creates the top level Resources for applications with the given compatibility info.
     *
     * @param resDir the resource directory.
     * @param compInfo the compability info. It will use the default compatibility info when it's
     * null.
     */
    Resources getTopLevelResources(String resDir, CompatibilityInfo compInfo) {
        synchronized (mPackages) {
            //Log.w(TAG, "getTopLevelResources: " + appDir);
            WeakReference<Resources> wr = mActiveResources.get(appDir);
            // Resources is app scale dependent.
            ResourcesKey key = new ResourcesKey(resDir, compInfo.applicationScale);
            //Log.w(TAG, "getTopLevelResources: " + resDir);
            WeakReference<Resources> wr = mActiveResources.get(key);
            Resources r = wr != null ? wr.get() : null;
            if (r != null && r.getAssets().isUpToDate()) {
                //Log.w(TAG, "Returning cached resources " + r + " " + appDir);
                //Log.w(TAG, "Returning cached resources " + r + " " + resDir);
                return r;
            }

            //if (r != null) {
            //    Log.w(TAG, "Throwing away out-of-date resources!!!! "
            //            + r + " " + appDir);
            //            + r + " " + resDir);
            //}

            AssetManager assets = new AssetManager();
            if (assets.addAssetPath(appDir) == 0) {
            if (assets.addAssetPath(resDir) == 0) {
                return null;
            }
            ApplicationInfo appInfo;
            try {
                appInfo = getPackageManager().getApplicationInfo(
                        pkgInfo.getPackageName(),
                        PackageManager.GET_SUPPORTS_DENSITIES);
            } catch (RemoteException e) {
                throw new AssertionError(e);
            }
            //Log.i(TAG, "Resource:" + appDir + ", display metrics=" + metrics);

            //Log.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
            DisplayMetrics metrics = getDisplayMetricsLocked(false);
            r = new Resources(assets, metrics, getConfiguration(), appInfo);
            r = new Resources(assets, metrics, getConfiguration(), compInfo);
            //Log.i(TAG, "Created app resources " + r + ": " + r.getConfiguration());
            // XXX need to remove entries when weak references go away
            mActiveResources.put(appDir, new WeakReference<Resources>(r));
            mActiveResources.put(key, new WeakReference<Resources>(r));
            return r;
        }
    }

    /**
     * Creates the top level resources for the given package.
     */
    Resources getTopLevelResources(String resDir, PackageInfo pkgInfo) {
        return getTopLevelResources(resDir, pkgInfo.mCompatibilityInfo);
    }

    final Handler getHandler() {
        return mH;
    }
@@ -223,6 +233,7 @@ public final class ActivityThread {
        private Resources mResources;
        private ClassLoader mClassLoader;
        private Application mApplication;
        private CompatibilityInfo mCompatibilityInfo;

        private final HashMap<Context, HashMap<BroadcastReceiver, ReceiverDispatcher>> mReceivers
            = new HashMap<Context, HashMap<BroadcastReceiver, ReceiverDispatcher>>();
@@ -250,6 +261,7 @@ public final class ActivityThread {
            mBaseClassLoader = baseLoader;
            mSecurityViolation = securityViolation;
            mIncludeCode = includeCode;
            mCompatibilityInfo = new CompatibilityInfo(aInfo);

            if (mAppDir == null) {
                if (mSystemContext == null) {
@@ -283,6 +295,7 @@ public final class ActivityThread {
            mIncludeCode = true;
            mClassLoader = systemContext.getClassLoader();
            mResources = systemContext.getResources();
            mCompatibilityInfo = new CompatibilityInfo(mApplicationInfo);
        }

        public String getPackageName() {
@@ -1894,6 +1907,32 @@ public final class ActivityThread {
        }
    }

    private final static class ResourcesKey {
        final private String mResDir;
        final private float mScale;
        final private int mHash;
        
        ResourcesKey(String resDir, float scale) {
            mResDir = resDir;
            mScale = scale;
            mHash = mResDir.hashCode() << 2 + (int) (mScale * 2);
        }
        
        @Override
        public int hashCode() {
            return mHash;
        }

        @Override
        public boolean equals(Object obj) {
            if (!(obj instanceof ResourcesKey)) {
                return false;
            }
            ResourcesKey peer = (ResourcesKey) obj;
            return mResDir.equals(peer.mResDir) && mScale == peer.mScale;
        }
    }

    static IPackageManager sPackageManager;

    final ApplicationThread mAppThread = new ApplicationThread();
@@ -1939,8 +1978,8 @@ public final class ActivityThread {
        = new HashMap<String, WeakReference<PackageInfo>>();
    Display mDisplay = null;
    DisplayMetrics mDisplayMetrics = null;
    HashMap<String, WeakReference<Resources> > mActiveResources
        = new HashMap<String, WeakReference<Resources> >();
    HashMap<ResourcesKey, WeakReference<Resources> > mActiveResources
        = new HashMap<ResourcesKey, WeakReference<Resources> >();

    // The lock of mProviderMap protects the following variables.
    final HashMap<String, ProviderRecord> mProviderMap
+17 −14
Original line number Diff line number Diff line
@@ -1357,21 +1357,8 @@ class ApplicationContext extends Context {
        if (pi != null) {
            ApplicationContext c = new ApplicationContext();
            c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
            c.init(pi, null, mMainThread);
            c.init(pi, null, mMainThread, mResources);
            if (c.mResources != null) {
                Resources newRes = c.mResources;
                if (mResources.getCompatibilityInfo().applicationScale !=
                    newRes.getCompatibilityInfo().applicationScale) {
                    DisplayMetrics dm = mMainThread.getDisplayMetricsLocked(false);
                    c.mResources = new Resources(newRes.getAssets(), dm,
                            newRes.getConfiguration(),
                            mResources.getCompatibilityInfo().copy());
                    if (DEBUG) {
                        Log.d(TAG, "loaded context has different scaling. Using container's" +
                                " compatiblity info:" + mResources.getDisplayMetrics());
                    }

                }
                return c;
            }
        }
@@ -1433,8 +1420,24 @@ class ApplicationContext extends Context {

    final void init(ActivityThread.PackageInfo packageInfo,
            IBinder activityToken, ActivityThread mainThread) {
        init(packageInfo, activityToken, mainThread, null);
    }

    final void init(ActivityThread.PackageInfo packageInfo,
                IBinder activityToken, ActivityThread mainThread,
                Resources container) {
        mPackageInfo = packageInfo;
        mResources = mPackageInfo.getResources(mainThread);

        if (container != null && container.getCompatibilityInfo().applicationScale !=
            mResources.getCompatibilityInfo().applicationScale) {
            if (DEBUG) {
                Log.d(TAG, "loaded context has different scaling. Using container's" +
                        " compatiblity info:" + container.getDisplayMetrics());
            }
            mResources = mainThread.getTopLevelResources(
                    mPackageInfo.getResDir(), container.getCompatibilityInfo().copy());
        }
        mMainThread = mainThread;
        mContentResolver = new ApplicationContentResolver(this, mainThread);

+1 −1
Original line number Diff line number Diff line
@@ -979,12 +979,12 @@ public class PackageParser {
        /**
         * TODO: enable this before code freeze. b/1967935
         * *
         */
        if ((densities == null || densities.length == 0)
                && (pkg.applicationInfo.targetSdkVersion
                        >= android.os.Build.VERSION_CODES.CUR_DEVELOPMENT)) {
            pkg.supportsDensities = ApplicationInfo.ANY_DENSITIES_ARRAY;
        }
         */

        return pkg;
    }
+7 −30
Original line number Diff line number Diff line
@@ -129,53 +129,30 @@ public class Resources {
     */
    public Resources(AssetManager assets, DisplayMetrics metrics,
            Configuration config) {
        this(assets, metrics, config, (ApplicationInfo) null);
        this(assets, metrics, config, (CompatibilityInfo) null);
    }

    /**
     * Creates a new Resources object with ApplicationInfo.
     * Creates a new Resources object with CompatibilityInfo.
     * 
     * @param assets Previously created AssetManager. 
     * @param metrics Current display metrics to consider when 
     *                selecting/computing resource values.
     * @param config Desired device configuration to consider when 
     *               selecting/computing resource values (optional).
     * @param appInfo this resource's application info.
     * @param compInfo this resource's compatibility info. It will use the default compatibility
     *  info when it's null.
     * @hide
     */
    public Resources(AssetManager assets, DisplayMetrics metrics,
            Configuration config, ApplicationInfo appInfo) {
            Configuration config, CompatibilityInfo compInfo) {
        mAssets = assets;
        mConfiguration.setToDefaults();
        mMetrics.setToDefaults();
        if (appInfo != null) {
            mCompatibilityInfo = new CompatibilityInfo(appInfo);
            if (DEBUG_CONFIG) {
                Log.d(TAG, "compatibility for " + appInfo.packageName + " : " + mCompatibilityInfo);
            }
        } else {
        if (compInfo == null) {
            mCompatibilityInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
        }
        updateConfiguration(config, metrics);
        assets.ensureStringBlocks();
        if (mCompatibilityInfo.isScalingRequired()) {
            mPreloadedDrawables = emptySparseArray();
        } else {
            mPreloadedDrawables = sPreloadedDrawables;
        }
            mCompatibilityInfo = compInfo;
        }

    /**
     * Creates a new resources that uses the given compatibility info. Used to create
     * a context for widgets using the container's compatibility info.
     * {@see ApplicationContext#createPackageCotnext}.
     * @hide
     */
    public Resources(AssetManager assets, DisplayMetrics metrics,
            Configuration config, CompatibilityInfo info) {
        mAssets = assets;
        mMetrics.setToDefaults();
        mCompatibilityInfo = info;
        updateConfiguration(config, metrics);
        assets.ensureStringBlocks();
        if (mCompatibilityInfo.isScalingRequired()) {