/**
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy
 * of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */
package android.app.usage;

import android.annotation.IntDef;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
import java.util.List;

/**
 * A result returned from {@link android.app.usage.UsageStatsManager#queryEvents(long, long)}
 * from which to read {@link android.app.usage.UsageEvents.Event} objects.
 */
public final class UsageEvents implements Parcelable {

    /** @hide */
    public static final String INSTANT_APP_PACKAGE_NAME = "android.instant_app";

    /** @hide */
    public static final String INSTANT_APP_CLASS_NAME = "android.instant_class";

    /**
     * An event representing a state change for a component.
     */
    public static final class Event {

        /**
         * No event type.
         */
        public static final int NONE = 0;

        /**
         * A device level event like {@link #DEVICE_SHUTDOWN} does not have package name, but some
         * user code always expect a non-null {@link #mPackage} for every event. Use
         * {@link #DEVICE_EVENT_PACKAGE_NAME} as packageName for these device level events.
         * @hide
         */
        public static final String DEVICE_EVENT_PACKAGE_NAME = "android";

        /**
         * @deprecated by {@link #ACTIVITY_RESUMED}
         */
        @Deprecated
        public static final int MOVE_TO_FOREGROUND = 1;

        /**
         * An event type denoting that an {@link android.app.Activity} moved to the foreground.
         * This event has a package name and class name associated with it and can be retrieved
         * using {@link #getPackageName()} and {@link #getClassName()}.
         * If a package has multiple activities, this event is reported for each activity that moves
         * to foreground.
         * This event is corresponding to {@link android.app.Activity#onResume()} of the
         * activity's lifecycle.
         */
        public static final int ACTIVITY_RESUMED = MOVE_TO_FOREGROUND;

        /**
         * @deprecated by {@link #ACTIVITY_PAUSED}
         */
        @Deprecated
        public static final int MOVE_TO_BACKGROUND = 2;

        /**
         * An event type denoting that an {@link android.app.Activity} moved to the background.
         * This event has a package name and class name associated with it and can be retrieved
         * using {@link #getPackageName()} and {@link #getClassName()}.
         * If a package has multiple activities, this event is reported for each activity that moves
         * to background.
         * This event is corresponding to {@link android.app.Activity#onPause()} of the activity's
         * lifecycle.
         */
        public static final int ACTIVITY_PAUSED = MOVE_TO_BACKGROUND;

        /**
         * An event type denoting that a component was in the foreground when the stats
         * rolled-over. This is effectively treated as a {@link #ACTIVITY_PAUSED}.
         * {@hide}
         */
        public static final int END_OF_DAY = 3;

        /**
         * An event type denoting that a component was in the foreground the previous day.
         * This is effectively treated as a {@link #ACTIVITY_RESUMED}.
         * {@hide}
         */
        public static final int CONTINUE_PREVIOUS_DAY = 4;

        /**
         * An event type denoting that the device configuration has changed.
         */
        public static final int CONFIGURATION_CHANGE = 5;

        /**
         * An event type denoting that a package was interacted with in some way by the system.
         * @hide
         */
        @SystemApi
        public static final int SYSTEM_INTERACTION = 6;

        /**
         * An event type denoting that a package was interacted with in some way by the user.
         */
        public static final int USER_INTERACTION = 7;

        /**
         * An event type denoting that an action equivalent to a ShortcutInfo is taken by the user.
         *
         * @see android.content.pm.ShortcutManager#reportShortcutUsed(String)
         */
        public static final int SHORTCUT_INVOCATION = 8;

        /**
         * An event type denoting that a package was selected by the user for ChooserActivity.
         * @hide
         */
        public static final int CHOOSER_ACTION = 9;

        /**
         * An event type denoting that a notification was viewed by the user.
         * @hide
         */
        @SystemApi
        public static final int NOTIFICATION_SEEN = 10;

        /**
         * An event type denoting a change in App Standby Bucket. The new bucket can be
         * retrieved by calling {@link #getAppStandbyBucket()}.
         *
         * @see UsageStatsManager#getAppStandbyBucket()
         */
        public static final int STANDBY_BUCKET_CHANGED = 11;

        /**
         * An event type denoting that an app posted an interruptive notification. Visual and
         * audible interruptions are included.
         * @hide
         */
        @SystemApi
        public static final int NOTIFICATION_INTERRUPTION = 12;

