summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/current.txt5
-rw-r--r--core/java/android/widget/RemoteViews.java292
2 files changed, 256 insertions, 41 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index f49ce1fd48a5..976fa5ed161d 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -54458,19 +54458,24 @@ package android.widget {
method public void setByte(@IdRes int, String, byte);
method public void setChar(@IdRes int, String, char);
method public void setCharSequence(@IdRes int, String, CharSequence);
+ method public void setCharSequence(@IdRes int, @NonNull String, @StringRes int);
method public void setChronometer(@IdRes int, long, String, boolean);
method public void setChronometerCountDown(@IdRes int, boolean);
+ method public void setColor(@IdRes int, @NonNull String, @ColorRes int);
+ method public void setColorStateList(@IdRes int, @NonNull String, @ColorRes int);
method public void setContentDescription(@IdRes int, CharSequence);
method public void setDisplayedChild(@IdRes int, int);
method public void setDouble(@IdRes int, String, double);
method public void setEmptyView(@IdRes int, @IdRes int);
method public void setFloat(@IdRes int, String, float);
+ method public void setFloatDimen(@IdRes int, @NonNull String, @DimenRes int);
method public void setIcon(@IdRes int, String, android.graphics.drawable.Icon);
method public void setImageViewBitmap(@IdRes int, android.graphics.Bitmap);
method public void setImageViewIcon(@IdRes int, android.graphics.drawable.Icon);
method public void setImageViewResource(@IdRes int, @DrawableRes int);
method public void setImageViewUri(@IdRes int, android.net.Uri);
method public void setInt(@IdRes int, String, int);
+ method public void setIntDimen(@IdRes int, @NonNull String, @DimenRes int);
method public void setIntent(@IdRes int, String, android.content.Intent);
method public void setLabelFor(@IdRes int, @IdRes int);
method public void setLightBackgroundLayoutId(@LayoutRes int);
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 8dafc5db6178..f78039b4a637 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -17,6 +17,7 @@
package android.widget;
import android.annotation.ColorInt;
+import android.annotation.ColorRes;
import android.annotation.DimenRes;
import android.annotation.DrawableRes;
import android.annotation.IdRes;
@@ -25,6 +26,7 @@ import android.annotation.LayoutRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Px;
+import android.annotation.StringRes;
import android.annotation.StyleRes;
import android.app.Activity;
import android.app.ActivityOptions;
@@ -180,6 +182,7 @@ public class RemoteViews implements Parcelable, Filter {
private static final int SET_RIPPLE_DRAWABLE_COLOR_TAG = 21;
private static final int SET_INT_TAG_TAG = 22;
private static final int REMOVE_FROM_PARENT_ACTION_TAG = 23;
+ private static final int RESOURCE_REFLECTION_ACTION_TAG = 24;
/** @hide **/
@IntDef(prefix = "MARGIN_", value = {
@@ -980,6 +983,45 @@ public class RemoteViews implements Parcelable, Filter {
return rect;
}
+ private static Class<?> getParameterType(int type) {
+ switch (type) {
+ case ReflectionAction.BOOLEAN:
+ return boolean.class;
+ case ReflectionAction.BYTE:
+ return byte.class;
+ case ReflectionAction.SHORT:
+ return short.class;
+ case ReflectionAction.INT:
+ return int.class;
+ case ReflectionAction.LONG:
+ return long.class;
+ case ReflectionAction.FLOAT:
+ return float.class;
+ case ReflectionAction.DOUBLE:
+ return double.class;
+ case ReflectionAction.CHAR:
+ return char.class;
+ case ReflectionAction.STRING:
+ return String.class;
+ case ReflectionAction.CHAR_SEQUENCE:
+ return CharSequence.class;
+ case ReflectionAction.URI:
+ return Uri.class;
+ case ReflectionAction.BITMAP:
+ return Bitmap.class;
+ case ReflectionAction.BUNDLE:
+ return Bundle.class;
+ case ReflectionAction.INTENT:
+ return Intent.class;
+ case ReflectionAction.COLOR_STATE_LIST:
+ return ColorStateList.class;
+ case ReflectionAction.ICON:
+ return Icon.class;
+ default:
+ return null;
+ }
+ }
+
private MethodHandle getMethod(View view, String methodName, Class<?> paramType,
boolean async) {
MethodArgs result;
@@ -1457,51 +1499,12 @@ public class RemoteViews implements Parcelable, Filter {
}
}
- private Class<?> getParameterType() {
- switch (this.type) {
- case BOOLEAN:
- return boolean.class;
- case BYTE:
- return byte.class;
- case SHORT:
- return short.class;
- case INT:
- return int.class;
- case LONG:
- return long.class;
- case FLOAT:
- return float.class;
- case DOUBLE:
- return double.class;
- case CHAR:
- return char.class;
- case STRING:
- return String.class;
- case CHAR_SEQUENCE:
- return CharSequence.class;
- case URI:
- return Uri.class;
- case BITMAP:
- return Bitmap.class;
- case BUNDLE:
- return Bundle.class;
- case INTENT:
- return Intent.class;
- case COLOR_STATE_LIST:
- return ColorStateList.class;
- case ICON:
- return Icon.class;
- default:
- return null;
- }
- }
-
@Override
public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
final View view = root.findViewById(viewId);
if (view == null) return;
- Class<?> param = getParameterType();
+ Class<?> param = getParameterType(this.type);
if (param == null) {
throw new ActionException("bad type: " + this.type);
}
@@ -1517,7 +1520,7 @@ public class RemoteViews implements Parcelable, Filter {
final View view = root.findViewById(viewId);
if (view == null) return ACTION_NOOP;
- Class<?> param = getParameterType();
+ Class<?> param = getParameterType(this.type);
if (param == null) {
throw new ActionException("bad type: " + this.type);
}
@@ -1588,6 +1591,133 @@ public class RemoteViews implements Parcelable, Filter {
}
}
+ private final class ResourceReflectionAction extends Action {
+
+ static final int DIMEN_RESOURCE = 1;
+ static final int COLOR_RESOURCE = 2;
+ static final int STRING_RESOURCE = 3;
+
+ private final String mMethodName;
+ private final int mParameterType;
+ private final int mResourceType;
+ private final int mResId;
+
+ ResourceReflectionAction(@IdRes int viewId, String methodName, int parameterType,
+ int resourceType, int resId) {
+ this.viewId = viewId;
+ this.mMethodName = methodName;
+ this.mParameterType = parameterType;
+ this.mResourceType = resourceType;
+ this.mResId = resId;
+ }
+
+ ResourceReflectionAction(Parcel in) {
+ this.viewId = in.readInt();
+ this.mMethodName = in.readString8();
+ this.mParameterType = in.readInt();
+ this.mResourceType = in.readInt();
+ this.mResId = in.readInt();
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(this.viewId);
+ dest.writeString8(this.mMethodName);
+ dest.writeInt(this.mParameterType);
+ dest.writeInt(this.mResourceType);
+ dest.writeInt(this.mResId);
+ }
+
+ private @NonNull Object getResourceValue(View view) throws ActionException {
+ Resources resources = view.getContext().getResources();
+ try {
+ switch (this.mResourceType) {
+ case DIMEN_RESOURCE:
+ if (this.mParameterType == ReflectionAction.INT) {
+ return resources.getDimensionPixelSize(this.mResId);
+ }
+ return resources.getDimension(this.mResId);
+ case COLOR_RESOURCE:
+ switch(this.mParameterType) {
+ case ReflectionAction.INT:
+ return view.getContext().getColor(this.mResId);
+ case ReflectionAction.COLOR_STATE_LIST:
+ return view.getContext().getColorStateList(this.mResId);
+ default:
+ throw new ActionException(
+ "color resources must be used as int or ColorStateList, "
+ + "not " + this.mParameterType);
+ }
+ case STRING_RESOURCE:
+ return resources.getText(this.mResId);
+ default:
+ throw new ActionException("unknown resource type: " + this.mResourceType);
+ }
+ } catch (Throwable t) {
+ throw new ActionException(t);
+ }
+ }
+
+ @Override
+ public void apply(View root, ViewGroup rootParent, OnClickHandler handler)
+ throws ActionException {
+ final View view = root.findViewById(viewId);
+ if (view == null) return;
+ Object value = getResourceValue(view);
+ Class<?> param = getParameterType(this.mParameterType);
+ if (param == null) {
+ throw new ActionException("bad type: " + this.mParameterType);
+ }
+ try {
+ getMethod(view, this.mMethodName, param, false /* async */).invoke(view, value);
+ } catch (Throwable ex) {
+ throw new ActionException(ex);
+ }
+ }
+
+ @Override
+ public Action initActionAsync(ViewTree root, ViewGroup rootParent, OnClickHandler handler) {
+ final View view = root.findViewById(viewId);
+ if (view == null) return ACTION_NOOP;
+
+ Class<?> param = getParameterType(this.mParameterType);
+ if (param == null) {
+ throw new ActionException("bad type: " + this.mParameterType);
+ }
+
+ Object value = getResourceValue(view);
+
+ try {
+ MethodHandle method = getMethod(view, this.mMethodName, param, true /* async */);
+
+ if (method != null) {
+ Runnable endAction = (Runnable) method.invoke(view, value);
+ if (endAction == null) {
+ return ACTION_NOOP;
+ } else {
+ // Special case view stub
+ if (endAction instanceof ViewStub.ViewReplaceRunnable) {
+ root.createTree();
+ // Replace child tree
+ root.findViewTreeById(viewId).replaceView(
+ ((ViewStub.ViewReplaceRunnable) endAction).view);
+ }
+ return new RunnableAction(endAction);
+ }
+ }
+ } catch (Throwable ex) {
+ throw new ActionException(ex);
+ }
+
+ return this;
+ }
+
+ @Override
+ public int getActionTag() {
+ return RESOURCE_REFLECTION_ACTION_TAG;
+ }
+ }
+
/**
* This is only used for async execution of actions and it not parcelable.
*/
@@ -2611,6 +2741,8 @@ public class RemoteViews implements Parcelable, Filter {
return new SetIntTagAction(parcel);
case REMOVE_FROM_PARENT_ACTION_TAG:
return new RemoveFromParentAction(parcel);
+ case RESOURCE_REFLECTION_ACTION_TAG:
+ return new ResourceReflectionAction(parcel);
default:
throw new ActionException("Tag " + tag + " not found");
}
@@ -3390,6 +3522,38 @@ public class RemoteViews implements Parcelable, Filter {
}
/**
+ * Call a method taking one int, a size in pixels, on a view in the layout for this
+ * RemoteViews.
+ *
+ * The dimension will be resolved from the resources at the time of inflation.
+ *
+ * @param viewId The id of the view on which to call the method.
+ * @param methodName The name of the method to call.
+ * @param dimenResource The resource to resolve and pass as argument to the method.
+ */
+ public void setIntDimen(@IdRes int viewId, @NonNull String methodName,
+ @DimenRes int dimenResource) {
+ addAction(new ResourceReflectionAction(viewId, methodName, ReflectionAction.INT,
+ ResourceReflectionAction.DIMEN_RESOURCE, dimenResource));
+ }
+
+ /**
+ * Call a method taking one int, a color, on a view in the layout for this RemoteViews.
+ *
+ * The ColorStateList will be resolved from the resources at the time of inflation.
+ *
+ * @param viewId The id of the view on which to call the method.
+ * @param methodName The name of the method to call.
+ * @param colorResource The resource to resolve and pass as argument to the method.
+ */
+ public void setColor(@IdRes int viewId, @NonNull String methodName,
+ @ColorRes int colorResource) {
+ addAction(new ResourceReflectionAction(viewId, methodName, ReflectionAction.INT,
+ ResourceReflectionAction.COLOR_RESOURCE, colorResource));
+ }
+
+
+ /**
* Call a method taking one ColorStateList on a view in the layout for this RemoteViews.
*
* @param viewId The id of the view on which to call the method.
@@ -3403,6 +3567,21 @@ public class RemoteViews implements Parcelable, Filter {
value));
}
+ /**
+ * Call a method taking one ColorStateList on a view in the layout for this RemoteViews.
+ *
+ * The ColorStateList will be resolved from the resources at the time of inflation.
+ *
+ * @param viewId The id of the view on which to call the method.
+ * @param methodName The name of the method to call.
+ * @param colorResource The resource to resolve and pass as argument to the method.
+ */
+ public void setColorStateList(@IdRes int viewId, @NonNull String methodName,
+ @ColorRes int colorResource) {
+ addAction(
+ new ResourceReflectionAction(viewId, methodName, ReflectionAction.COLOR_STATE_LIST,
+ ResourceReflectionAction.COLOR_RESOURCE, colorResource));
+ }
/**
* Call a method taking one long on a view in the layout for this RemoteViews.
@@ -3427,6 +3606,22 @@ public class RemoteViews implements Parcelable, Filter {
}
/**
+ * Call a method taking one float, a size in pixels, on a view in the layout for this
+ * RemoteViews.
+ *
+ * The dimension will be resolved from the resources at the time of inflation.
+ *
+ * @param viewId The id of the view on which to call the method.
+ * @param methodName The name of the method to call.
+ * @param dimenResource The resource to resolve and pass as argument to the method.
+ */
+ public void setFloatDimen(@IdRes int viewId, @NonNull String methodName,
+ @DimenRes int dimenResource) {
+ addAction(new ResourceReflectionAction(viewId, methodName, ReflectionAction.FLOAT,
+ ResourceReflectionAction.DIMEN_RESOURCE, dimenResource));
+ }
+
+ /**
* Call a method taking one double on a view in the layout for this RemoteViews.
*
* @param viewId The id of the view on which to call the method.
@@ -3471,6 +3666,21 @@ public class RemoteViews implements Parcelable, Filter {
}
/**
+ * Call a method taking one CharSequence on a view in the layout for this RemoteViews.
+ *
+ * The CharSequence will be resolved from the resources at the time of inflation.
+ *
+ * @param viewId The id of the view on which to call the method.
+ * @param methodName The name of the method to call.
+ * @param stringResource The resource to resolve and pass as argument to the method.
+ */
+ public void setCharSequence(@IdRes int viewId, @NonNull String methodName,
+ @StringRes int stringResource) {
+ addAction(new ResourceReflectionAction(viewId, methodName, ReflectionAction.CHAR_SEQUENCE,
+ ResourceReflectionAction.STRING_RESOURCE, stringResource));
+ }
+
+ /**
* Call a method taking one Uri on a view in the layout for this RemoteViews.
*
* @param viewId The id of the view on which to call the method.