Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 11a6450e authored by Adam Cohen's avatar Adam Cohen Committed by Android (Google) Code Review
Browse files

Merge "Fixing partiallyUpdateAppWidget to cache the new changes" into jb-mr1-dev

parents 957fadc5 fbe44b7d
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -436,10 +436,9 @@ public class AppWidgetManager {
     *
     * This update  differs from {@link #updateAppWidget(int[], RemoteViews)} in that the
     * RemoteViews object which is passed is understood to be an incomplete representation of the 
     * widget, and hence is not cached by the AppWidgetService. Note that because these updates are 
     * not cached, any state that they modify that is not restored by restoreInstanceState will not
     * persist in the case that the widgets are restored using the cached version in
     * AppWidgetService.
     * widget, and hence does not replace the cached representation of the widget. As of API
     * level 17, the new properties set within the views objects will be appended to the cached
     * representation of the widget, and hence will persist.
     *
     * Use with {@link RemoteViews#showNext(int)}, {@link RemoteViews#showPrevious(int)},
     * {@link RemoteViews#setScrollPosition(int, int)} and similar commands.
+134 −24
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;


/**
@@ -187,6 +188,10 @@ public class RemoteViews implements Parcelable, Filter {
        public abstract void apply(View root, ViewGroup rootParent,
                OnClickHandler handler) throws ActionException;

        public static final int MERGE_REPLACE = 0;
        public static final int MERGE_APPEND = 1;
        public static final int MERGE_IGNORE = 2;

        public int describeContents() {
            return 0;
        }
@@ -203,6 +208,60 @@ public class RemoteViews implements Parcelable, Filter {
        public void setBitmapCache(BitmapCache bitmapCache) {
            // Do nothing
        }

        public int mergeBehavior() {
            return MERGE_REPLACE;
        }

        public abstract String getActionName();

        public String getUniqueKey() {
            return (getActionName() + viewId);
        }

        int viewId;
    }

    public void mergeRemoteViews(RemoteViews newRv) {
        // We first copy the new RemoteViews, as the process of merging modifies the way the actions
        // reference the bitmap cache. We don't want to modify the object as it may need to
        // be merged and applied multiple times.
        Parcel p = Parcel.obtain();
        newRv.writeToParcel(p, 0);
        RemoteViews copy = new RemoteViews(p);

        HashMap<String, Action> map = new HashMap<String, Action>();
        if (mActions == null) {
            mActions = new ArrayList<Action>();
        }

        int count = mActions.size();
        for (int i = 0; i < count; i++) {
            Action a = mActions.get(i);
            map.put(a.getUniqueKey(), a);
        }

        ArrayList<Action> newActions = copy.mActions;
        if (newActions == null) return;
        count = newActions.size();
        for (int i = 0; i < count; i++) {
            Action a = newActions.get(i);
            String key = newActions.get(i).getUniqueKey();
            int mergeBehavior = map.get(key).mergeBehavior();
            if (map.containsKey(key) && mergeBehavior == Action.MERGE_REPLACE) {
                mActions.remove(map.get(key));
                map.remove(key);
            }

            // If the merge behavior is ignore, we don't bother keeping the extra action
            if (mergeBehavior == Action.MERGE_REPLACE || mergeBehavior == Action.MERGE_APPEND) {
                mActions.add(a);
            }
        }

        // Because pruning can remove the need for bitmaps, we reconstruct the bitmap cache
        mBitmapCache = new BitmapCache();
        setBitmapCache(mBitmapCache);
    }

    private class SetEmptyView extends Action {
@@ -239,6 +298,10 @@ public class RemoteViews implements Parcelable, Filter {

            adapterView.setEmptyView(emptyView);
        }

        public String getActionName() {
            return "SetEmptyView";
        }
    }

    private class SetOnClickFillInIntent extends Action {
@@ -316,7 +379,10 @@ public class RemoteViews implements Parcelable, Filter {
            }
        }

        int viewId;
        public String getActionName() {
            return "SetOnClickFillInIntent";
        }

        Intent fillInIntent;

        public final static int TAG = 9;
@@ -399,7 +465,10 @@ public class RemoteViews implements Parcelable, Filter {
            }
        }

        int viewId;
        public String getActionName() {
            return "SetPendingIntentTemplate";
        }

        PendingIntent pendingIntentTemplate;

        public final static int TAG = 8;
@@ -453,7 +522,10 @@ public class RemoteViews implements Parcelable, Filter {
            }
        }

        int viewId;
        public String getActionName() {
            return "SetRemoteViewsAdapterIntent";
        }

        Intent intent;

        public final static int TAG = 10;
@@ -539,7 +611,10 @@ public class RemoteViews implements Parcelable, Filter {
            }
        }

        int viewId;
        public String getActionName() {
            return "SetOnClickPendingIntent";
        }

        PendingIntent pendingIntent;

        public final static int TAG = 1;
@@ -625,7 +700,10 @@ public class RemoteViews implements Parcelable, Filter {
            }
        }

        int viewId;
        public String getActionName() {
            return "SetDrawableParameters";
        }

        boolean targetBackground;
        int alpha;
        int colorFilter;
@@ -636,7 +714,6 @@ public class RemoteViews implements Parcelable, Filter {
    }

    private class ReflectionActionWithoutParams extends Action {
        int viewId;
        String methodName;

        public final static int TAG = 5;
@@ -688,6 +765,19 @@ public class RemoteViews implements Parcelable, Filter {
                throw new ActionException(ex);
            }
        }

        public int mergeBehavior() {
            // we don't need to build up showNext or showPrevious calls
            if (methodName.equals("showNext") || methodName.equals("showPrevious")) {
                return MERGE_IGNORE;
            } else {
                return MERGE_REPLACE;
            }
        }

        public String getActionName() {
            return "ReflectionActionWithoutParams";
        }
    }

    private static class BitmapCache {
@@ -755,7 +845,6 @@ public class RemoteViews implements Parcelable, Filter {

    private class BitmapReflectionAction extends Action {
        int bitmapId;
        int viewId;
        Bitmap bitmap;
        String methodName;

@@ -794,6 +883,10 @@ public class RemoteViews implements Parcelable, Filter {
            bitmapId = bitmapCache.getBitmapId(bitmap);
        }

        public String getActionName() {
            return "BitmapReflectionAction";
        }

        public final static int TAG = 12;
    }

@@ -814,11 +907,12 @@ public class RemoteViews implements Parcelable, Filter {
        static final int STRING = 9;
        static final int CHAR_SEQUENCE = 10;
        static final int URI = 11;
        // BITMAP actions are never stored in the list of actions. They are only used locally
        // to implement BitmapReflectionAction, which eliminates duplicates using BitmapCache.
        static final int BITMAP = 12;
        static final int BUNDLE = 13;
        static final int INTENT = 14;

        int viewId;
        String methodName;
        int type;
        Object value;
@@ -1041,19 +1135,19 @@ public class RemoteViews implements Parcelable, Filter {
            }
        }

        @Override
        public void updateMemoryUsageEstimate(MemoryUsageCounter counter) {
            // We currently only calculate Bitmap memory usage
            switch (this.type) {
                case BITMAP:
                    if (this.value != null) {
                        final Bitmap b = (Bitmap) this.value;
                        counter.addBitmapMemory(b);
        public int mergeBehavior() {
            // smoothScrollBy is cumulative, everything else overwites.
            if (methodName.equals("smoothScrollBy")) {
                return MERGE_APPEND;
            } else {
                return MERGE_REPLACE;
            }
                    break;
                default:
                    break;
        }

        public String getActionName() {
            // Each type of reflection action corresponds to a setter, so each should be seen as
            // unique from the standpoint of merging.
            return "ReflectionAction" + this.methodName + this.type;
        }
    }

@@ -1131,7 +1225,14 @@ public class RemoteViews implements Parcelable, Filter {
            }
        }

        int viewId;
        public String getActionName() {
            return "ViewGroupAction" + this.nestedViews == null ? "Remove" : "Add";
        }

        public int mergeBehavior() {
            return MERGE_APPEND;
        }

        RemoteViews nestedViews;

        public final static int TAG = 4;
@@ -1182,7 +1283,10 @@ public class RemoteViews implements Parcelable, Filter {
            }
        }

        int viewId;
        public String getActionName() {
            return "TextViewDrawableAction";
        }

        boolean isRelative = false;
        int d1, d2, d3, d4;

@@ -1220,7 +1324,10 @@ public class RemoteViews implements Parcelable, Filter {
            target.setTextSize(units, size);
        }

        int viewId;
        public String getActionName() {
            return "TextViewSizeAction";
        }

        int units;
        float size;

@@ -1264,7 +1371,10 @@ public class RemoteViews implements Parcelable, Filter {
            target.setPadding(left, top, right, bottom);
        }

        int viewId;
        public String getActionName() {
            return "ViewPaddingAction";
        }

        int left, top, right, bottom;

        public final static int TAG = 14;
+6 −2
Original line number Diff line number Diff line
@@ -980,9 +980,13 @@ class AppWidgetServiceImpl {
        // drop unbound appWidgetIds (shouldn't be possible under normal circumstances)
        if (id != null && id.provider != null && !id.provider.zombie && !id.host.zombie) {

            // We do not want to save this RemoteViews
            if (!isPartialUpdate)
            if (!isPartialUpdate) {
                // For a full update we replace the RemoteViews completely.
                id.views = views;
            } else {
                // For a partial update, we merge the new RemoteViews with the old.
                id.views.mergeRemoteViews(views);
            }

            // is anyone listening?
            if (id.host.callbacks != null) {