Loading core/api/current.txt +1 −1 Original line number Diff line number Diff line Loading @@ -2483,7 +2483,6 @@ package android { field public static final int primary = 16908300; // 0x102000c field public static final int progress = 16908301; // 0x102000d field public static final int redo = 16908339; // 0x1020033 field @FlaggedApi("android.appwidget.flags.engagement_metrics") public static final int remoteViewsMetricsId; field public static final int replaceText = 16908340; // 0x1020034 field public static final int secondaryProgress = 16908303; // 0x102000f field public static final int selectAll = 16908319; // 0x102001f Loading Loading @@ -61755,6 +61754,7 @@ package android.widget { method public void setTextViewText(@IdRes int, CharSequence); method public void setTextViewTextSize(@IdRes int, int, float); method public void setUri(@IdRes int, String, android.net.Uri); method @FlaggedApi("android.appwidget.flags.engagement_metrics") public void setUsageEventTag(@IdRes int, int); method public void setViewLayoutHeight(@IdRes int, float, int); method public void setViewLayoutHeightAttr(@IdRes int, @AttrRes int); method public void setViewLayoutHeightDimen(@IdRes int, @DimenRes int); core/java/android/appwidget/AppWidgetHostView.java +115 −24 Original line number Diff line number Diff line Loading @@ -16,10 +16,15 @@ package android.appwidget; import static android.appwidget.flags.Flags.FLAG_ENGAGEMENT_METRICS; import static android.appwidget.flags.Flags.engagementMetrics; import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Activity; import android.app.ActivityOptions; import android.app.PendingIntent; import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; Loading @@ -38,6 +43,7 @@ import android.os.Build; import android.os.Bundle; import android.os.CancellationSignal; import android.os.Parcelable; import android.util.ArraySet; import android.util.AttributeSet; import android.util.Log; import android.util.Pair; Loading @@ -48,6 +54,7 @@ import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.accessibility.AccessibilityNodeInfo; import android.widget.AbsListView; import android.widget.Adapter; import android.widget.AdapterView; import android.widget.BaseAdapter; Loading @@ -57,8 +64,11 @@ import android.widget.RemoteViews.InteractionHandler; import android.widget.RemoteViewsAdapter.RemoteAdapterConnectionCallback; import android.widget.TextView; import com.android.internal.annotations.VisibleForTesting; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.concurrent.Executor; /** Loading Loading @@ -99,7 +109,8 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW int mViewMode = VIEW_MODE_NOINIT; // If true, we should not try to re-apply the RemoteViews on the next inflation. boolean mColorMappingChanged = false; private InteractionHandler mInteractionHandler; @NonNull private InteractionLogger mInteractionLogger = new InteractionLogger(); private boolean mOnLightBackground; private SizeF mCurrentSize = null; private RemoteViews.ColorResources mColorResources = null; Loading @@ -124,7 +135,7 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW */ public AppWidgetHostView(Context context, InteractionHandler handler) { this(context, android.R.anim.fade_in, android.R.anim.fade_out); mInteractionHandler = getHandler(handler); setInteractionHandler(handler); } /** Loading @@ -145,13 +156,29 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW /** * Pass the given handler to RemoteViews when updating this widget. Unless this * is done immediatly after construction, a call to {@link #updateAppWidget(RemoteViews)} * is done immediately after construction, a call to {@link #updateAppWidget(RemoteViews)} * should be made. * * @hide */ public void setInteractionHandler(InteractionHandler handler) { mInteractionHandler = getHandler(handler); if (handler instanceof InteractionLogger logger) { // Nested AppWidgetHostViews should reuse the parent logger instead of wrapping it. mInteractionLogger = logger; } else { mInteractionLogger = new InteractionLogger(handler); } } /** * Return the InteractionLogger used by this class. * * @hide */ @VisibleForTesting @NonNull public InteractionLogger getInteractionLogger() { return mInteractionLogger; } /** Loading Loading @@ -588,7 +615,7 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW if (!mColorMappingChanged && rvToApply.canRecycleView(mView)) { try { rvToApply.reapply(mContext, mView, mInteractionHandler, mCurrentSize, rvToApply.reapply(mContext, mView, mInteractionLogger, mCurrentSize, mColorResources); content = mView; mLastInflatedRemoteViewsId = rvToApply.computeUniqueId(remoteViews); Loading @@ -602,7 +629,7 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW // Try normal RemoteView inflation if (content == null) { try { content = rvToApply.apply(mContext, this, mInteractionHandler, content = rvToApply.apply(mContext, this, mInteractionLogger, mCurrentSize, mColorResources); mLastInflatedRemoteViewsId = rvToApply.computeUniqueId(remoteViews); if (LOGD) Log.d(TAG, "had to inflate new layout"); Loading Loading @@ -660,7 +687,7 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW mView, mAsyncExecutor, new ViewApplyListener(remoteViews, layoutId, true), mInteractionHandler, mInteractionLogger, mCurrentSize, mColorResources); } catch (Exception e) { Loading @@ -672,7 +699,7 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW this, mAsyncExecutor, new ViewApplyListener(remoteViews, layoutId, false), mInteractionHandler, mInteractionLogger, mCurrentSize, mColorResources); } Loading Loading @@ -711,7 +738,7 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW AppWidgetHostView.this, mAsyncExecutor, new ViewApplyListener(mViews, mLayoutId, false), mInteractionHandler, mInteractionLogger, mCurrentSize); } else { applyContent(null, false, e); Loading Loading @@ -916,21 +943,6 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW return null; } private InteractionHandler getHandler(InteractionHandler handler) { return (view, pendingIntent, response) -> { AppWidgetManager manager = AppWidgetManager.getInstance(mContext); if (manager != null) { manager.noteAppWidgetTapped(mAppWidgetId); } if (handler != null) { return handler.onInteraction(view, pendingIntent, response); } else { return RemoteViews.startPendingIntent(view, pendingIntent, response.getLaunchOptions(view)); } }; } /** * Set the dynamically overloaded color resources. * Loading Loading @@ -1016,4 +1028,83 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW post(this::handleViewError); } } /** * This class is used to track user interactions with this widget. * @hide */ public class InteractionLogger implements RemoteViews.InteractionHandler { // Max number of clicked and scrolled IDs stored per impression. public static final int MAX_NUM_ITEMS = 10; // Clicked views @NonNull private final Set<Integer> mClickedIds = new ArraySet<>(MAX_NUM_ITEMS); // Scrolled views @NonNull private final Set<Integer> mScrolledIds = new ArraySet<>(MAX_NUM_ITEMS); @Nullable private RemoteViews.InteractionHandler mInteractionHandler = null; InteractionLogger() { } InteractionLogger(@Nullable InteractionHandler handler) { mInteractionHandler = handler; } @VisibleForTesting @NonNull public Set<Integer> getClickedIds() { return mClickedIds; } @VisibleForTesting @NonNull public Set<Integer> getScrolledIds() { return mScrolledIds; } @Override public boolean onInteraction(View view, PendingIntent pendingIntent, RemoteViews.RemoteResponse response) { if (engagementMetrics() && mClickedIds.size() < MAX_NUM_ITEMS) { mClickedIds.add(getMetricsId(view)); } AppWidgetManager manager = AppWidgetManager.getInstance(mContext); if (manager != null) { manager.noteAppWidgetTapped(mAppWidgetId); } if (mInteractionHandler != null) { return mInteractionHandler.onInteraction(view, pendingIntent, response); } else { return RemoteViews.startPendingIntent(view, pendingIntent, response.getLaunchOptions(view)); } } @Override public void onScroll(@NonNull AbsListView view) { if (!engagementMetrics()) return; if (mScrolledIds.size() < MAX_NUM_ITEMS) { mScrolledIds.add(getMetricsId(view)); } if (mInteractionHandler != null) { mInteractionHandler.onScroll(view); } } @FlaggedApi(FLAG_ENGAGEMENT_METRICS) private int getMetricsId(@NonNull View view) { int viewId = view.getId(); Object metricsTag = view.getTag(com.android.internal.R.id.remoteViewsMetricsId); if (metricsTag instanceof Integer tag) { viewId = tag; } return viewId; } } } core/java/android/appwidget/AppWidgetManager.java +10 −8 Original line number Diff line number Diff line Loading @@ -515,12 +515,13 @@ public class AppWidgetManager { /** * This bundle extra describes which views have been clicked during a single impression of the * widget. It is an integer array of view IDs of the clicked views. * widget. It is an integer array of view IDs of the clicked views. The array may contain up to * 10 distinct IDs per event. * * Widget providers may set a different ID for event purposes by setting the * {@link android.R.id.remoteViewsMetricsId} int tag on the view. * Widget providers may set a different ID for event logging by setting the usage event tag on * the view with {@link RemoteViews#setUsageEventTag}. * * @see android.views.RemoteViews.setIntTag * @see android.widget.RemoteViews#setUsageEventTag */ @FlaggedApi(Flags.FLAG_ENGAGEMENT_METRICS) public static final String EXTRA_EVENT_CLICKED_VIEWS = Loading @@ -528,12 +529,13 @@ public class AppWidgetManager { /** * This bundle extra describes which views have been scrolled during a single impression of the * widget. It is an integer array of view IDs of the scrolled views. * widget. It is an integer array of view IDs of the scrolled views. The array may contain up to * 10 distinct IDs per event. * * Widget providers may set a different ID for event purposes by setting the * {@link android.R.id.remoteViewsMetricsId} int tag on the view. * Widget providers may set a different ID for event logging by setting the usage event tag on * the view with {@link RemoteViews#setUsageEventTag}. * * @see android.views.RemoteViews.setIntTag * @see android.widget.RemoteViews#setUsageEventTag */ @FlaggedApi(Flags.FLAG_ENGAGEMENT_METRICS) public static final String EXTRA_EVENT_SCROLLED_VIEWS = Loading core/java/android/widget/RemoteViews.java +57 −1 Original line number Diff line number Diff line Loading @@ -547,6 +547,25 @@ public class RemoteViews implements Parcelable, Filter { addAction(new SetIntTagAction(viewId, key, tag)); } /** * Set a view tag associating a View with an ID to be used for widget interaction usage events * ({@link android.app.usage.UsageEvents.Event}). When this RemoteViews is applied to a bound * widget, any clicks or scrolls on the tagged view will be reported to * {@link android.app.usage.UsageStatsManager} using this tag. * * @param viewId ID of the View whose tag will be set * @param tag The integer tag to use for the event * * @see android.appwidget.AppWidgetManager#EVENT_TYPE_WIDGET_INTERACTION * @see android.appwidget.AppWidgetManager#EXTRA_EVENT_CLICKED_VIEWS * @see android.appwidget.AppWidgetManager#EXTRA_EVENT_SCROLLED_VIEWS * @see android.app.usage.UsageStatsManager#queryEventsForSelf */ @FlaggedApi(Flags.FLAG_ENGAGEMENT_METRICS) public void setUsageEventTag(@IdRes int viewId, int tag) { addAction(new SetIntTagAction(viewId, com.android.internal.R.id.remoteViewsMetricsId, tag)); } /** * Set that it is disallowed to reapply another remoteview with the same layout as this view. * This should be done if an action is destroying the view tree of the base layout. Loading Loading @@ -666,6 +685,14 @@ public class RemoteViews implements Parcelable, Filter { View view, PendingIntent pendingIntent, RemoteResponse response); /** * Invoked when an AbsListView is scrolled. * @param view view that was scrolled * * @hide */ default void onScroll(@NonNull AbsListView view) {} } /** Loading Loading @@ -1313,6 +1340,21 @@ public class RemoteViews implements Parcelable, Filter { // a type error. throw new ActionException(throwable); } if (adapterView instanceof AbsListView listView) { listView.setOnScrollListener(new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { if (scrollState != SCROLL_STATE_IDLE) { params.handler.onScroll(view); } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { } }); } } @Override Loading Loading @@ -1804,6 +1846,19 @@ public class RemoteViews implements Parcelable, Filter { AbsListView v = (AbsListView) target; v.setRemoteViewsAdapter(mIntent, mIsAsync); v.setRemoteViewsInteractionHandler(params.handler); v.setOnScrollListener(new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { if (scrollState != SCROLL_STATE_IDLE) { params.handler.onScroll(view); } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { } }); } else if (target instanceof AdapterViewAnimator) { AdapterViewAnimator v = (AdapterViewAnimator) target; v.setRemoteViewsAdapter(mIntent, mIsAsync); Loading Loading @@ -1894,7 +1949,8 @@ public class RemoteViews implements Parcelable, Filter { target.setTagInternal(com.android.internal.R.id.fillInIntent, null); return; } target.setOnClickListener(v -> mResponse.handleViewInteraction(v, params.handler)); target.setOnClickListener(v -> mResponse.handleViewInteraction(v, params.handler)); } @Override Loading core/res/res/values/public-staging.xml +1 −1 Original line number Diff line number Diff line Loading @@ -128,7 +128,7 @@ <staging-public-group type="id" first-id="0x01b20000"> <!-- @FlaggedApi(android.appwidget.flags.Flags.FLAG_ENGAGEMENT_METRICS) --> <public name="remoteViewsMetricsId"/> <public name="removed_remoteViewsMetricsId"/> <!-- @FlaggedApi("android.view.accessibility.a11y_selection_api") --> <public name="accessibilityActionSetExtendedSelection"/> </staging-public-group> Loading Loading
core/api/current.txt +1 −1 Original line number Diff line number Diff line Loading @@ -2483,7 +2483,6 @@ package android { field public static final int primary = 16908300; // 0x102000c field public static final int progress = 16908301; // 0x102000d field public static final int redo = 16908339; // 0x1020033 field @FlaggedApi("android.appwidget.flags.engagement_metrics") public static final int remoteViewsMetricsId; field public static final int replaceText = 16908340; // 0x1020034 field public static final int secondaryProgress = 16908303; // 0x102000f field public static final int selectAll = 16908319; // 0x102001f Loading Loading @@ -61755,6 +61754,7 @@ package android.widget { method public void setTextViewText(@IdRes int, CharSequence); method public void setTextViewTextSize(@IdRes int, int, float); method public void setUri(@IdRes int, String, android.net.Uri); method @FlaggedApi("android.appwidget.flags.engagement_metrics") public void setUsageEventTag(@IdRes int, int); method public void setViewLayoutHeight(@IdRes int, float, int); method public void setViewLayoutHeightAttr(@IdRes int, @AttrRes int); method public void setViewLayoutHeightDimen(@IdRes int, @DimenRes int);
core/java/android/appwidget/AppWidgetHostView.java +115 −24 Original line number Diff line number Diff line Loading @@ -16,10 +16,15 @@ package android.appwidget; import static android.appwidget.flags.Flags.FLAG_ENGAGEMENT_METRICS; import static android.appwidget.flags.Flags.engagementMetrics; import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Activity; import android.app.ActivityOptions; import android.app.PendingIntent; import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; Loading @@ -38,6 +43,7 @@ import android.os.Build; import android.os.Bundle; import android.os.CancellationSignal; import android.os.Parcelable; import android.util.ArraySet; import android.util.AttributeSet; import android.util.Log; import android.util.Pair; Loading @@ -48,6 +54,7 @@ import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.accessibility.AccessibilityNodeInfo; import android.widget.AbsListView; import android.widget.Adapter; import android.widget.AdapterView; import android.widget.BaseAdapter; Loading @@ -57,8 +64,11 @@ import android.widget.RemoteViews.InteractionHandler; import android.widget.RemoteViewsAdapter.RemoteAdapterConnectionCallback; import android.widget.TextView; import com.android.internal.annotations.VisibleForTesting; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.concurrent.Executor; /** Loading Loading @@ -99,7 +109,8 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW int mViewMode = VIEW_MODE_NOINIT; // If true, we should not try to re-apply the RemoteViews on the next inflation. boolean mColorMappingChanged = false; private InteractionHandler mInteractionHandler; @NonNull private InteractionLogger mInteractionLogger = new InteractionLogger(); private boolean mOnLightBackground; private SizeF mCurrentSize = null; private RemoteViews.ColorResources mColorResources = null; Loading @@ -124,7 +135,7 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW */ public AppWidgetHostView(Context context, InteractionHandler handler) { this(context, android.R.anim.fade_in, android.R.anim.fade_out); mInteractionHandler = getHandler(handler); setInteractionHandler(handler); } /** Loading @@ -145,13 +156,29 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW /** * Pass the given handler to RemoteViews when updating this widget. Unless this * is done immediatly after construction, a call to {@link #updateAppWidget(RemoteViews)} * is done immediately after construction, a call to {@link #updateAppWidget(RemoteViews)} * should be made. * * @hide */ public void setInteractionHandler(InteractionHandler handler) { mInteractionHandler = getHandler(handler); if (handler instanceof InteractionLogger logger) { // Nested AppWidgetHostViews should reuse the parent logger instead of wrapping it. mInteractionLogger = logger; } else { mInteractionLogger = new InteractionLogger(handler); } } /** * Return the InteractionLogger used by this class. * * @hide */ @VisibleForTesting @NonNull public InteractionLogger getInteractionLogger() { return mInteractionLogger; } /** Loading Loading @@ -588,7 +615,7 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW if (!mColorMappingChanged && rvToApply.canRecycleView(mView)) { try { rvToApply.reapply(mContext, mView, mInteractionHandler, mCurrentSize, rvToApply.reapply(mContext, mView, mInteractionLogger, mCurrentSize, mColorResources); content = mView; mLastInflatedRemoteViewsId = rvToApply.computeUniqueId(remoteViews); Loading @@ -602,7 +629,7 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW // Try normal RemoteView inflation if (content == null) { try { content = rvToApply.apply(mContext, this, mInteractionHandler, content = rvToApply.apply(mContext, this, mInteractionLogger, mCurrentSize, mColorResources); mLastInflatedRemoteViewsId = rvToApply.computeUniqueId(remoteViews); if (LOGD) Log.d(TAG, "had to inflate new layout"); Loading Loading @@ -660,7 +687,7 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW mView, mAsyncExecutor, new ViewApplyListener(remoteViews, layoutId, true), mInteractionHandler, mInteractionLogger, mCurrentSize, mColorResources); } catch (Exception e) { Loading @@ -672,7 +699,7 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW this, mAsyncExecutor, new ViewApplyListener(remoteViews, layoutId, false), mInteractionHandler, mInteractionLogger, mCurrentSize, mColorResources); } Loading Loading @@ -711,7 +738,7 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW AppWidgetHostView.this, mAsyncExecutor, new ViewApplyListener(mViews, mLayoutId, false), mInteractionHandler, mInteractionLogger, mCurrentSize); } else { applyContent(null, false, e); Loading Loading @@ -916,21 +943,6 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW return null; } private InteractionHandler getHandler(InteractionHandler handler) { return (view, pendingIntent, response) -> { AppWidgetManager manager = AppWidgetManager.getInstance(mContext); if (manager != null) { manager.noteAppWidgetTapped(mAppWidgetId); } if (handler != null) { return handler.onInteraction(view, pendingIntent, response); } else { return RemoteViews.startPendingIntent(view, pendingIntent, response.getLaunchOptions(view)); } }; } /** * Set the dynamically overloaded color resources. * Loading Loading @@ -1016,4 +1028,83 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW post(this::handleViewError); } } /** * This class is used to track user interactions with this widget. * @hide */ public class InteractionLogger implements RemoteViews.InteractionHandler { // Max number of clicked and scrolled IDs stored per impression. public static final int MAX_NUM_ITEMS = 10; // Clicked views @NonNull private final Set<Integer> mClickedIds = new ArraySet<>(MAX_NUM_ITEMS); // Scrolled views @NonNull private final Set<Integer> mScrolledIds = new ArraySet<>(MAX_NUM_ITEMS); @Nullable private RemoteViews.InteractionHandler mInteractionHandler = null; InteractionLogger() { } InteractionLogger(@Nullable InteractionHandler handler) { mInteractionHandler = handler; } @VisibleForTesting @NonNull public Set<Integer> getClickedIds() { return mClickedIds; } @VisibleForTesting @NonNull public Set<Integer> getScrolledIds() { return mScrolledIds; } @Override public boolean onInteraction(View view, PendingIntent pendingIntent, RemoteViews.RemoteResponse response) { if (engagementMetrics() && mClickedIds.size() < MAX_NUM_ITEMS) { mClickedIds.add(getMetricsId(view)); } AppWidgetManager manager = AppWidgetManager.getInstance(mContext); if (manager != null) { manager.noteAppWidgetTapped(mAppWidgetId); } if (mInteractionHandler != null) { return mInteractionHandler.onInteraction(view, pendingIntent, response); } else { return RemoteViews.startPendingIntent(view, pendingIntent, response.getLaunchOptions(view)); } } @Override public void onScroll(@NonNull AbsListView view) { if (!engagementMetrics()) return; if (mScrolledIds.size() < MAX_NUM_ITEMS) { mScrolledIds.add(getMetricsId(view)); } if (mInteractionHandler != null) { mInteractionHandler.onScroll(view); } } @FlaggedApi(FLAG_ENGAGEMENT_METRICS) private int getMetricsId(@NonNull View view) { int viewId = view.getId(); Object metricsTag = view.getTag(com.android.internal.R.id.remoteViewsMetricsId); if (metricsTag instanceof Integer tag) { viewId = tag; } return viewId; } } }
core/java/android/appwidget/AppWidgetManager.java +10 −8 Original line number Diff line number Diff line Loading @@ -515,12 +515,13 @@ public class AppWidgetManager { /** * This bundle extra describes which views have been clicked during a single impression of the * widget. It is an integer array of view IDs of the clicked views. * widget. It is an integer array of view IDs of the clicked views. The array may contain up to * 10 distinct IDs per event. * * Widget providers may set a different ID for event purposes by setting the * {@link android.R.id.remoteViewsMetricsId} int tag on the view. * Widget providers may set a different ID for event logging by setting the usage event tag on * the view with {@link RemoteViews#setUsageEventTag}. * * @see android.views.RemoteViews.setIntTag * @see android.widget.RemoteViews#setUsageEventTag */ @FlaggedApi(Flags.FLAG_ENGAGEMENT_METRICS) public static final String EXTRA_EVENT_CLICKED_VIEWS = Loading @@ -528,12 +529,13 @@ public class AppWidgetManager { /** * This bundle extra describes which views have been scrolled during a single impression of the * widget. It is an integer array of view IDs of the scrolled views. * widget. It is an integer array of view IDs of the scrolled views. The array may contain up to * 10 distinct IDs per event. * * Widget providers may set a different ID for event purposes by setting the * {@link android.R.id.remoteViewsMetricsId} int tag on the view. * Widget providers may set a different ID for event logging by setting the usage event tag on * the view with {@link RemoteViews#setUsageEventTag}. * * @see android.views.RemoteViews.setIntTag * @see android.widget.RemoteViews#setUsageEventTag */ @FlaggedApi(Flags.FLAG_ENGAGEMENT_METRICS) public static final String EXTRA_EVENT_SCROLLED_VIEWS = Loading
core/java/android/widget/RemoteViews.java +57 −1 Original line number Diff line number Diff line Loading @@ -547,6 +547,25 @@ public class RemoteViews implements Parcelable, Filter { addAction(new SetIntTagAction(viewId, key, tag)); } /** * Set a view tag associating a View with an ID to be used for widget interaction usage events * ({@link android.app.usage.UsageEvents.Event}). When this RemoteViews is applied to a bound * widget, any clicks or scrolls on the tagged view will be reported to * {@link android.app.usage.UsageStatsManager} using this tag. * * @param viewId ID of the View whose tag will be set * @param tag The integer tag to use for the event * * @see android.appwidget.AppWidgetManager#EVENT_TYPE_WIDGET_INTERACTION * @see android.appwidget.AppWidgetManager#EXTRA_EVENT_CLICKED_VIEWS * @see android.appwidget.AppWidgetManager#EXTRA_EVENT_SCROLLED_VIEWS * @see android.app.usage.UsageStatsManager#queryEventsForSelf */ @FlaggedApi(Flags.FLAG_ENGAGEMENT_METRICS) public void setUsageEventTag(@IdRes int viewId, int tag) { addAction(new SetIntTagAction(viewId, com.android.internal.R.id.remoteViewsMetricsId, tag)); } /** * Set that it is disallowed to reapply another remoteview with the same layout as this view. * This should be done if an action is destroying the view tree of the base layout. Loading Loading @@ -666,6 +685,14 @@ public class RemoteViews implements Parcelable, Filter { View view, PendingIntent pendingIntent, RemoteResponse response); /** * Invoked when an AbsListView is scrolled. * @param view view that was scrolled * * @hide */ default void onScroll(@NonNull AbsListView view) {} } /** Loading Loading @@ -1313,6 +1340,21 @@ public class RemoteViews implements Parcelable, Filter { // a type error. throw new ActionException(throwable); } if (adapterView instanceof AbsListView listView) { listView.setOnScrollListener(new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { if (scrollState != SCROLL_STATE_IDLE) { params.handler.onScroll(view); } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { } }); } } @Override Loading Loading @@ -1804,6 +1846,19 @@ public class RemoteViews implements Parcelable, Filter { AbsListView v = (AbsListView) target; v.setRemoteViewsAdapter(mIntent, mIsAsync); v.setRemoteViewsInteractionHandler(params.handler); v.setOnScrollListener(new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { if (scrollState != SCROLL_STATE_IDLE) { params.handler.onScroll(view); } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { } }); } else if (target instanceof AdapterViewAnimator) { AdapterViewAnimator v = (AdapterViewAnimator) target; v.setRemoteViewsAdapter(mIntent, mIsAsync); Loading Loading @@ -1894,7 +1949,8 @@ public class RemoteViews implements Parcelable, Filter { target.setTagInternal(com.android.internal.R.id.fillInIntent, null); return; } target.setOnClickListener(v -> mResponse.handleViewInteraction(v, params.handler)); target.setOnClickListener(v -> mResponse.handleViewInteraction(v, params.handler)); } @Override Loading
core/res/res/values/public-staging.xml +1 −1 Original line number Diff line number Diff line Loading @@ -128,7 +128,7 @@ <staging-public-group type="id" first-id="0x01b20000"> <!-- @FlaggedApi(android.appwidget.flags.Flags.FLAG_ENGAGEMENT_METRICS) --> <public name="remoteViewsMetricsId"/> <public name="removed_remoteViewsMetricsId"/> <!-- @FlaggedApi("android.view.accessibility.a11y_selection_api") --> <public name="accessibilityActionSetExtendedSelection"/> </staging-public-group> Loading