        /**
         * A Slice was pinned by the default launcher or the default assistant.
         * @hide
         */
        @SystemApi
        public static final int SLICE_PINNED_PRIV = 13;

        /**
         * A Slice was pinned by an app.
         * @hide
         */
        @SystemApi
        public static final int SLICE_PINNED = 14;

        /**
         * An event type denoting that the screen has gone in to an interactive state (turned
         * on for full user interaction, not ambient display or other non-interactive state).
         */
        public static final int SCREEN_INTERACTIVE = 15;

        /**
         * An event type denoting that the screen has gone in to a non-interactive state
         * (completely turned off or turned on only in a non-interactive state like ambient
         * display).
         */
        public static final int SCREEN_NON_INTERACTIVE = 16;

        /**
         * An event type denoting that the screen's keyguard has been shown, whether or not
         * the screen is off.
         */
        public static final int KEYGUARD_SHOWN = 17;

        /**
         * An event type denoting that the screen's keyguard has been hidden.  This typically
         * happens when the user unlocks their phone after turning it on.
         */
        public static final int KEYGUARD_HIDDEN = 18;

        /**
         * An event type denoting start of a foreground service.
         * This event has a package name and class name associated with it and can be retrieved
         * using {@link #getPackageName()} and {@link #getClassName()}.
         * If a package has multiple foreground services, this event is reported for each service
         * that is started.
         */
        public static final int FOREGROUND_SERVICE_START = 19;

        /**
         * An event type denoting stop of a foreground service.
         * This event has a package name and class name associated with it and can be retrieved
         * using {@link #getPackageName()} and {@link #getClassName()}.
         * If a package has multiple foreground services, this event is reported for each service
         * that is stopped.
         */
        public static final int FOREGROUND_SERVICE_STOP = 20;

        /**
         * An event type denoting that a foreground service is at started state at beginning of a
         * time interval.
         * This is effectively treated as a {@link #FOREGROUND_SERVICE_START}.
         * {@hide}
         */
        public static final int CONTINUING_FOREGROUND_SERVICE = 21;

        /**
         * An event type denoting that a foreground service is at started state when the stats
         * rolled-over at the end of a time interval.
         * {@hide}
         */
        public static final int ROLLOVER_FOREGROUND_SERVICE = 22;

        /**
         * An activity becomes invisible on the UI, corresponding to
         * {@link android.app.Activity#onStop()} of the activity's lifecycle.
         */
        public static final int ACTIVITY_STOPPED = 23;

        /**
         * An activity object is destroyed, corresponding to
         * {@link android.app.Activity#onDestroy()} of the activity's lifecycle.
         * {@hide}
         */
        public static final int ACTIVITY_DESTROYED = 24;

        /**
         * The event type demoting that a flush of UsageStatsDatabase to file system. Before the
         * flush all usage stats need to be updated to latest timestamp to make sure the most
         * up to date stats are persisted.
         * @hide
         */
        public static final int FLUSH_TO_DISK = 25;

        /**
         * An event type denoting that the Android runtime underwent a shutdown process.
         * A DEVICE_SHUTDOWN event should be treated as if all started activities and foreground
         * services are now stopped and no explicit {@link #ACTIVITY_STOPPED} and
         * {@link #FOREGROUND_SERVICE_STOP} events will be generated for them.
         *
         * <p>The DEVICE_SHUTDOWN timestamp is actually the last time UsageStats database is
         * persisted before the actual shutdown. Events (if there are any) between this timestamp
         * and the actual shutdown is not persisted in the database. So any open events without
         * matching close events between DEVICE_SHUTDOWN and {@link #DEVICE_STARTUP} should be
         * ignored because the closing time is unknown.</p>
         */
        public static final int DEVICE_SHUTDOWN = 26;

        /**
         * An event type denoting that the Android runtime started up. This could be after a
         * shutdown or a runtime restart. Any open events without matching close events between
         * {@link #DEVICE_SHUTDOWN} and DEVICE_STARTUP should be ignored because the closing time is
         * unknown.
         */
        public static final int DEVICE_STARTUP = 27;

        /**
         * Keep in sync with the greatest event type value.
         * @hide
         */
        public static final int MAX_EVENT_TYPE = 27;

        /** @hide */
        public static final int FLAG_IS_PACKAGE_INSTANT_APP = 1 << 0;

