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:
@@ -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.
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user