Merge "Enabling RemoteViews to have a landscape and portrait layout" into jb-dev
diff --git a/api/current.txt b/api/current.txt
index 2e49bc5..882503d 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -27842,6 +27842,7 @@
 
   public class RemoteViews implements android.view.LayoutInflater.Filter android.os.Parcelable {
     ctor public RemoteViews(java.lang.String, int);
+    ctor public RemoteViews(android.widget.RemoteViews, android.widget.RemoteViews);
     ctor public RemoteViews(android.os.Parcel);
     method public void addView(int, android.widget.RemoteViews);
     method public android.view.View apply(android.content.Context, android.view.ViewGroup);
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 214775a..57a3012 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -23,6 +23,7 @@
 import android.content.Intent;
 import android.content.IntentSender;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Configuration;
 import android.graphics.Bitmap;
 import android.graphics.PorterDuff;
 import android.graphics.Rect;
@@ -87,7 +88,32 @@
      */
     private MemoryUsageCounter mMemoryUsageCounter;
 
-    
+    /**
+     * Maps bitmaps to unique indicies to avoid Bitmap duplication.
+     */
+    private BitmapCache mBitmapCache;
+
+    /**
+     * Indicates whether or not this RemoteViews object is contained as a child of any other
+     * RemoteViews.
+     */
+    private boolean mIsRoot = true;
+
+    /**
+     * Constants to whether or not this RemoteViews is composed of a landscape and portrait
+     * RemoteViews.
+     */
+    private static final int MODE_NORMAL = 0;
+    private static final int MODE_HAS_LANDSCAPE_AND_PORTRAIT = 1;
+
+    /**
+     * Used in conjunction with the special constructor
+     * {@link #RemoteViews(RemoteViews, RemoteViews)} to keep track of the landscape and portrait
+     * RemoteViews.
+     */
+    private RemoteViews mLandscape = null;
+    private RemoteViews mPortrait = null;
+
     /**
      * This flag indicates whether this RemoteViews object is being created from a
      * RemoteViewsService for use as a child of a widget collection. This flag is used
@@ -163,6 +189,10 @@
             }
             return true;
         }
+
+        public void setBitmapCache(BitmapCache bitmapCache) {
+            // Do nothing
+        }
     }
 
     private class SetEmptyView extends Action {
@@ -643,6 +673,112 @@
         }
     }
 
+    private static class BitmapCache {
+        ArrayList<Bitmap> mBitmaps;
+
+        public BitmapCache() {
+            mBitmaps = new ArrayList<Bitmap>();
+        }
+
+        public BitmapCache(Parcel source) {
+            int count = source.readInt();
+            mBitmaps = new ArrayList<Bitmap>();
+            for (int i = 0; i < count; i++) {
+                Bitmap b = Bitmap.CREATOR.createFromParcel(source);
+                mBitmaps.add(b);
+            }
+        }
+
+        public int getBitmapId(Bitmap b) {
+            if (b == null) {
+                return -1;
+            } else {
+                if (mBitmaps.contains(b)) {
+                    return mBitmaps.indexOf(b);
+                } else {
+                    mBitmaps.add(b);
+                    return (mBitmaps.size() - 1);
+                }
+            }
+        }
+
+        public Bitmap getBitmapForId(int id) {
+            if (id == -1 || id >= mBitmaps.size()) {
+                return null;
+            } else {
+                return mBitmaps.get(id);
+            }
+        }
+
+        public void writeBitmapsToParcel(Parcel dest, int flags) {
+            int count = mBitmaps.size();
+            dest.writeInt(count);
+            for (int i = 0; i < count; i++) {
+                mBitmaps.get(i).writeToParcel(dest, flags);
+            }
+        }
+
+        public void assimilate(BitmapCache bitmapCache) {
+            ArrayList<Bitmap> bitmapsToBeAdded = bitmapCache.mBitmaps;
+            int count = bitmapsToBeAdded.size();
+            for (int i = 0; i < count; i++) {
+                Bitmap b = bitmapsToBeAdded.get(i);
+                if (!mBitmaps.contains(b)) {
+                    mBitmaps.add(b);
+                }
+            }
+        }
+
+        public void addBitmapMemory(MemoryUsageCounter memoryCounter) {
+            for (int i = 0; i < mBitmaps.size(); i++) {
+                memoryCounter.addBitmapMemory(mBitmaps.get(i));
+            }
+        }
+    }
+
+    private class BitmapReflectionAction extends Action {
+        int bitmapId;
+        int viewId;
+        Bitmap bitmap;
+        String methodName;
+
+        BitmapReflectionAction(int viewId, String methodName, Bitmap bitmap) {
+            this.bitmap = bitmap;
+            this.viewId = viewId;
+            this.methodName = methodName;
+            bitmapId = mBitmapCache.getBitmapId(bitmap);
+        }
+
+        BitmapReflectionAction(Parcel in) {
+            viewId = in.readInt();
+            methodName = in.readString();
+            bitmapId = in.readInt();
+            bitmap = mBitmapCache.getBitmapForId(bitmapId);
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeInt(TAG);
+            dest.writeInt(viewId);
+            dest.writeString(methodName);
+            dest.writeInt(bitmapId);
+        }
+
+        @Override
+        public void apply(View root, ViewGroup rootParent) throws ActionException {
+            ReflectionAction ra = new ReflectionAction(viewId, methodName, ReflectionAction.BITMAP,
+                    bitmap);
+            ra.apply(root, rootParent);
+        }
+
+        @Override
+        public void setBitmapCache(BitmapCache bitmapCache) {
+            bitmapId = bitmapCache.getBitmapId(bitmap);
+        }
+
+        public final static int TAG = 12;
+    }
+
     /**
      * Base class for the reflection actions.
      */
@@ -894,24 +1030,7 @@
                 case BITMAP:
                     if (this.value != null) {
                         final Bitmap b = (Bitmap) this.value;
-                        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;
-                            }
-                        }
-                        counter.bitmapIncrement(b.getWidth() * b.getHeight() * bpp);
+                        counter.addBitmapMemory(b);
                     }
                     break;
                 default:
