Skip to content

Commit e0bb6fe

Browse files
Adam CohenAndroid (Google) Code Review
authored andcommitted
Merge "Cap widget bitmap usage by screen size (issue 6464700)" into jb-dev
2 parents c5fb580 + 311c79c commit e0bb6fe

File tree

3 files changed

+29
-1
lines changed

3 files changed

+29
-1
lines changed

core/java/android/appwidget/AppWidgetManager.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,10 @@ private AppWidgetManager(Context context) {
320320
* It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast,
321321
* and outside of the handler.
322322
* This method will only work when called from the uid that owns the AppWidget provider.
323+
*
324+
* <p>
325+
* The total Bitmap memory used by the RemoteViews object cannot exceed that required to
326+
* fill the screen once, ie. (screen width x screen height x 4) bytes.
323327
*
324328
* @param appWidgetIds The AppWidget instances for which to set the RemoteViews.
325329
* @param views The RemoteViews object to show.
@@ -385,6 +389,10 @@ public Bundle getAppWidgetOptions(int appWidgetId) {
385389
* and outside of the handler.
386390
* This method will only work when called from the uid that owns the AppWidget provider.
387391
*
392+
* <p>
393+
* The total Bitmap memory used by the RemoteViews object cannot exceed that required to
394+
* fill the screen once, ie. (screen width x screen height x 4) bytes.
395+
*
388396
* @param appWidgetId The AppWidget instance for which to set the RemoteViews.
389397
* @param views The RemoteViews object to show.
390398
*/

core/java/android/widget/RemoteViews.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1445,7 +1445,8 @@ private void setBitmapCache(BitmapCache bitmapCache) {
14451445
/**
14461446
* Returns an estimate of the bitmap heap memory usage for this RemoteViews.
14471447
*/
1448-
int estimateMemoryUsage() {
1448+
/** @hide */
1449+
public int estimateMemoryUsage() {
14491450
return mMemoryUsageCounter.getMemoryUsage();
14501451
}
14511452

services/java/com/android/server/AppWidgetServiceImpl.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import android.util.Slog;
5050
import android.util.TypedValue;
5151
import android.util.Xml;
52+
import android.view.WindowManager;
5253
import android.widget.RemoteViews;
5354

5455
import com.android.internal.appwidget.IAppWidgetHost;
@@ -171,6 +172,7 @@ public void disconnect() {
171172
boolean mSafeMode;
172173
int mUserId;
173174
boolean mStateLoaded;
175+
int mMaxWidgetBitmapMemory;
174176

175177
// These are for debugging only -- widgets are going missing in some rare instances
176178
ArrayList<Provider> mDeletedProviders = new ArrayList<Provider>();
@@ -181,6 +183,14 @@ public void disconnect() {
181183
mPm = AppGlobals.getPackageManager();
182184
mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
183185
mUserId = userId;
186+
computeMaximumWidgetBitmapMemory();
187+
}
188+
189+
void computeMaximumWidgetBitmapMemory() {
190+
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
191+
int height = wm.getDefaultDisplay().getRawHeight();
192+
int width = wm.getDefaultDisplay().getRawWidth();
193+
mMaxWidgetBitmapMemory = 4 * width * height;
184194
}
185195

186196
public void systemReady(boolean safeMode) {
@@ -806,6 +816,15 @@ public void updateAppWidgetIds(int[] appWidgetIds, RemoteViews views) {
806816
if (appWidgetIds == null) {
807817
return;
808818
}
819+
820+
int bitmapMemoryUsage = views.estimateMemoryUsage();
821+
if (bitmapMemoryUsage > mMaxWidgetBitmapMemory) {
822+
throw new IllegalArgumentException("RemoteViews for widget update exceeds maximum" +
823+
" bitmap memory usage (used: " + bitmapMemoryUsage + ", max: " +
824+
mMaxWidgetBitmapMemory + ") The total memory cannot exceed that required to" +
825+
" fill the device's screen once.");
826+
}
827+
809828
if (appWidgetIds.length == 0) {
810829
return;
811830
}

0 commit comments

Comments
 (0)