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 349b412b4b)
This commit is contained in:
Sunny Goyal
2016-11-09 17:05:06 -08:00
parent 96d4aadb4c
commit 4f05d8d76b
2 changed files with 11 additions and 27 deletions

View File

@@ -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;

View File

@@ -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());
}
}