@@ -920,6 +1039,16 @@
         }
     }
 
+    private void configureRemoteViewsAsChild(RemoteViews rv) {
+        mBitmapCache.assimilate(rv.mBitmapCache);
+        rv.setBitmapCache(mBitmapCache);
+        rv.setNotRoot();
+    }
+
+    void setNotRoot() {
+        mIsRoot = false;
+    }
+
     /**
      * Equivalent to calling {@link ViewGroup#addView(View)} after inflating the
      * given {@link RemoteViews}, or calling {@link ViewGroup#removeAllViews()}
@@ -929,17 +1058,29 @@
         public ViewGroupAction(int viewId, RemoteViews nestedViews) {
             this.viewId = viewId;
             this.nestedViews = nestedViews;
+            configureRemoteViewsAsChild(nestedViews);
         }
 
-        public ViewGroupAction(Parcel parcel) {
+        public ViewGroupAction(Parcel parcel, BitmapCache bitmapCache) {
             viewId = parcel.readInt();
-            nestedViews = parcel.readParcelable(null);
+            boolean nestedViewsNull = parcel.readInt() == 0;
+            if (!nestedViewsNull) {
+                nestedViews = new RemoteViews(parcel, bitmapCache);
+            } else {
+                nestedViews = null;
+            }
         }
 
         public void writeToParcel(Parcel dest, int flags) {
             dest.writeInt(TAG);
             dest.writeInt(viewId);
-            dest.writeParcelable(nestedViews, 0 /* no flags */);
+            if (nestedViews != null) {
+                dest.writeInt(1);
+                nestedViews.writeToParcel(dest, flags);
+            } else {
+                // signifies null
+                dest.writeInt(0);
+            }
         }
 
         @Override
@@ -959,7 +1100,14 @@
         @Override
         public void updateMemoryUsageEstimate(MemoryUsageCounter counter) {
             if (nestedViews != null) {
-                counter.bitmapIncrement(nestedViews.estimateBitmapMemoryUsage());
+                counter.increment(nestedViews.estimateMemoryUsage());
+            }
+        }
+
+        @Override
+        public void setBitmapCache(BitmapCache bitmapCache) {
+            if (nestedViews != null) {
+                nestedViews.setBitmapCache(bitmapCache);
             }
         }
 