        /** @hide */
        @IntDef(flag = true, prefix = { "FLAG_" }, value = {
                FLAG_IS_PACKAGE_INSTANT_APP,
        })
        @Retention(RetentionPolicy.SOURCE)
        public @interface EventFlags {}

        /**
         * Bitwise OR all valid flag constants to create this constant.
         * @hide
         */
        public static final int VALID_FLAG_BITS = FLAG_IS_PACKAGE_INSTANT_APP;

        /**
         * {@hide}
         */
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
        public String mPackage;

        /**
         * {@hide}
         */
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
        public String mClass;

        /**
         * {@hide}
         */
        public int mInstanceId;

        /**
         * {@hide}
         */
        public String mTaskRootPackage;

        /**
         * {@hide}
         */
        public String mTaskRootClass;

        /**
         * {@hide}
         */
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
        public long mTimeStamp;

        /**
         * {@hide}
         */
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
        public int mEventType;

        /**
         * Only present for {@link #CONFIGURATION_CHANGE} event types.
         * {@hide}
         */
        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
        public Configuration mConfiguration;

        /**
         * ID of the shortcut.
         * Only present for {@link #SHORTCUT_INVOCATION} event types.
         * {@hide}
         */
        public String mShortcutId;

        /**
         * Action type passed to ChooserActivity
         * Only present for {@link #CHOOSER_ACTION} event types.
         * {@hide}
         */
        public String mAction;

        /**
         * Content type passed to ChooserActivity.
         * Only present for {@link #CHOOSER_ACTION} event types.
         * {@hide}
         */
        public String mContentType;

        /**
         * Content annotations passed to ChooserActivity.
         * Only present for {@link #CHOOSER_ACTION} event types.
         * {@hide}
         */
        public String[] mContentAnnotations;

        /**
         * The app standby bucket assigned and reason. Bucket is the high order 16 bits, reason
         * is the low order 16 bits.
         * Only present for {@link #STANDBY_BUCKET_CHANGED} event types
         * {@hide}
         */
        public int mBucketAndReason;

        /**
         * The id of the {@link android.app.NotificationChannel} to which an interruptive
         * notification was posted.
         * Only present for {@link #NOTIFICATION_INTERRUPTION} event types.
         * {@hide}
         */
        public String mNotificationChannelId;

        /** @hide */
        @EventFlags
        public int mFlags;

        public Event() {
        }

        /** @hide */
        public Event(int type,  long timeStamp) {
            mEventType = type;
            mTimeStamp = timeStamp;
        }

        /** @hide */
        public Event(Event orig) {
            mPackage = orig.mPackage;
            mClass = orig.mClass;
            mInstanceId = orig.mInstanceId;
            mTaskRootPackage = orig.mTaskRootPackage;
            mTaskRootClass = orig.mTaskRootClass;
            mTimeStamp = orig.mTimeStamp;
            mEventType = orig.mEventType;
            mConfiguration = orig.mConfiguration;
            mShortcutId = orig.mShortcutId;
            mAction = orig.mAction;
            mContentType = orig.mContentType;
            mContentAnnotations = orig.mContentAnnotations;
            mFlags = orig.mFlags;
            mBucketAndReason = orig.mBucketAndReason;
            mNotificationChannelId = orig.mNotificationChannelId;
        }

        /**
         * The package name of the source of this event.
         */
        public String getPackageName() {
            return mPackage;
        }

        /**
         * Indicates whether it is an instant app.
         * STOPSHIP b/111407095: Add GTS tests for the newly added API method.
         * @hide
         */
        @SystemApi
        public boolean isInstantApp() {
            return (mFlags & FLAG_IS_PACKAGE_INSTANT_APP) == FLAG_IS_PACKAGE_INSTANT_APP;
        }

        /**
         * The class name of the source of this event. This may be null for
         * certain events.
         */
        public String getClassName() {
            return mClass;
        }

        /**
         *  An activity can be instantiated multiple times, this is the unique activity instance ID.
         *  For non-activity class, instance ID is always zero.
         *  @hide
         */
        @SystemApi
        public int getInstanceId() {
            return mInstanceId;
        }

        /**
         * The package name of the task root when this event was reported.
         * Or {@code null} for queries from apps without {@link
         * android.Manifest.permission#PACKAGE_USAGE_STATS}
         * @hide
         */
        @SystemApi
        public @Nullable String getTaskRootPackageName() {
            return mTaskRootPackage;
        }

