From 758e88bd44d32d3c77cff4d6d1c06435a5376806 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Thu, 6 Jun 2019 16:26:38 -0700 Subject: [PATCH] Resetting widget cache when some configurations change Sometimes widget providers hardcode colors in their remoteViews by loading them from resources. On UI mode change, this can lead to inconsistent UI if some widgets use a different configuration than others. Test: Verified with calendar widget on device Bug: 133064045 Change-Id: If47a6b1973f55b7590f5d4116813d6a332951697 --- .../android/widget/RemoteViewsAdapter.java | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java index 365638f5a96a0..efc5eb373e007 100644 --- a/core/java/android/widget/RemoteViewsAdapter.java +++ b/core/java/android/widget/RemoteViewsAdapter.java @@ -28,7 +28,9 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; +import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; +import android.content.res.Configuration; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; @@ -554,6 +556,12 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback } } + /** + * Config diff flags for which the cache should be reset + */ + private static final int CACHE_RESET_CONFIG_FLAGS = ActivityInfo.CONFIG_FONT_SCALE + | ActivityInfo.CONFIG_UI_MODE | ActivityInfo.CONFIG_DENSITY + | ActivityInfo.CONFIG_ASSETS_PATHS; /** * */ @@ -587,7 +595,6 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback // farthest items from when we hit the memory limit private int mLastRequestedIndex; - // The lower and upper bounds of the preloaded range private int mPreloadLowerBound; private int mPreloadUpperBound; @@ -602,12 +609,17 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback private static final float sMaxCountSlackPercent = 0.75f; private static final int sMaxMemoryLimitInBytes = 2 * 1024 * 1024; - public FixedSizeRemoteViewsCache(int maxCacheSize) { + // Configuration for which the cache was created + private final Configuration mConfiguration; + + FixedSizeRemoteViewsCache(int maxCacheSize, Configuration configuration) { mMaxCount = maxCacheSize; mMaxCountSlack = Math.round(sMaxCountSlackPercent * (mMaxCount / 2)); mPreloadLowerBound = 0; mPreloadUpperBound = -1; mLastRequestedIndex = -1; + + mConfiguration = new Configuration(configuration); } public void insert(int position, RemoteViews v, long itemId, int[] visibleWindow) { @@ -852,7 +864,12 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback mAppWidgetId); synchronized(sCachedRemoteViewsCaches) { - if (sCachedRemoteViewsCaches.containsKey(key)) { + FixedSizeRemoteViewsCache cache = sCachedRemoteViewsCaches.get(key); + Configuration config = context.getResources().getConfiguration(); + if (cache == null + || (cache.mConfiguration.diff(config) & CACHE_RESET_CONFIG_FLAGS) != 0) { + mCache = new FixedSizeRemoteViewsCache(DEFAULT_CACHE_SIZE, config); + } else { mCache = sCachedRemoteViewsCaches.get(key); synchronized (mCache.mMetaData) { if (mCache.mMetaData.count > 0) { @@ -861,8 +878,6 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback mDataReady = true; } } - } else { - mCache = new FixedSizeRemoteViewsCache(DEFAULT_CACHE_SIZE); } if (!mDataReady) { requestBindService();