@@ -1027,18 +1175,39 @@
      */
     private class MemoryUsageCounter {
         public void clear() {
-            mBitmapHeapMemoryUsage = 0;
+            mMemoryUsage = 0;
         }
 
-        public void bitmapIncrement(int numBytes) {
-            mBitmapHeapMemoryUsage += numBytes;
+        public void increment(int numBytes) {
+            mMemoryUsage += numBytes;
         }
 
-        public int getBitmapHeapMemoryUsage() {
-            return mBitmapHeapMemoryUsage;
+        public int getMemoryUsage() {
+            return mMemoryUsage;
         }
 
-        int mBitmapHeapMemoryUsage;
+        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);
+        }
+
+        int mMemoryUsage;
     }
 
     /**
@@ -1051,62 +1220,122 @@
     public RemoteViews(String packageName, int layoutId) {
         mPackage = packageName;
         mLayoutId = layoutId;
+        mBitmapCache = new BitmapCache();
 
         // setup the memory usage statistics
         mMemoryUsageCounter = new MemoryUsageCounter();
         recalculateMemoryUsage();
     }
 
+    private boolean hasLandscapeAndPortraitLayouts() {
+        return (mLandscape != null) && (mPortrait != null);
+    }
+
+     /**
+     * Create a new RemoteViews object that will inflate as the specified
+     * landspace or portrait RemoteViews, depending on the current configuration.
+     *
+     * @param landscape The RemoteViews to inflate in landscape configuration
+     * @param portrait The RemoteViews to inflate in portrait configuration
+     */
+    public RemoteViews(RemoteViews landscape, RemoteViews portrait) {
+        if (landscape == null || portrait == null) {
+            throw new RuntimeException("Both RemoteViews must be non-null");
+        }
+        if (landscape.getPackage().compareTo(portrait.getPackage()) != 0) {
+            throw new RuntimeException("Both RemoteViews must share the same package");
+        }
+        mPackage = portrait.getPackage();
+        mLayoutId = portrait.getLayoutId();
+
+        mLandscape = landscape;
+        mPortrait = portrait;
+
+        // setup the memory usage statistics
+        mMemoryUsageCounter = new MemoryUsageCounter();
+
+        mBitmapCache = new BitmapCache();
+        configureRemoteViewsAsChild(landscape);
+        configureRemoteViewsAsChild(portrait);
+
+        recalculateMemoryUsage();
+    }
+
     /**
      * Reads a RemoteViews object from a parcel.
      * 
      * @param parcel
      */
     public RemoteViews(Parcel parcel) {
-        mPackage = parcel.readString();
-        mLayoutId = parcel.readInt();
-        mIsWidgetCollectionChild = parcel.readInt() == 1 ? true : false;
+        this(parcel, null);
+    }
 
