From 4f05d8d76beef330339dea55170eddb86c58b03c Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Wed, 9 Nov 2016 17:05:06 -0800 Subject: [PATCH] Preventing widgets from exceeding Bitmap memory limit > Moving the size check to a comman place so that it is executed in all related code > Fixing size calculation when views are merged as a result of partial update Test: Manually tested with a dummy app Bug: 31790171 Change-Id: Id0ea776796f156455d2cba31c8392d4875116949 (cherry picked from commit 349b412b4ba93e6ab835e3f0c45a998979339b4f) --- core/java/android/widget/RemoteViews.java | 21 ++----------------- .../appwidget/AppWidgetServiceImpl.java | 17 ++++++++------- 2 files changed, 11 insertions(+), 27 deletions(-) diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index d0d233ebe975e..7cc539cba2fc3 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -390,6 +390,7 @@ public class RemoteViews implements Parcelable, Filter { // Because pruning can remove the need for bitmaps, we reconstruct the bitmap cache mBitmapCache = new BitmapCache(); setBitmapCache(mBitmapCache); + recalculateMemoryUsage(); } private class SetEmptyView extends Action { @@ -2057,26 +2058,8 @@ public class RemoteViews implements Parcelable, Filter { return mMemoryUsage; } - @SuppressWarnings("deprecation") public void addBitmapMemory(Bitmap b) { - final Bitmap.Config c = b.getConfig(); - // If we don't know, be pessimistic and assume 4 - int bpp = 4; - if (c != null) { - switch (c) { - case ALPHA_8: - bpp = 1; - break; - case RGB_565: - case ARGB_4444: - bpp = 2; - break; - case ARGB_8888: - bpp = 4; - break; - } - } - increment(b.getWidth() * b.getHeight() * bpp); + increment(b.getAllocationByteCount()); } int mMemoryUsage; diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java index b5fcb5cb6a3b9..f5e50c61d4599 100644 --- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java +++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java @@ -1590,14 +1590,6 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku // Make sure the package runs under the caller uid. mSecurityPolicy.enforceCallFromPackage(callingPackage); - - final int bitmapMemoryUsage = (views != null) ? views.estimateMemoryUsage() : 0; - if (bitmapMemoryUsage > mMaxWidgetBitmapMemory) { - throw new IllegalArgumentException("RemoteViews for widget update exceeds" - + " maximum bitmap memory usage (used: " + bitmapMemoryUsage - + ", max: " + mMaxWidgetBitmapMemory + ")"); - } - synchronized (mLock) { ensureGroupStateLoadedLocked(userId); @@ -1809,6 +1801,15 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku // For a full update we replace the RemoteViews completely. widget.views = views; } + int memoryUsage; + if ((UserHandle.getAppId(Binder.getCallingUid()) != Process.SYSTEM_UID) && + (widget.views != null) && + ((memoryUsage = widget.views.estimateMemoryUsage()) > mMaxWidgetBitmapMemory)) { + widget.views = null; + throw new IllegalArgumentException("RemoteViews for widget update exceeds" + + " maximum bitmap memory usage (used: " + memoryUsage + + ", max: " + mMaxWidgetBitmapMemory + ")"); + } scheduleNotifyUpdateAppWidgetLocked(widget, widget.getEffectiveViewsLocked()); } }