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

Commit 77b81d1d authored by Willie Koomson's avatar Willie Koomson
Browse files

Add AppWidgetManager.queryAppWidgetEvents API

This changes add queryAppWidgetEvents API to query widget interaction
events for widgets provided by the calling process. Internally, it uses
UsageStatsManager to query usage events.

Bug: 364655296
Test: CtsAppWidgetTestCases:WidgetEventsTest
Flag: android.appwidget.flags.engagement_metrics
Change-Id: I922caf67366bcb9ec21442f4689167d39623288b
parent 45dea56c
Loading
Loading
Loading
Loading
+15 −7
Original line number Diff line number Diff line
@@ -10096,6 +10096,19 @@ package android.app.wallpaper {
package android.appwidget {
  @FlaggedApi("android.appwidget.flags.engagement_metrics") public final class AppWidgetEvent implements android.os.Parcelable {
    method public int describeContents();
    method public int getAppWidgetId();
    method @Nullable public int[] getClickedIds();
    method @NonNull public java.time.Instant getEnd();
    method @Nullable public android.graphics.Rect getPosition();
    method @Nullable public int[] getScrolledIds();
    method @NonNull public java.time.Instant getStart();
    method @NonNull public java.time.Duration getVisibleDuration();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.appwidget.AppWidgetEvent> CREATOR;
  }
  public class AppWidgetHost {
    ctor public AppWidgetHost(android.content.Context, int);
    method public int allocateAppWidgetId();
@@ -10153,6 +10166,7 @@ package android.appwidget {
    method @Deprecated public void notifyAppWidgetViewDataChanged(int, int);
    method public void partiallyUpdateAppWidget(int[], android.widget.RemoteViews);
    method public void partiallyUpdateAppWidget(int, android.widget.RemoteViews);
    method @FlaggedApi("android.appwidget.flags.engagement_metrics") @NonNull public java.util.List<android.appwidget.AppWidgetEvent> queryAppWidgetEvents(long, long);
    method @FlaggedApi("android.appwidget.flags.generated_previews") public void removeWidgetPreview(@NonNull android.content.ComponentName, int);
    method public boolean requestPinAppWidget(@NonNull android.content.ComponentName, @Nullable android.os.Bundle, @Nullable android.app.PendingIntent);
    method @FlaggedApi("android.appwidget.flags.generated_previews") public boolean setWidgetPreview(@NonNull android.content.ComponentName, int, @NonNull android.widget.RemoteViews);
@@ -10171,8 +10185,6 @@ package android.appwidget {
    field public static final String ACTION_APPWIDGET_PICK = "android.appwidget.action.APPWIDGET_PICK";
    field public static final String ACTION_APPWIDGET_RESTORED = "android.appwidget.action.APPWIDGET_RESTORED";
    field public static final String ACTION_APPWIDGET_UPDATE = "android.appwidget.action.APPWIDGET_UPDATE";
    field @FlaggedApi("android.appwidget.flags.engagement_metrics") public static final String EVENT_CATEGORY_APPWIDGET = "android.appwidget";
    field @FlaggedApi("android.appwidget.flags.engagement_metrics") public static final String EVENT_TYPE_WIDGET_INTERACTION = "widget_interaction";
    field public static final String EXTRA_APPWIDGET_ID = "appWidgetId";
    field public static final String EXTRA_APPWIDGET_IDS = "appWidgetIds";
    field public static final String EXTRA_APPWIDGET_OLD_IDS = "appWidgetOldIds";
@@ -10182,10 +10194,6 @@ package android.appwidget {
    field public static final String EXTRA_APPWIDGET_PROVIDER_PROFILE = "appWidgetProviderProfile";
    field public static final String EXTRA_CUSTOM_EXTRAS = "customExtras";
    field public static final String EXTRA_CUSTOM_INFO = "customInfo";
    field @FlaggedApi("android.appwidget.flags.engagement_metrics") public static final String EXTRA_EVENT_CLICKED_VIEWS = "android.appwidget.extra.EVENT_CLICKED_VIEWS";
    field @FlaggedApi("android.appwidget.flags.engagement_metrics") public static final String EXTRA_EVENT_DURATION_MS = "android.appwidget.extra.EVENT_DURATION_MS";
    field @FlaggedApi("android.appwidget.flags.engagement_metrics") public static final String EXTRA_EVENT_POSITION_RECT = "android.appwidget.extra.EVENT_POSITION_RECT";
    field @FlaggedApi("android.appwidget.flags.engagement_metrics") public static final String EXTRA_EVENT_SCROLLED_VIEWS = "android.appwidget.extra.EVENT_SCROLLED_VIEWS";
    field public static final String EXTRA_HOST_ID = "hostId";
    field public static final int INVALID_APPWIDGET_ID = 0; // 0x0
    field public static final String META_DATA_APPWIDGET_PROVIDER = "android.appwidget.provider";
@@ -62136,6 +62144,7 @@ package android.widget {
    method public void removeAllViews(@IdRes int);
    method public void setAccessibilityTraversalAfter(@IdRes int, @IdRes int);
    method public void setAccessibilityTraversalBefore(@IdRes int, @IdRes int);
    method @FlaggedApi("android.appwidget.flags.engagement_metrics") public void setAppWidgetEventTag(@IdRes int, int);
    method public void setBitmap(@IdRes int, String, android.graphics.Bitmap);
    method public void setBlendMode(@IdRes int, @NonNull String, @Nullable android.graphics.BlendMode);
    method public void setBoolean(@IdRes int, String, boolean);
@@ -62198,7 +62207,6 @@ 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);
+151 −32
Original line number Diff line number Diff line
@@ -21,30 +21,38 @@ import static android.appwidget.flags.Flags.FLAG_ENGAGEMENT_METRICS;
import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStatsManager;
import android.graphics.Rect;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.PersistableBundle;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.ArraySet;

import java.time.Duration;
import java.time.Instant;
import java.util.Arrays;

/**
 * An immutable class that describes the event data for an app widget interaction event.
 *
 * @hide
 */
@FlaggedApi(FLAG_ENGAGEMENT_METRICS)
public class AppWidgetEvent implements Parcelable {
public final class AppWidgetEvent implements Parcelable {
    /**
     * Max number of clicked and scrolled IDs stored per event.
     * @hide
     */
    public static final int MAX_NUM_ITEMS = 10;

    private final int mAppWidgetId;
    private final long mDurationMs;
    @NonNull
    private final Duration mVisibleDuration;
    @NonNull
    private final Instant mStart;
    @NonNull
    private final Instant mEnd;
    @Nullable
    private final Rect mPosition;
    @Nullable
@@ -54,22 +62,42 @@ public class AppWidgetEvent implements Parcelable {

    /**
     * The app widget ID of the widget that generated this event.
     *
     * @see AppWidgetManager#getAppWidgetInfo(int)
     */
    public int getAppWidgetId() {
        return mAppWidgetId;
    }

    /**
     * This contains a long that represents the duration of time in milliseconds during which the
     * widget was visible.
     * Describes the total duration of time during which the widget was visible. This may be
     * different than the event time range (between {@link #getStart()} and {@link #getEnd()} if the
     * widget was hidden and shown multiple times during the event time range.
     */
    public long getDurationMs() {
        return mDurationMs;
    @NonNull
    public Duration getVisibleDuration() {
        return mVisibleDuration;
    }

    /**
     * This rect with describes the global coordinates of the widget at the end of the interaction
     * event.
     * Describes the start of the time range that this event contains data for.
     */
    @NonNull
    public Instant getStart() {
        return mStart;
    }

    /**
     * Describes the end of the time range that this event contains data for.
     */
    @NonNull
    public Instant getEnd() {
        return mEnd;
    }

    /**
     * This rect with describes the global coordinates of the widget at the end of the event time
     * range.
     */
    @Nullable
    public Rect getPosition() {
@@ -77,7 +105,10 @@ public class AppWidgetEvent implements Parcelable {
    }

    /**
     * This describes which views have been clicked during a single impression of the widget.
     * This returns the set of View IDs of the views which have been clicked during the event time
     * range. Use {@link android.widget.RemoteViews#setAppWidgetEventTag(int, int)} to set a custom
     * integer tag on a view for reporting clicks. If the tag is set, it will be used here instead
     * of the View ID.
     */
    @Nullable
    public int[] getClickedIds() {
@@ -85,18 +116,23 @@ public class AppWidgetEvent implements Parcelable {
    }

    /**
     * This describes which views have been scrolled during a single impression of the widget.
     * This returns the set of View IDs of the views which have been scrolled during the event time
     * range. Use {@link android.widget.RemoteViews#setAppWidgetEventTag(int, int)} to set a custom
     * integer tag on a view for reporting scrolls. If the tag is set, it will be used here instead
     * of the View ID.
     */
    @Nullable
    public int[] getScrolledIds() {
        return mScrolledIds;
    }

    private AppWidgetEvent(int appWidgetId, long durationMs,
            @Nullable Rect position, @Nullable int[] clickedIds,
            @Nullable int[] scrolledIds) {
    private AppWidgetEvent(int appWidgetId, @NonNull Duration visibleDuration,
            @NonNull Instant start, @NonNull Instant end, @Nullable Rect position,
            @Nullable int[] clickedIds, @Nullable int[] scrolledIds) {
        mAppWidgetId = appWidgetId;
        mDurationMs = durationMs;
        mVisibleDuration = visibleDuration;
        mStart = start;
        mEnd = end;
        mPosition = position;
        mClickedIds = clickedIds;
        mScrolledIds = scrolledIds;
@@ -105,18 +141,22 @@ public class AppWidgetEvent implements Parcelable {
    /**
     * Unflatten the AppWidgetEvent from a parcel.
     */
    private AppWidgetEvent(Parcel in) {
    private AppWidgetEvent(@NonNull Parcel in) {
        mAppWidgetId = in.readInt();
        mDurationMs = in.readLong();
        mVisibleDuration = Duration.ofMillis(in.readLong());
        mStart = Instant.ofEpochMilli(in.readLong());
        mEnd = Instant.ofEpochMilli(in.readLong());
        mPosition = in.readTypedObject(Rect.CREATOR);
        mClickedIds = in.createIntArray();
        mScrolledIds = in.createIntArray();
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
    public void writeToParcel(@NonNull Parcel out, int flags) {
        out.writeInt(mAppWidgetId);
        out.writeLong(mDurationMs);
        out.writeLong(mVisibleDuration.toMillis());
        out.writeLong(mStart.toEpochMilli());
        out.writeLong(mEnd.toEpochMilli());
        out.writeTypedObject(mPosition, flags);
        out.writeIntArray(mClickedIds);
        out.writeIntArray(mScrolledIds);
@@ -143,6 +183,7 @@ public class AppWidgetEvent implements Parcelable {

    /**
     * Create a PersistableBundle that represents this event.
     * @hide
     */
    @NonNull
    public PersistableBundle toBundle() {
@@ -152,7 +193,9 @@ public class AppWidgetEvent implements Parcelable {
        extras.putString(UsageStatsManager.EXTRA_EVENT_CATEGORY,
                AppWidgetManager.EVENT_CATEGORY_APPWIDGET);
        extras.putInt(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
        extras.putLong(AppWidgetManager.EXTRA_EVENT_DURATION_MS, mDurationMs);
        extras.putLong(AppWidgetManager.EXTRA_EVENT_DURATION_MS, mVisibleDuration.toMillis());
        extras.putLong(AppWidgetManager.EXTRA_EVENT_START, mStart.toEpochMilli());
        extras.putLong(AppWidgetManager.EXTRA_EVENT_END, mEnd.toEpochMilli());
        if (mPosition != null) {
            extras.putIntArray(AppWidgetManager.EXTRA_EVENT_POSITION_RECT,
                new int[]{mPosition.left, mPosition.top, mPosition.right, mPosition.bottom});
@@ -166,11 +209,56 @@ public class AppWidgetEvent implements Parcelable {
        return extras;
    }

    /**
     * Create an AppWidgetEvent from a {@link UsageEvents.Event}.
     * @hide
     */
    @NonNull
    public static AppWidgetEvent fromUsageEvent(@NonNull UsageEvents.Event usageEvent) {
        PersistableBundle extras = usageEvent.getExtras();
        int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,
                AppWidgetManager.INVALID_APPWIDGET_ID);
        Duration duration = Duration.ofMillis(extras.getLong(
                AppWidgetManager.EXTRA_EVENT_DURATION_MS, 0L));
        Instant start = Instant.ofEpochMilli(extras.getLong(AppWidgetManager.EXTRA_EVENT_START,
                0L));
        Instant end = Instant.ofEpochMilli(extras.getLong(AppWidgetManager.EXTRA_EVENT_END, 0L));
        Rect position = null;
        int[] clickedIds = null;
        int[] scrolledIds = null;
        if (extras.containsKey(AppWidgetManager.EXTRA_EVENT_POSITION_RECT)) {
            int[] positionArray = extras.getIntArray(AppWidgetManager.EXTRA_EVENT_POSITION_RECT);
            if (positionArray != null && positionArray.length == 4) {
                position = new Rect(positionArray[0], positionArray[1], positionArray[2],
                        positionArray[3]);
            }
        }
        if (extras.containsKey(AppWidgetManager.EXTRA_EVENT_CLICKED_VIEWS)) {
            clickedIds = extras.getIntArray(AppWidgetManager.EXTRA_EVENT_CLICKED_VIEWS);
        }
        if (extras.containsKey(AppWidgetManager.EXTRA_EVENT_SCROLLED_VIEWS)) {
            scrolledIds = extras.getIntArray(AppWidgetManager.EXTRA_EVENT_SCROLLED_VIEWS);
        }
        return new AppWidgetEvent(appWidgetId, duration, start, end, position, clickedIds,
            scrolledIds);
    }

    @Override
    public String toString() {
        return TextUtils.formatSimple("AppWidgetEvent(appWidgetId=%d, durationMs=%d, position=%s,"
                + " clickedIds=%s, scrolledIds=%s)", mAppWidgetId, mDurationMs, mPosition,
            Arrays.toString(mClickedIds), Arrays.toString(mScrolledIds));
        return TextUtils.formatSimple("AppWidgetEvent(appWidgetId=%d, duration=%s, start=%s, "
                + "end=%s position=%s, clickedIds=%s, scrolledIds=%s)", mAppWidgetId,
            mVisibleDuration, mStart, mEnd, mPosition, Arrays.toString(mClickedIds),
            Arrays.toString(mScrolledIds));
    }

    /**
     * Returns true if the given {@link UsageEvents.Event} contains an app widget interaction event.
     * @hide
     */
    public static boolean isAppWidgetEvent(@NonNull UsageEvents.Event event) {
        return event.getEventType() == UsageEvents.Event.USER_INTERACTION
            && event.getExtras().getString(UsageStatsManager.EXTRA_EVENT_ACTION).equals(
                AppWidgetManager.EVENT_TYPE_WIDGET_INTERACTION);
    }

    /**
@@ -184,7 +272,10 @@ public class AppWidgetEvent implements Parcelable {
        @NonNull
        private final ArraySet<Integer> mScrolledIds = new ArraySet<>(MAX_NUM_ITEMS);
        private int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
        private long mDurationMs = 0;
        private Instant mStart = Instant.MAX;
        private Instant mEnd = Instant.MIN;
        private Duration mDuration = Duration.ZERO;
        private long mLastVisibilityChangeMillis = 0L;
        @Nullable
        private Rect mPosition = null;

@@ -196,8 +287,28 @@ public class AppWidgetEvent implements Parcelable {
            return this;
        }

        public Builder addDurationMs(long durationMs) {
            mDurationMs += durationMs;
        /**
         * Start a new visibility duration for this event.
         */
        public Builder startVisibility() {
            Instant now = Instant.now();
            if (now.isBefore(mStart)) {
                mStart = now;
            }
            mLastVisibilityChangeMillis = SystemClock.uptimeMillis();
            return this;
        }

        /**
         * End the visibility duration, and add the duration to this event's total duration.
         */
        public Builder endVisibility() {
            Instant now = Instant.now();
            if (now.isAfter(mEnd)) {
                mEnd = now;
            }
            mDuration = mDuration.plusMillis(
                SystemClock.uptimeMillis() - mLastVisibilityChangeMillis);
            return this;
        }

@@ -234,7 +345,13 @@ public class AppWidgetEvent implements Parcelable {
                throw new IllegalArgumentException("Trying to merge events with different app "
                    + "widget IDs: " + mAppWidgetId + " != " + event.getAppWidgetId());
            }
            addDurationMs(event.getDurationMs());
            if (event.getStart().isBefore(mStart)) {
                mStart = event.getStart();
            }
            if (event.getEnd().isAfter(mEnd)) {
                mEnd = event.getEnd();
            }
            mDuration = mDuration.plus(event.getVisibleDuration());
            setPosition(event.getPosition());
            addAllUntilMax(mClickedIds, event.getClickedIds());
            addAllUntilMax(mScrolledIds, event.getScrolledIds());
@@ -245,22 +362,24 @@ public class AppWidgetEvent implements Parcelable {
         * event yet.
         */
        public boolean isEmpty() {
            return mAppWidgetId <= 0 || mDurationMs == 0L;
            return mAppWidgetId <= 0 || mDuration.isZero();
        }

        /**
         * Resets the event data fields.
         */
        public void clear() {
            mDurationMs = 0;
            mDuration = Duration.ZERO;
            mStart = Instant.MAX;
            mEnd = Instant.MIN;
            mPosition = null;
            mClickedIds.clear();
            mScrolledIds.clear();
        }

        public AppWidgetEvent build() {
            return new AppWidgetEvent(mAppWidgetId, mDurationMs, mPosition, toIntArray(mClickedIds),
                toIntArray(mScrolledIds));
            return new AppWidgetEvent(mAppWidgetId, mDuration, mStart, mEnd, mPosition,
                    toIntArray(mClickedIds), toIntArray(mScrolledIds));
        }

        private static void addAllUntilMax(@NonNull ArraySet<Integer> set, @Nullable int[] toAdd) {
+2 −5
Original line number Diff line number Diff line
@@ -44,7 +44,6 @@ import android.os.Build;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.Parcelable;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Pair;
@@ -1115,8 +1114,6 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW
        private final AppWidgetEvent.Builder mEvent = new AppWidgetEvent.Builder();
        @Nullable
        private RemoteViews.InteractionHandler mInteractionHandler = null;
        // Last time the widget became visible in SystemClock.uptimeMillis()
        private long mVisibilityChangeMs = 0L;
        private boolean mIsVisible = false;
        private boolean mIsTracking = false;

@@ -1244,11 +1241,11 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW
            boolean isVisible = isTracking && hasWindowFocus() && isVisibleToUser();
            if (!wasVisible && isVisible) {
                // View has become visible, start the tracker.
                mVisibilityChangeMs = SystemClock.uptimeMillis();
                mEvent.startVisibility();
                if (LOGD) Log.d(TAG, logName() + " became visible");
            } else if (wasVisible && !isVisible) {
                // View is no longer visible, add duration.
                mEvent.addDurationMs(SystemClock.uptimeMillis() - mVisibilityChangeMs);
                mEvent.endVisibility();
                if (LOGD) Log.d(TAG, logName() + " lost visibility");
            }

+55 −9
Original line number Diff line number Diff line
@@ -499,13 +499,15 @@ public class AppWidgetManager {
     *
     * A single widget interaction event describes what user interactions happened during a single
     * impression of the widget.
     * @hide
     */
    @FlaggedApi(Flags.FLAG_ENGAGEMENT_METRICS)
    public static final String EVENT_TYPE_WIDGET_INTERACTION = "widget_interaction";
    static final String EVENT_TYPE_WIDGET_INTERACTION = "widget_interaction";

    /**
     * This is the value of {@link UsageStatsManager.EXTRA_EVENT_CATEGORY} in the event bundle for
     * widget user interaction events.
     * @hide
     */
    @FlaggedApi(Flags.FLAG_ENGAGEMENT_METRICS)
    public static final String EVENT_CATEGORY_APPWIDGET = "android.appwidget";
@@ -516,12 +518,13 @@ public class AppWidgetManager {
     * 10 distinct IDs per event.
     *
     * Widget providers may set a different ID for event logging by setting the usage event tag on
     * the view with {@link RemoteViews#setUsageEventTag}.
     * the view with {@link RemoteViews#setAppWidgetEventTag}.
     *
     * @see android.widget.RemoteViews#setUsageEventTag
     * @see android.widget.RemoteViews#setAppWidgetEventTag
     * @hide
     */
    @FlaggedApi(Flags.FLAG_ENGAGEMENT_METRICS)
    public static final String EXTRA_EVENT_CLICKED_VIEWS =
    static final String EXTRA_EVENT_CLICKED_VIEWS =
            "android.appwidget.extra.EVENT_CLICKED_VIEWS";

    /**
@@ -530,20 +533,22 @@ public class AppWidgetManager {
     * 10 distinct IDs per event.
     *
     * Widget providers may set a different ID for event logging by setting the usage event tag on
     * the view with {@link RemoteViews#setUsageEventTag}.
     * the view with {@link RemoteViews#setAppWidgetEventTag}.
     *
     * @see android.widget.RemoteViews#setUsageEventTag
     * @see android.widget.RemoteViews#setAppWidgetEventTag
     * @hide
     */
    @FlaggedApi(Flags.FLAG_ENGAGEMENT_METRICS)
    public static final String EXTRA_EVENT_SCROLLED_VIEWS =
    static final String EXTRA_EVENT_SCROLLED_VIEWS =
            "android.appwidget.extra.EVENT_SCROLLED_VIEWS";

    /**
     * This bundle extra contains a long that represents the duration of time in milliseconds
     * during which the widget was visible.
     * @hide
     */
    @FlaggedApi(Flags.FLAG_ENGAGEMENT_METRICS)
    public static final String EXTRA_EVENT_DURATION_MS =
    static final String EXTRA_EVENT_DURATION_MS =
            "android.appwidget.extra.EVENT_DURATION_MS";

    /**
@@ -551,11 +556,28 @@ public class AppWidgetManager {
     * right, and bottom coordinates of the widget at the end of the interaction event.
     *
     * This Rect indicates the current position and size of the widget.
     * @hide
     */
    @FlaggedApi(Flags.FLAG_ENGAGEMENT_METRICS)
    public static final String EXTRA_EVENT_POSITION_RECT =
    static final String EXTRA_EVENT_POSITION_RECT =
            "android.appwidget.extra.EVENT_POSITION_RECT";

    /**
     * This bundle extra contains a long that describes the start (in epoch milliseconds) of the
     * time range that this event represents.
     * @hide
     */
    @FlaggedApi(Flags.FLAG_ENGAGEMENT_METRICS)
    static final String EXTRA_EVENT_START = "android.appwidget.extra.EVENT_START";

    /**
     * This bundle extra contains a long that describes the end (in epoch milliseconds) of the time
     * range that this event represents.
     * @hide
     */
    @FlaggedApi(Flags.FLAG_ENGAGEMENT_METRICS)
    static final String EXTRA_EVENT_END = "android.appwidget.extra.EVENT_END";

    private static final String TAG = "AppWidgetManager";

    private static Executor sUpdateExecutor;
@@ -1642,6 +1664,30 @@ public class AppWidgetManager {
        }
    }

    /**
     * Query for app widget interaction events in the given time range. Events are only kept by the
     * system for a few days. This method only returns events for widgets provided by the calling
     * package and does not require any additional permissions.
     *
     * @param beginTime The inclusive beginning of the range of events to include in the results.
     *                  Defined in terms of "Unix time", see
     *                  {@link java.lang.System#currentTimeMillis}.
     * @param endTime The exclusive end of the range of events to include in the results. Defined
     *                in terms of "Unix time", see {@link java.lang.System#currentTimeMillis}.
     * @return An array of {@link AppWidgetEvent} objects.
     */
    @FlaggedApi(Flags.FLAG_ENGAGEMENT_METRICS)
    @NonNull
    public List<AppWidgetEvent> queryAppWidgetEvents(long beginTime, long endTime) {
        try {
            ParceledListSlice<AppWidgetEvent> events = mService.queryAppWidgetEvents(mPackageName,
                    beginTime, endTime);
            return events != null ? events.getList() : Collections.emptyList();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    @UiThread
    private static @NonNull Executor createUpdateExecutorIfNull() {
        if (sUpdateExecutor == null) {
+6 −7
Original line number Diff line number Diff line
@@ -542,20 +542,19 @@ public class RemoteViews implements Parcelable, Filter {

    /**
     * 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
     * ({@link android.appwidget.AppWidgetEvent}). 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.
     * {@link android.appwidget.AppWidgetManager} 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
     * @see android.appwidget.AppWidgetEvent#getClickedIds
     * @see android.appwidget.AppWidgetEvent#getScrolledIds
     * @see android.appwidget.AppWidgetManager#queryAppWidgetEvents
     */
    @FlaggedApi(Flags.FLAG_ENGAGEMENT_METRICS)
    public void setUsageEventTag(@IdRes int viewId, int tag) {
    public void setAppWidgetEventTag(@IdRes int viewId, int tag) {
        addAction(new SetIntTagAction(viewId, com.android.internal.R.id.remoteViewsMetricsId, tag));
    }

Loading