am 11a6450e: Merge "Fixing partiallyUpdateAppWidget to cache the new changes" into jb-mr1-dev

* commit '11a6450e543d5c178c60ce2216fad1b29bf15457':
  Fixing partiallyUpdateAppWidget to cache the new changes
This commit is contained in:
Adam Cohen
2012-09-20 20:23:46 -07:00
committed by Android Git Automerger
3 changed files with 143 additions and 30 deletions

View File

@@ -436,10 +436,9 @@ public class AppWidgetManager {
* *
* This update differs from {@link #updateAppWidget(int[], RemoteViews)} in that the * 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 * 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 * widget, and hence does not replace the cached representation of the widget. As of API
* not cached, any state that they modify that is not restored by restoreInstanceState will not * level 17, the new properties set within the views objects will be appended to the cached
* persist in the case that the widgets are restored using the cached version in * representation of the widget, and hence will persist.
* AppWidgetService.
* *
* Use with {@link RemoteViews#showNext(int)}, {@link RemoteViews#showPrevious(int)}, * Use with {@link RemoteViews#showNext(int)}, {@link RemoteViews#showPrevious(int)},
* {@link RemoteViews#setScrollPosition(int, int)} and similar commands. * {@link RemoteViews#setScrollPosition(int, int)} and similar commands.

View File

@@ -52,6 +52,7 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; 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, public abstract void apply(View root, ViewGroup rootParent,
OnClickHandler handler) throws ActionException; 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() { public int describeContents() {
return 0; return 0;
} }
@@ -203,6 +208,60 @@ public class RemoteViews implements Parcelable, Filter {
public void setBitmapCache(BitmapCache bitmapCache) { public void setBitmapCache(BitmapCache bitmapCache) {
// Do nothing // 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 { private class SetEmptyView extends Action {
@@ -239,6 +298,10 @@ public class RemoteViews implements Parcelable, Filter {
adapterView.setEmptyView(emptyView); adapterView.setEmptyView(emptyView);
} }
public String getActionName() {
return "SetEmptyView";
}
} }
private class SetOnClickFillInIntent extends Action { private class SetOnClickFillInIntent extends Action {
@@ -316,7 +379,10 @@ public class RemoteViews implements Parcelable, Filter {
} }
} }
int viewId; public String getActionName() {
return "SetOnClickFillInIntent";
}
Intent fillInIntent; Intent fillInIntent;
public final static int TAG = 9; 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; PendingIntent pendingIntentTemplate;
public final static int TAG = 8; 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; Intent intent;
public final static int TAG = 10; 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; PendingIntent pendingIntent;
public final static int TAG = 1; 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; boolean targetBackground;
int alpha; int alpha;
int colorFilter; int colorFilter;
@@ -636,7 +714,6 @@ public class RemoteViews implements Parcelable, Filter {
} }
private class ReflectionActionWithoutParams extends Action { private class ReflectionActionWithoutParams extends Action {
int viewId;
String methodName; String methodName;
public final static int TAG = 5; public final static int TAG = 5;
@@ -688,6 +765,19 @@ public class RemoteViews implements Parcelable, Filter {
throw new ActionException(ex); 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 { private static class BitmapCache {
@@ -755,7 +845,6 @@ public class RemoteViews implements Parcelable, Filter {
private class BitmapReflectionAction extends Action { private class BitmapReflectionAction extends Action {
int bitmapId; int bitmapId;
int viewId;
Bitmap bitmap; Bitmap bitmap;
String methodName; String methodName;
@@ -794,6 +883,10 @@ public class RemoteViews implements Parcelable, Filter {
bitmapId = bitmapCache.getBitmapId(bitmap); bitmapId = bitmapCache.getBitmapId(bitmap);
} }
public String getActionName() {
return "BitmapReflectionAction";
}
public final static int TAG = 12; public final static int TAG = 12;
} }
@@ -814,11 +907,12 @@ public class RemoteViews implements Parcelable, Filter {
static final int STRING = 9; static final int STRING = 9;
static final int CHAR_SEQUENCE = 10; static final int CHAR_SEQUENCE = 10;
static final int URI = 11; 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 BITMAP = 12;
static final int BUNDLE = 13; static final int BUNDLE = 13;
static final int INTENT = 14; static final int INTENT = 14;
int viewId;
String methodName; String methodName;
int type; int type;
Object value; Object value;
@@ -1041,20 +1135,20 @@ public class RemoteViews implements Parcelable, Filter {
} }
} }
@Override public int mergeBehavior() {
public void updateMemoryUsageEstimate(MemoryUsageCounter counter) { // smoothScrollBy is cumulative, everything else overwites.
// We currently only calculate Bitmap memory usage if (methodName.equals("smoothScrollBy")) {
switch (this.type) { return MERGE_APPEND;
case BITMAP: } else {
if (this.value != null) { return MERGE_REPLACE;
final Bitmap b = (Bitmap) this.value;
counter.addBitmapMemory(b);
}
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;
}
} }
private void configureRemoteViewsAsChild(RemoteViews rv) { private void configureRemoteViewsAsChild(RemoteViews rv) {
@@ -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; RemoteViews nestedViews;
public final static int TAG = 4; 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; boolean isRelative = false;
int d1, d2, d3, d4; int d1, d2, d3, d4;
@@ -1220,7 +1324,10 @@ public class RemoteViews implements Parcelable, Filter {
target.setTextSize(units, size); target.setTextSize(units, size);
} }
int viewId; public String getActionName() {
return "TextViewSizeAction";
}
int units; int units;
float size; float size;
@@ -1264,7 +1371,10 @@ public class RemoteViews implements Parcelable, Filter {
target.setPadding(left, top, right, bottom); target.setPadding(left, top, right, bottom);
} }
int viewId; public String getActionName() {
return "ViewPaddingAction";
}
int left, top, right, bottom; int left, top, right, bottom;
public final static int TAG = 14; public final static int TAG = 14;

View File

@@ -980,9 +980,13 @@ class AppWidgetServiceImpl {
// drop unbound appWidgetIds (shouldn't be possible under normal circumstances) // drop unbound appWidgetIds (shouldn't be possible under normal circumstances)
if (id != null && id.provider != null && !id.provider.zombie && !id.host.zombie) { 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; id.views = views;
} else {
// For a partial update, we merge the new RemoteViews with the old.
id.views.mergeRemoteViews(views);
}
// is anyone listening? // is anyone listening?
if (id.host.callbacks != null) { if (id.host.callbacks != null) {