From 6a3f83e78694c3c11cb7ee56ca2dcceae017a646 Mon Sep 17 00:00:00 2001 From: Pierre Barbier de Reuille Date: Wed, 12 May 2021 21:53:06 +0100 Subject: [PATCH] Check colors actually change for App Widget If new colors are set but do not change, do not re-inflate the App Widget. Bug: 187852819 Test: Added logs and added a widget, moved it to see Change-Id: I672ee7984cab8966f79d839494ac8a7b91679102 --- .../android/appwidget/AppWidgetHostView.java | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java index 152de4496cac2..2ed44ec648fb2 100644 --- a/core/java/android/appwidget/AppWidgetHostView.java +++ b/core/java/android/appwidget/AppWidgetHostView.java @@ -78,6 +78,10 @@ public class AppWidgetHostView extends FrameLayout { static final int VIEW_MODE_ERROR = 2; static final int VIEW_MODE_DEFAULT = 3; + // Set of valid colors resources. + private static final int FIRST_RESOURCE_COLOR_ID = android.R.color.system_neutral1_0; + private static final int LAST_RESOURCE_COLOR_ID = android.R.color.system_accent3_1000; + // When we're inflating the initialLayout for a AppWidget, we only allow // views that are allowed in RemoteViews. private static final LayoutInflater.Filter INFLATER_FILTER = @@ -97,6 +101,7 @@ public class AppWidgetHostView extends FrameLayout { private boolean mOnLightBackground; private SizeF mCurrentSize = null; private RemoteViews.ColorResources mColorResources = null; + private SparseIntArray mColorMapping = null; // Stores the last remote views last inflated. private RemoteViews mLastInflatedRemoteViews = null; private long mLastInflatedRemoteViewsId = -1; @@ -888,12 +893,29 @@ public class AppWidgetHostView extends FrameLayout { * {@link android.R.color#system_neutral1_500}. */ public void setColorResources(@NonNull SparseIntArray colorMapping) { - mColorResources = RemoteViews.ColorResources.create(mContext, colorMapping); + if (mColorMapping != null && isSameColorMapping(mColorMapping, colorMapping)) { + return; + } + mColorMapping = colorMapping.clone(); + mColorResources = RemoteViews.ColorResources.create(mContext, mColorMapping); mLayoutId = -1; mViewMode = VIEW_MODE_NOINIT; reapplyLastRemoteViews(); } + /** Check if, in the current context, the two color mappings are equivalent. */ + private boolean isSameColorMapping(SparseIntArray oldColors, SparseIntArray newColors) { + if (oldColors.size() != newColors.size()) { + return false; + } + for (int i = 0; i < oldColors.size(); i++) { + if (oldColors.valueAt(i) != newColors.get(oldColors.keyAt(i))) { + return false; + } + } + return true; + } + /** * Reset the dynamically overloaded resources, reverting to the default values for * all the colors. @@ -904,6 +926,7 @@ public class AppWidgetHostView extends FrameLayout { public void resetColorResources() { if (mColorResources != null) { mColorResources = null; + mColorMapping = null; mLayoutId = -1; mViewMode = VIEW_MODE_NOINIT; reapplyLastRemoteViews();