        /**
         * The class name of the task root when this event was reported.
         * Or {@code null} for queries from apps without {@link
         * android.Manifest.permission#PACKAGE_USAGE_STATS}
         * @hide
         */
        @SystemApi
        public @Nullable String getTaskRootClassName() {
            return mTaskRootClass;
        }

        /**
         * The time at which this event occurred, measured in milliseconds since the epoch.
         * <p/>
         * See {@link System#currentTimeMillis()}.
         */
        public long getTimeStamp() {
            return mTimeStamp;
        }

        /**
         * The event type.
         * @see #ACTIVITY_PAUSED
         * @see #ACTIVITY_RESUMED
         * @see #CONFIGURATION_CHANGE
         * @see #USER_INTERACTION
         * @see #STANDBY_BUCKET_CHANGED
         * @see #FOREGROUND_SERVICE_START
         * @see #FOREGROUND_SERVICE_STOP
         * @see #ACTIVITY_STOPPED
         */
        public int getEventType() {
            return mEventType;
        }

        /**
         * Returns a {@link Configuration} for this event if the event is of type
         * {@link #CONFIGURATION_CHANGE}, otherwise it returns null.
         */
        public Configuration getConfiguration() {
            return mConfiguration;
        }

        /**
         * Returns the ID of a {@link android.content.pm.ShortcutInfo} for this event
         * if the event is of type {@link #SHORTCUT_INVOCATION}, otherwise it returns null.
         *
         * @see android.content.pm.ShortcutManager#reportShortcutUsed(String)
         */
        public String getShortcutId() {
            return mShortcutId;
        }

        /**
         * Returns the standby bucket of the app, if the event is of type
         * {@link #STANDBY_BUCKET_CHANGED}, otherwise returns 0.
         * @return the standby bucket associated with the event.
         * @hide
         */
        public int getStandbyBucket() {
            return (mBucketAndReason & 0xFFFF0000) >>> 16;
        }

        /**
         * Returns the standby bucket of the app, if the event is of type
         * {@link #STANDBY_BUCKET_CHANGED}, otherwise returns 0.
         * @return the standby bucket associated with the event.
         *
         */
        public int getAppStandbyBucket() {
            return (mBucketAndReason & 0xFFFF0000) >>> 16;
        }

        /**
         * Returns the reason for the bucketing, if the event is of type
         * {@link #STANDBY_BUCKET_CHANGED}, otherwise returns 0. Reason values include
         * the main reason which is one of REASON_MAIN_*, OR'ed with REASON_SUB_*, if there
         * are sub-reasons for the main reason, such as REASON_SUB_USAGE_* when the main reason
         * is REASON_MAIN_USAGE.
         * @hide
         */
        public int getStandbyReason() {
            return mBucketAndReason & 0x0000FFFF;
        }

        /**
         * Returns the ID of the {@link android.app.NotificationChannel} for this event if the
         * event is of type {@link #NOTIFICATION_INTERRUPTION}, otherwise it returns null;
         * @hide
         */
        @SystemApi
        public String getNotificationChannelId() {
            return mNotificationChannelId;
        }

        /** @hide */
        public Event getObfuscatedIfInstantApp() {
            if (!isInstantApp()) {
                return this;
            }
            final Event ret = new Event(this);
            ret.mPackage = INSTANT_APP_PACKAGE_NAME;
            ret.mClass = INSTANT_APP_CLASS_NAME;

            // Note there are other string fields too, but they're for app shortcuts and choosers,
            // which instant apps can't use anyway, so there's no need to hide them.
            return ret;
        }
    }

    // Only used when creating the resulting events. Not used for reading/unparceling.
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private List<Event> mEventsToWrite = null;

    // Only used for reading/unparceling events.
    @UnsupportedAppUsage
    private Parcel mParcel = null;
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private final int mEventCount;

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private int mIndex = 0;

    // Only used when parceling events. If false, task roots will be omitted from the parcel
    private final boolean mIncludeTaskRoots;

    /*
     * In order to save space, since ComponentNames will be duplicated everywhere,
     * we use a map and index into it.
     */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private String[] mStringPool;

