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

Commit 31817bfe authored by Xin Guan's avatar Xin Guan Committed by Android (Google) Code Review
Browse files

Merge "Introduce user interaction usage events reporting" into main

parents 10ac77c7 751214da
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -9342,6 +9342,7 @@ package android.app.usage {
    method public String getClassName();
    method public android.content.res.Configuration getConfiguration();
    method public int getEventType();
    method @FlaggedApi("android.app.usage.user_interaction_type_api") @NonNull public android.os.PersistableBundle getExtras();
    method public String getPackageName();
    method public String getShortcutId();
    method public long getTimeStamp();
@@ -9407,6 +9408,8 @@ package android.app.usage {
    method @FlaggedApi("android.app.usage.filter_based_event_query_api") @NonNull @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public android.app.usage.UsageEvents queryEvents(@NonNull android.app.usage.UsageEventsQuery);
    method public android.app.usage.UsageEvents queryEventsForSelf(long, long);
    method public java.util.List<android.app.usage.UsageStats> queryUsageStats(int, long, long);
    field @FlaggedApi("android.app.usage.user_interaction_type_api") public static final String EXTRA_EVENT_ACTION = "android.app.usage.extra.EVENT_ACTION";
    field @FlaggedApi("android.app.usage.user_interaction_type_api") public static final String EXTRA_EVENT_CATEGORY = "android.app.usage.extra.EVENT_CATEGORY";
    field public static final int INTERVAL_BEST = 4; // 0x4
    field public static final int INTERVAL_DAILY = 0; // 0x0
    field public static final int INTERVAL_MONTHLY = 2; // 0x2
+3 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.app.usage.BroadcastResponseStatsList;
import android.app.usage.UsageEvents;
import android.app.usage.UsageEventsQuery;
import android.content.pm.ParceledListSlice;
import android.os.PersistableBundle;

/**
 * System private API for talking with the UsageStatsManagerService.
@@ -77,6 +78,8 @@ interface IUsageStatsManager {
            String callingPackage);
    void reportUsageStop(in IBinder activity, String token, String callingPackage);
    void reportUserInteraction(String packageName, int userId);
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.REPORT_USAGE_STATS)")
    void reportUserInteractionWithBundle(String packageName, int userId, in PersistableBundle eventExtras);
    int getUsageSource();
    void forceUsageSourceSettingRead();
    long getLastTimeAnyComponentUsed(String packageName, String callingPackage);
+14 −0
Original line number Diff line number Diff line
@@ -223,6 +223,7 @@ public final class ParcelableUsageEventList implements Parcelable {
        event.mContentAnnotations = null;
        event.mNotificationChannelId = null;
        event.mLocusId = null;
        event.mExtras = null;

        switch (event.mEventType) {
            case Event.CONFIGURATION_CHANGE -> {
@@ -237,6 +238,11 @@ public final class ParcelableUsageEventList implements Parcelable {
            case Event.STANDBY_BUCKET_CHANGED -> event.mBucketAndReason = in.readInt();
            case Event.NOTIFICATION_INTERRUPTION -> event.mNotificationChannelId = in.readString();
            case Event.LOCUS_ID_SET -> event.mLocusId = in.readString();
            case Event.USER_INTERACTION -> {
                if (in.readInt() != 0) {
                    event.mExtras = in.readPersistableBundle(getClass().getClassLoader());
                }
            }
        }
        event.mFlags = in.readInt();

@@ -263,6 +269,14 @@ public final class ParcelableUsageEventList implements Parcelable {
            case Event.STANDBY_BUCKET_CHANGED -> dest.writeInt(event.mBucketAndReason);
            case Event.NOTIFICATION_INTERRUPTION -> dest.writeString(event.mNotificationChannelId);
            case Event.LOCUS_ID_SET -> dest.writeString(event.mLocusId);
            case Event.USER_INTERACTION -> {
                if (event.mExtras != null) {
                    dest.writeInt(1);
                    dest.writePersistableBundle(event.mExtras);
                } else {
                    dest.writeInt(0);
                }
            }
        }
        dest.writeInt(event.mFlags);
    }
+49 −0
Original line number Diff line number Diff line
@@ -16,7 +16,9 @@
package android.app.usage;

import android.annotation.CurrentTimeMillisLong;
import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
@@ -24,6 +26,7 @@ import android.content.res.Configuration;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.PersistableBundle;
import android.util.Log;

import java.lang.annotation.Retention;
@@ -550,6 +553,22 @@ public final class UsageEvents implements Parcelable {
         */
        public int mLocusIdToken = UNASSIGNED_TOKEN;

        /** @hide */
        public PersistableBundle mExtras = null;

        /** @hide */
        public static class UserInteractionEventExtrasToken {
            public int mCategoryToken = UNASSIGNED_TOKEN;
            public int mActionToken = UNASSIGNED_TOKEN;

            public UserInteractionEventExtrasToken() {
                // Do nothing.
            }
        }

        /** @hide */
        public UserInteractionEventExtrasToken mUserInteractionExtrasToken = null;

        /** @hide */
        @EventFlags
        public int mFlags;
@@ -649,6 +668,21 @@ public final class UsageEvents implements Parcelable {
            return mEventType;
        }

        /**
         * Retrieves a map of extended data from the event if the event is of type
         * {@link #USER_INTERACTION}.
         *
         * @return the map of all extras that associated with the reported user interaction
         *         event. The returned {@link PersistableBundle} will contain the extras
         *         {@link UsageStatsManager#EXTRA_EVENT_CATEGORY} and
         *         {@link UsageStatsManager#EXTRA_EVENT_ACTION}. {@link PersistableBundle#EMPTY}
         *         will be returned if the details are not available.
         */
        @FlaggedApi(Flags.FLAG_USER_INTERACTION_TYPE_API)
        public @NonNull PersistableBundle getExtras() {
            return mExtras == null ? PersistableBundle.EMPTY : mExtras;
        }

        /**
         * Returns a {@link Configuration} for this event if the event is of type
         * {@link #CONFIGURATION_CHANGE}, otherwise it returns null.
@@ -747,6 +781,7 @@ public final class UsageEvents implements Parcelable {
            mBucketAndReason = orig.mBucketAndReason;
            mNotificationChannelId = orig.mNotificationChannelId;
            mLocusId = orig.mLocusId;
            mExtras = orig.mExtras;
        }
    }

@@ -987,6 +1022,14 @@ public final class UsageEvents implements Parcelable {
            case Event.LOCUS_ID_SET:
                p.writeString(event.mLocusId);
                break;
            case Event.USER_INTERACTION:
                if (event.mExtras != null) {
                    p.writeInt(1);
                    p.writePersistableBundle(event.mExtras);
                } else {
                    p.writeInt(0);
                }
                break;
        }
        p.writeInt(event.mFlags);
    }
@@ -1036,6 +1079,7 @@ public final class UsageEvents implements Parcelable {
        eventOut.mContentAnnotations = null;
        eventOut.mNotificationChannelId = null;
        eventOut.mLocusId = null;
        eventOut.mExtras = null;

        switch (eventOut.mEventType) {
            case Event.CONFIGURATION_CHANGE:
@@ -1059,6 +1103,11 @@ public final class UsageEvents implements Parcelable {
            case Event.LOCUS_ID_SET:
                eventOut.mLocusId = p.readString();
                break;
            case Event.USER_INTERACTION:
                if (p.readInt() != 0) {
                    eventOut.mExtras = p.readPersistableBundle(getClass().getClassLoader());
                }
                break;
        }
        eventOut.mFlags = p.readInt();
    }
+58 −6
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
import android.annotation.UserHandleAware;
import android.annotation.UserIdInt;
import android.app.Activity;
import android.app.BroadcastOptions;
import android.app.PendingIntent;
@@ -35,6 +36,7 @@ import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.pm.ParceledListSlice;
import android.os.Build;
import android.os.PersistableBundle;
import android.os.PowerWhitelistManager;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -392,6 +394,23 @@ public final class UsageStatsManager {
    @SystemApi
    public static final String EXTRA_TIME_USED = "android.app.usage.extra.TIME_USED";

    /**
     * A String extra, when used with {@link UsageEvents.Event#getExtras}, that indicates
     * the category of the user interaction associated with the event. The category cannot
     * be more than 127 characters, longer value will be truncated to 127 characters.
     */
    @FlaggedApi(Flags.FLAG_USER_INTERACTION_TYPE_API)
    public static final String EXTRA_EVENT_CATEGORY =
            "android.app.usage.extra.EVENT_CATEGORY";

    /**
     * A String extra, when used with {@link UsageEvents.Event#getExtras}, that indicates
     * the action of the user interaction associated with the event. The action cannot be
     * more than 127 characters, longer value will be truncated to 127 characters.
     */
    @FlaggedApi(Flags.FLAG_USER_INTERACTION_TYPE_API)
    public static final String EXTRA_EVENT_ACTION =
            "android.app.usage.extra.EVENT_ACTION";

    /**
     * App usage observers will consider the task root package the source of usage.
@@ -1128,6 +1147,7 @@ public final class UsageStatsManager {
     * Reports user interaction with a given package in the given user.
     *
     * <p><em>This method is only for use by the system</em>
     *
     * @hide
     */
    @RequiresPermission(android.Manifest.permission.REPORT_USAGE_STATS)
@@ -1139,6 +1159,38 @@ public final class UsageStatsManager {
        }
    }

    /**
     * Reports user interaction with given package and a particular {@code extras}
     * in the given user.
     *
     * <p>
     * Note: The structure of {@code extras} is a {@link PersistableBundle} with the
     * category {@link #EXTRA_EVENT_CATEGORY} and the action {@link #EXTRA_EVENT_ACTION}.
     * Category provides additional detail about the user interaction, the value
     * is defined in namespace based. Example: android.app.notification could be used to
     * indicate that the reported user interaction is related to notification. Action
     * indicates the general action that performed.
     * </p>
     *
     * @param packageName The package name of the app
     * @param userId The user id who triggers the user interaction
     * @param extras The {@link PersistableBundle} that will be used to specify the
     *               extra details for the user interaction event. The {@link PersistableBundle}
     *               must contain the extras {@link #EXTRA_EVENT_CATEGORY},
     *               {@link #EXTRA_EVENT_ACTION}. Cannot be empty.
     * @hide
     */
    @FlaggedApi(Flags.FLAG_USER_INTERACTION_TYPE_API)
    @RequiresPermission(android.Manifest.permission.REPORT_USAGE_STATS)
    public void reportUserInteraction(@NonNull String packageName, @UserIdInt int userId,
            @NonNull PersistableBundle extras) {
        try {
            mService.reportUserInteractionWithBundle(packageName, userId, extras);
        } catch (RemoteException re) {
            throw re.rethrowFromSystemServer();
        }
    }

    /**
     * Report usage associated with a particular {@code token} has started. Tokens are app defined
     * strings used to represent usage of in-app features. Apps with the {@link
Loading