ResourcesManager.java revision add005cf94dcc815d29b54588c76fd87929075b3
188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner/*
288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner * Copyright (C) 2013 The Android Open Source Project
388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner *
488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner * Licensed under the Apache License, Version 2.0 (the "License");
588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner * you may not use this file except in compliance with the License.
688c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner * You may obtain a copy of the License at
788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner *
888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner *      http://www.apache.org/licenses/LICENSE-2.0
988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner *
1088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner * Unless required by applicable law or agreed to in writing, software
1188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner * distributed under the License is distributed on an "AS IS" BASIS,
1288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner * See the License for the specific language governing permissions and
1488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner * limitations under the License.
1588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner */
1688c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
1788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautnerpackage android.app;
1888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
1988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautnerimport static android.app.ActivityThread.DEBUG_CONFIGURATION;
2088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
2188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautnerimport android.content.pm.ActivityInfo;
2288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautnerimport android.content.res.AssetManager;
2388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautnerimport android.content.res.CompatibilityInfo;
2488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautnerimport android.content.res.Configuration;
2588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautnerimport android.content.res.Resources;
2688c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautnerimport android.content.res.ResourcesKey;
2788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautnerimport android.hardware.display.DisplayManagerGlobal;
2888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautnerimport android.os.IBinder;
2988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautnerimport android.util.ArrayMap;
3088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautnerimport android.util.DisplayMetrics;
3188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautnerimport android.util.Slog;
3288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautnerimport android.view.Display;
3388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautnerimport android.view.DisplayAdjustments;
3488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
3588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautnerimport java.lang.ref.WeakReference;
3688c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautnerimport java.util.Locale;
3788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
3888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner/** @hide */
3988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautnerpublic class ResourcesManager {
4088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    static final String TAG = "ResourcesManager";
4188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    static final boolean DEBUG_CACHE = false;
4288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    static final boolean DEBUG_STATS = true;
4388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
4488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    private static ResourcesManager sResourcesManager;
45add005cf94dcc815d29b54588c76fd87929075b3Dianne Hackborn    final ArrayMap<ResourcesKey, WeakReference<Resources> > mActiveResources
46add005cf94dcc815d29b54588c76fd87929075b3Dianne Hackborn            = new ArrayMap<ResourcesKey, WeakReference<Resources> >();
4788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
4888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    final ArrayMap<DisplayAdjustments, DisplayMetrics> mDefaultDisplayMetrics
4988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            = new ArrayMap<DisplayAdjustments, DisplayMetrics>();
5088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
5188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    CompatibilityInfo mResCompatibilityInfo;
5288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
5388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    Configuration mResConfiguration;
5488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    final Configuration mTmpConfig = new Configuration();
5588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
5688c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    public static ResourcesManager getInstance() {
5788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        synchronized (ResourcesManager.class) {
5888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            if (sResourcesManager == null) {
5988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                sResourcesManager = new ResourcesManager();
6088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            }
6188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            return sResourcesManager;
6288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        }
6388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    }
6488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
6588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    public Configuration getConfiguration() {
6688c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        return mResConfiguration;
6788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    }
6888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
6988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    public void flushDisplayMetricsLocked() {
7088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        mDefaultDisplayMetrics.clear();
7188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    }
7288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
7388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    public DisplayMetrics getDisplayMetricsLocked(int displayId) {
7488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        return getDisplayMetricsLocked(displayId, DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
7588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    }
7688c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
7788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    public DisplayMetrics getDisplayMetricsLocked(int displayId, DisplayAdjustments daj) {
7888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
7988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        DisplayMetrics dm = isDefaultDisplay ? mDefaultDisplayMetrics.get(daj) : null;
8088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        if (dm != null) {
8188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            return dm;
8288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        }
8388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        dm = new DisplayMetrics();
8488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
8588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        DisplayManagerGlobal displayManager = DisplayManagerGlobal.getInstance();
8688c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        if (displayManager == null) {
8788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            // may be null early in system startup
8888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            dm.setToDefaults();
8988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            return dm;
9088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        }
9188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
9288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        if (isDefaultDisplay) {
9388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            mDefaultDisplayMetrics.put(daj, dm);
9488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        }
9588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
9688c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        Display d = displayManager.getCompatibleDisplay(displayId, daj);
9788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        if (d != null) {
9888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            d.getMetrics(dm);
9988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        } else {
10088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            // Display no longer exists
10188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            // FIXME: This would not be a problem if we kept the Display object around
10288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            // instead of using the raw display id everywhere.  The Display object caches
10388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            // its information even after the display has been removed.
10488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            dm.setToDefaults();
10588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        }
10688c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        //Slog.i("foo", "New metrics: w=" + metrics.widthPixels + " h="
10788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        //        + metrics.heightPixels + " den=" + metrics.density
10888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        //        + " xdpi=" + metrics.xdpi + " ydpi=" + metrics.ydpi);
10988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        return dm;
11088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    }
11188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
11288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    final void applyNonDefaultDisplayMetricsToConfigurationLocked(
11388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            DisplayMetrics dm, Configuration config) {
11488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
11588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        config.densityDpi = dm.densityDpi;
11688c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        config.screenWidthDp = (int)(dm.widthPixels / dm.density);
11788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        config.screenHeightDp = (int)(dm.heightPixels / dm.density);
11888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        int sl = Configuration.resetScreenLayout(config.screenLayout);
11988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        if (dm.widthPixels > dm.heightPixels) {
12088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            config.orientation = Configuration.ORIENTATION_LANDSCAPE;
12188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            config.screenLayout = Configuration.reduceScreenLayout(sl,
12288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                    config.screenWidthDp, config.screenHeightDp);
12388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        } else {
12488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            config.orientation = Configuration.ORIENTATION_PORTRAIT;
12588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            config.screenLayout = Configuration.reduceScreenLayout(sl,
12688c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                    config.screenHeightDp, config.screenWidthDp);
12788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        }
12888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        config.smallestScreenWidthDp = config.screenWidthDp; // assume screen does not rotate
12988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        config.compatScreenWidthDp = config.screenWidthDp;
13088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        config.compatScreenHeightDp = config.screenHeightDp;
13188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        config.compatSmallestScreenWidthDp = config.smallestScreenWidthDp;
13288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    }
13388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
13488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    public boolean applyCompatConfiguration(int displayDensity,
13588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            Configuration compatConfiguration) {
13688c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        if (mResCompatibilityInfo != null && !mResCompatibilityInfo.supportsScreen()) {
13788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            mResCompatibilityInfo.applyToConfiguration(displayDensity, compatConfiguration);
13888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            return true;
13988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        }
14088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        return false;
14188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    }
14288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
14388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    /**
14488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner     * Creates the top level Resources for applications with the given compatibility info.
14588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner     *
14688c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner     * @param resDir the resource directory.
14788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner     * @param compatInfo the compability info. Must not be null.
14888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner     * @param token the application token for determining stack bounds.
14988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner     */
15088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    public Resources getTopLevelResources(String resDir, int displayId,
15188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            Configuration overrideConfiguration, CompatibilityInfo compatInfo, IBinder token) {
15288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        final float scale = compatInfo.applicationScale;
15388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        ResourcesKey key = new ResourcesKey(resDir, displayId, overrideConfiguration, scale,
15488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                token);
15588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        Resources r;
15688c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        synchronized (this) {
15788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            // Resources is app scale dependent.
15888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            if (false) {
15988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                Slog.w(TAG, "getTopLevelResources: " + resDir + " / " + scale);
16088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            }
16188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            WeakReference<Resources> wr = mActiveResources.get(key);
16288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            r = wr != null ? wr.get() : null;
16388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            //if (r != null) Slog.i(TAG, "isUpToDate " + resDir + ": " + r.getAssets().isUpToDate());
16488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            if (r != null && r.getAssets().isUpToDate()) {
16588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                if (false) {
16688c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                    Slog.w(TAG, "Returning cached resources " + r + " " + resDir
16788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                            + ": appScale=" + r.getCompatibilityInfo().applicationScale);
16888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                }
16988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                return r;
17088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            }
17188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        }
17288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
17388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        //if (r != null) {
17488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        //    Slog.w(TAG, "Throwing away out-of-date resources!!!! "
17588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        //            + r + " " + resDir);
17688c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        //}
17788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
17888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        AssetManager assets = new AssetManager();
17988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        if (assets.addAssetPath(resDir) == 0) {
18088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            return null;
18188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        }
18288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
18388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        //Slog.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
18488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        DisplayMetrics dm = getDisplayMetricsLocked(displayId);
18588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        Configuration config;
18688c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
18788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        final boolean hasOverrideConfig = key.hasOverrideConfiguration();
18888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        if (!isDefaultDisplay || hasOverrideConfig) {
18988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            config = new Configuration(getConfiguration());
19088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            if (!isDefaultDisplay) {
19188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                applyNonDefaultDisplayMetricsToConfigurationLocked(dm, config);
19288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            }
19388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            if (hasOverrideConfig) {
19488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                config.updateFrom(key.mOverrideConfiguration);
19588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            }
19688c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        } else {
19788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            config = getConfiguration();
19888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        }
19988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        r = new Resources(assets, dm, config, compatInfo, token);
20088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        if (false) {
20188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            Slog.i(TAG, "Created app resources " + resDir + " " + r + ": "
20288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                    + r.getConfiguration() + " appScale="
20388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                    + r.getCompatibilityInfo().applicationScale);
20488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        }
20588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
20688c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        synchronized (this) {
20788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            WeakReference<Resources> wr = mActiveResources.get(key);
20888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            Resources existing = wr != null ? wr.get() : null;
20988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            if (existing != null && existing.getAssets().isUpToDate()) {
21088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                // Someone else already created the resources while we were
21188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                // unlocked; go ahead and use theirs.
21288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                r.getAssets().close();
21388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                return existing;
21488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            }
21588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
21688c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            // XXX need to remove entries when weak references go away
21788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            mActiveResources.put(key, new WeakReference<Resources>(r));
21888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            return r;
21988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        }
22088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    }
22188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
22288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    public final boolean applyConfigurationToResourcesLocked(Configuration config,
22388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            CompatibilityInfo compat) {
22488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        if (mResConfiguration == null) {
22588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            mResConfiguration = new Configuration();
22688c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        }
22788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        if (!mResConfiguration.isOtherSeqNewer(config) && compat == null) {
22888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Skipping new config: curSeq="
22988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                    + mResConfiguration.seq + ", newSeq=" + config.seq);
23088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            return false;
23188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        }
23288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        int changes = mResConfiguration.updateFrom(config);
23388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        flushDisplayMetricsLocked();
23488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        DisplayMetrics defaultDisplayMetrics = getDisplayMetricsLocked(Display.DEFAULT_DISPLAY);
23588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
23688c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        if (compat != null && (mResCompatibilityInfo == null ||
23788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                !mResCompatibilityInfo.equals(compat))) {
23888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            mResCompatibilityInfo = compat;
23988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            changes |= ActivityInfo.CONFIG_SCREEN_LAYOUT
24088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                    | ActivityInfo.CONFIG_SCREEN_SIZE
24188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                    | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
24288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        }
24388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
24488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        // set it for java, this also affects newly created Resources
24588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        if (config.locale != null) {
24688c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            Locale.setDefault(config.locale);
24788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        }
24888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
24988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        Resources.updateSystemConfiguration(config, defaultDisplayMetrics, compat);
25088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
25188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        ApplicationPackageManager.configurationChanged();
25288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        //Slog.i(TAG, "Configuration changed in " + currentPackageName());
25388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
25488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        Configuration tmpConfig = null;
25588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
256add005cf94dcc815d29b54588c76fd87929075b3Dianne Hackborn        for (int i=mActiveResources.size()-1; i>=0; i--) {
257add005cf94dcc815d29b54588c76fd87929075b3Dianne Hackborn            ResourcesKey key = mActiveResources.keyAt(i);
258add005cf94dcc815d29b54588c76fd87929075b3Dianne Hackborn            Resources r = mActiveResources.valueAt(i).get();
25988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            if (r != null) {
26088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Changing resources "
26188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                        + r + " config to: " + config);
262add005cf94dcc815d29b54588c76fd87929075b3Dianne Hackborn                int displayId = key.mDisplayId;
26388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
26488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                DisplayMetrics dm = defaultDisplayMetrics;
265add005cf94dcc815d29b54588c76fd87929075b3Dianne Hackborn                final boolean hasOverrideConfiguration = key.hasOverrideConfiguration();
26688c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                if (!isDefaultDisplay || hasOverrideConfiguration) {
26788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                    if (tmpConfig == null) {
26888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                        tmpConfig = new Configuration();
26988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                    }
27088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                    tmpConfig.setTo(config);
27188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                    if (!isDefaultDisplay) {
27288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                        dm = getDisplayMetricsLocked(displayId);
27388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                        applyNonDefaultDisplayMetricsToConfigurationLocked(dm, tmpConfig);
27488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                    }
27588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                    if (hasOverrideConfiguration) {
276add005cf94dcc815d29b54588c76fd87929075b3Dianne Hackborn                        tmpConfig.updateFrom(key.mOverrideConfiguration);
27788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                    }
27888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                    r.updateConfiguration(tmpConfig, dm, compat);
27988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                } else {
28088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                    r.updateConfiguration(config, dm, compat);
28188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                }
28288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                //Slog.i(TAG, "Updated app resources " + v.getKey()
28388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                //        + " " + r + ": " + r.getConfiguration());
28488c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            } else {
28588c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner                //Slog.i(TAG, "Removing old resources " + v.getKey());
286add005cf94dcc815d29b54588c76fd87929075b3Dianne Hackborn                mActiveResources.removeAt(i);
28788c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner            }
28888c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        }
28988c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
29088c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner        return changes != 0;
29188c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner    }
29288c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner
29388c0589969b17e66559cd2f132094cdaa0ee351dCraig Mautner}
294