    /**
     * Construct the iterator from a parcel.
     * {@hide}
     */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    public UsageEvents(Parcel in) {
        byte[] bytes = in.readBlob();
        Parcel data = Parcel.obtain();
        data.unmarshall(bytes, 0, bytes.length);
        data.setDataPosition(0);
        mEventCount = data.readInt();
        mIndex = data.readInt();
        if (mEventCount > 0) {
            mStringPool = data.createStringArray();

            final int listByteLength = data.readInt();
            final int positionInParcel = data.readInt();
            mParcel = Parcel.obtain();
            mParcel.setDataPosition(0);
            mParcel.appendFrom(data, data.dataPosition(), listByteLength);
            mParcel.setDataSize(mParcel.dataPosition());
            mParcel.setDataPosition(positionInParcel);
        }
        mIncludeTaskRoots = true;
    }

    /**
     * Create an empty iterator.
     * {@hide}
     */
    UsageEvents() {
        mEventCount = 0;
        mIncludeTaskRoots = true;
    }

    /**
     * Construct the iterator in preparation for writing it to a parcel.
     * Defaults to excluding task roots from the parcel.
     * {@hide}
     */
    public UsageEvents(List<Event> events, String[] stringPool) {
        this(events, stringPool, false);
    }

    /**
     * Construct the iterator in preparation for writing it to a parcel.
     * {@hide}
     */
    public UsageEvents(List<Event> events, String[] stringPool, boolean includeTaskRoots) {
        mStringPool = stringPool;
        mEventCount = events.size();
        mEventsToWrite = events;
        mIncludeTaskRoots = includeTaskRoots;
    }

    /**
     * Returns whether or not there are more events to read using
     * {@link #getNextEvent(android.app.usage.UsageEvents.Event)}.
     *
     * @return true if there are more events, false otherwise.
     */
    public boolean hasNextEvent() {
        return mIndex < mEventCount;
    }

    /**
     * Retrieve the next {@link android.app.usage.UsageEvents.Event} from the collection and put the
     * resulting data into {@code eventOut}.
     *
     * @param eventOut The {@link android.app.usage.UsageEvents.Event} object that will receive the
     *                 next event data.
     * @return true if an event was available, false if there are no more events.
     */
    public boolean getNextEvent(Event eventOut) {
        if (mIndex >= mEventCount) {
            return false;
        }

        readEventFromParcel(mParcel, eventOut);

        mIndex++;
        if (mIndex >= mEventCount) {
            mParcel.recycle();
            mParcel = null;
        }
        return true;
    }

    /**
     * Resets the collection so that it can be iterated over from the beginning.
     *
     * @hide When this object is iterated to completion, the parcel is destroyed and
     * so resetToStart doesn't work.
     */
    public void resetToStart() {
        mIndex = 0;
        if (mParcel != null) {
            mParcel.setDataPosition(0);
        }
    }

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private int findStringIndex(String str) {
        final int index = Arrays.binarySearch(mStringPool, str);
        if (index < 0) {
            throw new IllegalStateException("String '" + str + "' is not in the string pool");
        }
        return index;
    }

    /**
     * Writes a single event to the parcel. Modify this when updating {@link Event}.
     */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private void writeEventToParcel(Event event, Parcel p, int flags) {
        final int packageIndex;
        if (event.mPackage != null) {
            packageIndex = findStringIndex(event.mPackage);
        } else {
            packageIndex = -1;
        }

        final int classIndex;
        if (event.mClass != null) {
            classIndex = findStringIndex(event.mClass);
        } else {
            classIndex = -1;
        }

        final int taskRootPackageIndex;
        if (mIncludeTaskRoots && event.mTaskRootPackage != null) {
            taskRootPackageIndex = findStringIndex(event.mTaskRootPackage);
        } else {
            taskRootPackageIndex = -1;
        }

        final int taskRootClassIndex;
        if (mIncludeTaskRoots && event.mTaskRootClass != null) {
            taskRootClassIndex = findStringIndex(event.mTaskRootClass);
        } else {
            taskRootClassIndex = -1;
        }
        p.writeInt(packageIndex);
        p.writeInt(classIndex);
        p.writeInt(event.mInstanceId);
        p.writeInt(taskRootPackageIndex);
        p.writeInt(taskRootClassIndex);
        p.writeInt(event.mEventType);
        p.writeLong(event.mTimeStamp);

        switch (event.mEventType) {
            case Event.CONFIGURATION_CHANGE:
                event.mConfiguration.writeToParcel(p, flags);
                break;
            case Event.SHORTCUT_INVOCATION:
                p.writeString(event.mShortcutId);
                break;
            case Event.CHOOSER_ACTION:
                p.writeString(event.mAction);
                p.writeString(event.mContentType);
                p.writeStringArray(event.mContentAnnotations);
                break;
            case Event.STANDBY_BUCKET_CHANGED:
                p.writeInt(event.mBucketAndReason);
                break;
            case Event.NOTIFICATION_INTERRUPTION:
                p.writeString(event.mNotificationChannelId);
                break;
        }
        p.writeInt(event.mFlags);
    }