-        int count = parcel.readInt();
-        if (count > 0) {
-            mActions = new ArrayList<Action>(count);
-            for (int i=0; i<count; i++) {
-                int tag = parcel.readInt();
-                switch (tag) {
-                case SetOnClickPendingIntent.TAG:
-                    mActions.add(new SetOnClickPendingIntent(parcel));
-                    break;
-                case SetDrawableParameters.TAG:
-                    mActions.add(new SetDrawableParameters(parcel));
-                    break;
-                case ReflectionAction.TAG:
-                    mActions.add(new ReflectionAction(parcel));
-                    break;
-                case ViewGroupAction.TAG:
-                    mActions.add(new ViewGroupAction(parcel));
-                    break;
-                case ReflectionActionWithoutParams.TAG:
-                    mActions.add(new ReflectionActionWithoutParams(parcel));
-                    break;
-                case SetEmptyView.TAG:
-                    mActions.add(new SetEmptyView(parcel));
-                    break;
-                case SetPendingIntentTemplate.TAG:
-                    mActions.add(new SetPendingIntentTemplate(parcel));
-                    break;
-                case SetOnClickFillInIntent.TAG:
-                    mActions.add(new SetOnClickFillInIntent(parcel));
-                    break;
-                case SetRemoteViewsAdapterIntent.TAG:
-                    mActions.add(new SetRemoteViewsAdapterIntent(parcel));
-                    break;
-                case TextViewDrawableAction.TAG:
-                    mActions.add(new TextViewDrawableAction(parcel));
-                    break;
-                default:
-                    throw new ActionException("Tag " + tag + " not found");
+    private RemoteViews(Parcel parcel, BitmapCache bitmapCache) {
+        int mode = parcel.readInt();
+
+        // We only store a bitmap cache in the root of the RemoteViews.
+        if (bitmapCache == null) {
+            mBitmapCache = new BitmapCache(parcel);
+        } else {
+            setBitmapCache(bitmapCache);
+            setNotRoot();
+        }
+
+        if (mode == MODE_NORMAL) {
+            mPackage = parcel.readString();
+            mLayoutId = parcel.readInt();
+            mIsWidgetCollectionChild = parcel.readInt() == 1 ? true : false;
+
+            int count = parcel.readInt();
+            if (count > 0) {
+                mActions = new ArrayList<Action>(count);
+                for (int i=0; i<count; i++) {
+                    int tag = parcel.readInt();
+                    switch (tag) {
+                    case SetOnClickPendingIntent.TAG:
+                        mActions.add(new SetOnClickPendingIntent(parcel));
+                        break;
+                    case SetDrawableParameters.TAG:
+                        mActions.add(new SetDrawableParameters(parcel));
+                        break;
+                    case ReflectionAction.TAG:
+                        mActions.add(new ReflectionAction(parcel));
+                        break;
+                    case ViewGroupAction.TAG:
+                        mActions.add(new ViewGroupAction(parcel, mBitmapCache));
+                        break;
+                    case ReflectionActionWithoutParams.TAG:
+                        mActions.add(new ReflectionActionWithoutParams(parcel));
+                        break;
+                    case SetEmptyView.TAG:
+                        mActions.add(new SetEmptyView(parcel));
+                        break;
+                    case SetPendingIntentTemplate.TAG:
+                        mActions.add(new SetPendingIntentTemplate(parcel));
+                        break;
+                    case SetOnClickFillInIntent.TAG:
+                        mActions.add(new SetOnClickFillInIntent(parcel));
+                        break;
+                    case SetRemoteViewsAdapterIntent.TAG:
+                        mActions.add(new SetRemoteViewsAdapterIntent(parcel));
+                        break;
+                    case TextViewDrawableAction.TAG:
+                        mActions.add(new TextViewDrawableAction(parcel));
+                        break;
+                    case BitmapReflectionAction.TAG:
+                        mActions.add(new BitmapReflectionAction(parcel));
+                        break;
+                    default:
+                        throw new ActionException("Tag " + tag + " not found");
+                    }
                 }
             }
+        } else {
+            // MODE_HAS_LANDSCAPE_AND_PORTRAIT
+            mLandscape = new RemoteViews(parcel, mBitmapCache);
+            mPortrait = new RemoteViews(parcel, mBitmapCache);
+            mPackage = mPortrait.getPackage();
+            mLayoutId = mPortrait.getLayoutId();
         }
 
         // setup the memory usage statistics
@@ -1116,11 +1345,18 @@
 
     @Override
     public RemoteViews clone() {
-        final RemoteViews that = new RemoteViews(mPackage, mLayoutId);
-        if (mActions != null) {
-            that.mActions = (ArrayList<Action>)mActions.clone();
-        }
+        RemoteViews that;
+        if (!hasLandscapeAndPortraitLayouts()) {
+            that = new RemoteViews(mPackage, mLayoutId);
 
+            if (mActions != null) {
+                that.mActions = (ArrayList<Action>)mActions.clone();
+            }
+        } else {
+            RemoteViews land = mLandscape.clone();
+            RemoteViews port = mPortrait.clone();
+            that = new RemoteViews(land, port);
+        }
         // update the memory usage stats of the cloned RemoteViews
         that.recalculateMemoryUsage();
         return that;
@@ -1130,6 +1366,13 @@
         return mPackage;
     }
 
+    /**
+     * Reutrns the layout id of the root layout associated with this RemoteViews. In the case
+     * that the RemoteViews has both a landscape and portrait root, this will return the layout
+     * id associated with the portrait layout.
+     *
+     * @return the layout id.
+     */
     public int getLayoutId() {
         return mLayoutId;
     }
@@ -1151,20 +1394,47 @@
     private void recalculateMemoryUsage() {
         mMemoryUsageCounter.clear();
 
-        // Accumulate the memory usage for each action
-        if (mActions != null) {
-            final int count = mActions.size();
-            for (int i= 0; i < count; ++i) {
-                mActions.get(i).updateMemoryUsageEstimate(mMemoryUsageCounter);
+        if (!hasLandscapeAndPortraitLayouts()) {
+            // Accumulate the memory usage for each action
+            if (mActions != null) {
+                final int count = mActions.size();
+                for (int i= 0; i < count; ++i) {
+                    mActions.get(i).updateMemoryUsageEstimate(mMemoryUsageCounter);
+                }
             }
+            if (mIsRoot) {
+                mBitmapCache.addBitmapMemory(mMemoryUsageCounter);
+            }
+        } else {
+            mMemoryUsageCounter.increment(mLandscape.estimateMemoryUsage());
+            mMemoryUsageCounter.increment(mPortrait.estimateMemoryUsage());
+            mBitmapCache.addBitmapMemory(mMemoryUsageCounter);
+        }
+    }
+
+    /**
+     * Recursively sets BitmapCache in the hierarchy and update the bitmap ids.
+     */
+    private void setBitmapCache(BitmapCache bitmapCache) {
+        mBitmapCache = bitmapCache;
+        if (!hasLandscapeAndPortraitLayouts()) {
+            if (mActions != null) {
+                final int count = mActions.size();
+                for (int i= 0; i < count; ++i) {
+                    mActions.get(i).setBitmapCache(bitmapCache);
+                }
+            }
+        } else {
+            mLandscape.setBitmapCache(bitmapCache);
+            mPortrait.setBitmapCache(bitmapCache);
         }
     }
 
     /**
      * Returns an estimate of the bitmap heap memory usage for this RemoteViews.
      */
-    int estimateBitmapMemoryUsage() {
-        return mMemoryUsageCounter.getBitmapHeapMemoryUsage();
+    int estimateMemoryUsage() {
+        return mMemoryUsageCounter.getMemoryUsage();
     }
 
     /**
@@ -1173,6 +1443,11 @@
      * @param a The action to add
      */
     private void addAction(Action a) {
+        if (hasLandscapeAndPortraitLayouts()) {
+            throw new RuntimeException("RemoteViews specifying separate landscape and portrait" +
+                    " layouts cannot be modified. Instead, fully configure the landscape and" +
+                    " portrait layouts individually before constructing the combined layout.");
+        }
         if (mActions == null) {
             mActions = new ArrayList<Action>();
         }
@@ -1644,7 +1919,7 @@
      * @param value The value to pass to the method.
      */
     public void setBitmap(int viewId, String methodName, Bitmap value) {
-        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.BITMAP, value));
+        addAction(new BitmapReflectionAction(viewId, methodName, value));
     }
 
     /**
@@ -1679,6 +1954,18 @@
         setCharSequence(viewId, "setContentDescription", contentDescription);
     }
 
+    private RemoteViews getRemoteViewsToApply(Context context) {
+        if (hasLandscapeAndPortraitLayouts()) {
+            int orientation = context.getResources().getConfiguration().orientation;
+            if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
+                return mLandscape;
+            } else {
+                return mPortrait;
+            }
+        }
+        return this;
+    }
+
     /**
      * Inflates the view hierarchy represented by this object and applies
      * all of the actions.
@@ -1691,6 +1978,8 @@
      * @return The inflated view hierarchy
      */
     public View apply(Context context, ViewGroup parent) {
+        RemoteViews rvToApply = getRemoteViewsToApply(context);
+
         View result;
 
         Context c = prepareContext(context);
@@ -1701,13 +1990,13 @@
         inflater = inflater.cloneInContext(c);
         inflater.setFilter(this);
 
-        result = inflater.inflate(mLayoutId, parent, false);
+        result = inflater.inflate(rvToApply.getLayoutId(), parent, false);
 
-        performApply(result, parent);
+        rvToApply.performApply(result, parent);
 
         return result;
     }
-    
+
     /**
      * Applies all of the actions to the provided view.
      *
@@ -1717,8 +2006,20 @@
      * the {@link #apply(Context,ViewGroup)} call.
      */
     public void reapply(Context context, View v) {
+        RemoteViews rvToApply = getRemoteViewsToApply(context);
+
+        // In the case that a view has this RemoteViews applied in one orientation, is persisted
+        // across orientation change, and has the RemoteViews re-applied in the new orientation,
+        // we throw an exception, since the layouts may be completely unrelated.
+        if (hasLandscapeAndPortraitLayouts()) {
+            if (v.getId() != rvToApply.getLayoutId()) {
+                throw new RuntimeException("Attempting to re-apply RemoteViews to a view that" +
+                        " that does not share the same root layout id.");
+            }
+        }
+
         prepareContext(context);
-        performApply(v, (ViewGroup) v.getParent());
+        rvToApply.performApply(v, (ViewGroup) v.getParent());
     }
 
     private void performApply(View v, ViewGroup parent) {
@@ -1757,25 +2058,42 @@
     public boolean onLoadClass(Class clazz) {
         return clazz.isAnnotationPresent(RemoteView.class);
     }
-    
+
     public int describeContents() {
         return 0;
     }
 
     public void writeToParcel(Parcel dest, int flags) {
-        dest.writeString(mPackage);
-        dest.writeInt(mLayoutId);
-        dest.writeInt(mIsWidgetCollectionChild ? 1 : 0);
-        int count;
-        if (mActions != null) {
-            count = mActions.size();
+        if (!hasLandscapeAndPortraitLayouts()) {
+            dest.writeInt(MODE_NORMAL);
+            // We only write the bitmap cache if we are the root RemoteViews, as this cache
+            // is shared by all children.
+            if (mIsRoot) {
+                mBitmapCache.writeBitmapsToParcel(dest, flags);
+            }
+            dest.writeString(mPackage);
+            dest.writeInt(mLayoutId);
+            dest.writeInt(mIsWidgetCollectionChild ? 1 : 0);
+            int count;
+            if (mActions != null) {
+                count = mActions.size();
+            } else {
+                count = 0;
+            }
+            dest.writeInt(count);
+            for (int i=0; i<count; i++) {
+                Action a = mActions.get(i);
+                a.writeToParcel(dest, 0);
+            }
         } else {
-            count = 0;
-        }
-        dest.writeInt(count);
-        for (int i=0; i<count; i++) {
-            Action a = mActions.get(i);
-            a.writeToParcel(dest, 0);
+            dest.writeInt(MODE_HAS_LANDSCAPE_AND_PORTRAIT);
+            // We only write the bitmap cache if we are the root RemoteViews, as this cache
+            // is shared by all children.
+            if (mIsRoot) {
+                mBitmapCache.writeBitmapsToParcel(dest, flags);
+            }
+            mLandscape.writeToParcel(dest, flags);
+            mPortrait.writeToParcel(dest, flags);
         }
     }
 
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index 8067435..f266d50 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -595,7 +595,7 @@
             for (Integer i : mIndexRemoteViews.keySet()) {
                 final RemoteViews v = mIndexRemoteViews.get(i);
                 if (v != null) {
-                    mem += v.estimateBitmapMemoryUsage();
+                    mem += v.estimateMemoryUsage();
                 }
             }
             return mem;
@@ -942,10 +942,6 @@
      * which  wouldn't otherwise be possible.
      */
     public void setVisibleRangeHint(int lowerBound, int upperBound) {
-        if (lowerBound < 0 || upperBound < 0) {
-            throw new RuntimeException("Attempted to set invalid range: lowerBound="+lowerBound +
-                    "," + "upperBound="+upperBound);
-        }
         mVisibleWindowLowerBound = lowerBound;
         mVisibleWindowUpperBound = upperBound;
     }