    /**
     * Reads a single event from the parcel. Modify this when updating {@link Event}.
     */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private void readEventFromParcel(Parcel p, Event eventOut) {
        final int packageIndex = p.readInt();
        if (packageIndex >= 0) {
            eventOut.mPackage = mStringPool[packageIndex];
        } else {
            eventOut.mPackage = null;
        }

        final int classIndex = p.readInt();
        if (classIndex >= 0) {
            eventOut.mClass = mStringPool[classIndex];
        } else {
            eventOut.mClass = null;
        }
        eventOut.mInstanceId = p.readInt();

        final int taskRootPackageIndex = p.readInt();
        if (taskRootPackageIndex >= 0) {
            eventOut.mTaskRootPackage = mStringPool[taskRootPackageIndex];
        } else {
            eventOut.mTaskRootPackage = null;
        }

        final int taskRootClassIndex = p.readInt();
        if (taskRootClassIndex >= 0) {
            eventOut.mTaskRootClass = mStringPool[taskRootClassIndex];
        } else {
            eventOut.mTaskRootClass = null;
        }

        eventOut.mEventType = p.readInt();
        eventOut.mTimeStamp = p.readLong();

        // Fill out the event-dependant fields.
        eventOut.mConfiguration = null;
        eventOut.mShortcutId = null;
        eventOut.mAction = null;
        eventOut.mContentType = null;
        eventOut.mContentAnnotations = null;
        eventOut.mNotificationChannelId = null;

        switch (eventOut.mEventType) {
            case Event.CONFIGURATION_CHANGE:
                // Extract the configuration for configuration change events.
                eventOut.mConfiguration = Configuration.CREATOR.createFromParcel(p);
                break;
            case Event.SHORTCUT_INVOCATION:
                eventOut.mShortcutId = p.readString();
                break;
            case Event.CHOOSER_ACTION:
                eventOut.mAction = p.readString();
                eventOut.mContentType = p.readString();
                eventOut.mContentAnnotations = p.createStringArray();
                break;
            case Event.STANDBY_BUCKET_CHANGED:
                eventOut.mBucketAndReason = p.readInt();
                break;
            case Event.NOTIFICATION_INTERRUPTION:
                eventOut.mNotificationChannelId = p.readString();
                break;
        }
        eventOut.mFlags = p.readInt();
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        Parcel data = Parcel.obtain();
        data.writeInt(mEventCount);
        data.writeInt(mIndex);
        if (mEventCount > 0) {
            data.writeStringArray(mStringPool);

            if (mEventsToWrite != null) {
                // Write out the events
                Parcel p = Parcel.obtain();
                try {
                    p.setDataPosition(0);
                    for (int i = 0; i < mEventCount; i++) {
                        final Event event = mEventsToWrite.get(i);
                        writeEventToParcel(event, p, flags);
                    }

                    final int listByteLength = p.dataPosition();

                    // Write the total length of the data.
                    data.writeInt(listByteLength);

                    // Write our current position into the data.
                    data.writeInt(0);

                    // Write the data.
                    data.appendFrom(p, 0, listByteLength);
                } finally {
                    p.recycle();
                }

            } else if (mParcel != null) {
                // Write the total length of the data.
                data.writeInt(mParcel.dataSize());

                // Write out current position into the data.
                data.writeInt(mParcel.dataPosition());

                // Write the data.
                data.appendFrom(mParcel, 0, mParcel.dataSize());
            } else {
                throw new IllegalStateException(
                        "Either mParcel or mEventsToWrite must not be null");
            }
        }
        // Data can be too large for a transact. Write the data as a Blob, which will be written to
        // ashmem if too large.
        dest.writeBlob(data.marshall());
    }

    public static final @android.annotation.NonNull Creator<UsageEvents> CREATOR = new Creator<UsageEvents>() {
        @Override
        public UsageEvents createFromParcel(Parcel source) {
            return new UsageEvents(source);
        }

        @Override
        public UsageEvents[] newArray(int size) {
            return new UsageEvents[size];
        }
    };
}
