/*
 * Copyright (C) 2020 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 com.android.server.am;

import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;

import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
import static com.android.server.am.ActivityManagerService.TAG_UID_OBSERVERS;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManagerProto;
import android.app.IUidObserver;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
import android.util.Slog;
import android.util.SparseIntArray;
import android.util.proto.ProtoOutputStream;
import android.util.proto.ProtoUtils;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.am.ActivityManagerServiceDumpProcessesProto.UidObserverRegistrationProto;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.UUID;

public class UidObserverController {
    /** If a UID observer takes more than this long, send a WTF. */
    private static final int SLOW_UID_OBSERVER_THRESHOLD_MS = 20;

    private final Handler mHandler;

    private final Object mLock = new Object();

    @GuardedBy("mLock")
    final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();

    @GuardedBy("mLock")
    private final ArrayList<ChangeRecord> mPendingUidChanges = new ArrayList<>();
    @GuardedBy("mLock")
    private final ArrayList<ChangeRecord> mAvailUidChanges = new ArrayList<>();

    private ChangeRecord[] mActiveUidChanges = new ChangeRecord[5];

    /** Total # of UID change events dispatched, shown in dumpsys. */
    @GuardedBy("mLock")
    private int mUidChangeDispatchCount;

    private final Runnable mDispatchRunnable = this::dispatchUidsChanged;

    /**
     * This is for verifying the UID report flow.
     */
    private static final boolean VALIDATE_UID_STATES = true;
    private final ActiveUids mValidateUids;

    UidObserverController(@NonNull Handler handler) {
        mHandler = handler;
        mValidateUids = new ActiveUids(null /* service */, false /* postChangesToAtm */);
    }

    IBinder register(@NonNull IUidObserver observer, int which, int cutpoint,
            @NonNull String callingPackage, int callingUid, @Nullable int[] uids) {
        IBinder token = new Binder("UidObserver-" + callingPackage + "-"
                + UUID.randomUUID().toString());

        synchronized (mLock) {
            mUidObservers.register(observer, new UidObserverRegistration(callingUid,
                    callingPackage, which, cutpoint,
                    ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, callingUid)
                    == PackageManager.PERMISSION_GRANTED, uids, token));
        }

        return token;
    }

    void unregister(@NonNull IUidObserver observer) {
        synchronized (mLock) {
            mUidObservers.unregister(observer);
        }
    }

    final void addUidToObserver(@NonNull IBinder observerToken, int uid) {
        Message msg = Message.obtain(mHandler, ActivityManagerService.ADD_UID_TO_OBSERVER_MSG,
                uid, /*arg2*/ 0, observerToken);
        mHandler.sendMessage(msg);
    }

    /**
     * Add a uid to the list of uids an observer is interested in. Must be run on the same thread
     * as mDispatchRunnable.
     *
     * @param observerToken The token identifier for a UidObserver
     * @param uid The uid to add to the list of watched uids
     */
    public final void addUidToObserverImpl(@NonNull IBinder observerToken, int uid) {
        int i = mUidObservers.beginBroadcast();
        while (i-- > 0) {
            var reg = (UidObserverRegistration) mUidObservers.getBroadcastCookie(i);
            if (reg.getToken().equals(observerToken)) {
                reg.addUid(uid);
                break;
            }

            if (i == 0) {
                Slog.e(TAG_UID_OBSERVERS, "Unable to find UidObserver by token");
            }
        }
        mUidObservers.finishBroadcast();
    }

    final void removeUidFromObserver(@NonNull IBinder observerToken, int uid) {
        Message msg = Message.obtain(mHandler, ActivityManagerService.REMOVE_UID_FROM_OBSERVER_MSG,
                uid, /*arg2*/ 0, observerToken);
        mHandler.sendMessage(msg);
    }

    /**
     * Remove a uid from the list of uids an observer is interested in. Must be run on the same
     * thread as mDispatchRunnable.
     *
     * @param observerToken The token identifier for a UidObserver
     * @param uid The uid to remove from the list of watched uids
     */
    public final void removeUidFromObserverImpl(@NonNull IBinder observerToken, int uid) {
        int i = mUidObservers.beginBroadcast();
        while (i-- > 0) {
            var reg = (UidObserverRegistration) mUidObservers.getBroadcastCookie(i);
            if (reg.getToken().equals(observerToken)) {
                reg.removeUid(uid);
                break;
            }

            if (i == 0) {
                Slog.e(TAG_UID_OBSERVERS, "Unable to find UidObserver by token");
            }
        }
        mUidObservers.finishBroadcast();
    }

    int enqueueUidChange(@Nullable ChangeRecord currentRecord, int uid, int change, int procState,
            int procAdj, long procStateSeq, int capability, boolean ephemeral) {
        synchronized (mLock) {
            if (mPendingUidChanges.size() == 0) {
                if (DEBUG_UID_OBSERVERS) {
                    Slog.i(TAG_UID_OBSERVERS, "*** Enqueueing dispatch uid changed!");
                }
                mHandler.post(mDispatchRunnable);
            }

            final ChangeRecord changeRecord = currentRecord != null
                    ? currentRecord : getOrCreateChangeRecordLocked();
            if (!changeRecord.isPending) {
                changeRecord.isPending = true;
                mPendingUidChanges.add(changeRecord);
            } else {
                change = mergeWithPendingChange(change, changeRecord.change);
            }

            changeRecord.uid = uid;
            changeRecord.change = change;
            changeRecord.procState = procState;
            changeRecord.procAdj = procAdj;
            changeRecord.procStateSeq = procStateSeq;
            changeRecord.capability = capability;
            changeRecord.ephemeral = ephemeral;

            return changeRecord.change;
        }
    }

    ArrayList<ChangeRecord> getPendingUidChangesForTest() {
        return mPendingUidChanges;
    }

    ActiveUids getValidateUidsForTest() {
        return mValidateUids;
    }

    Runnable getDispatchRunnableForTest() {
        return mDispatchRunnable;
    }

    @VisibleForTesting
    static int mergeWithPendingChange(int currentChange, int pendingChange) {
        // If there is no change in idle or active state, then keep whatever was pending.
        if ((currentChange & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
            currentChange |= (pendingChange & (UidRecord.CHANGE_IDLE
                    | UidRecord.CHANGE_ACTIVE));
        }
        // If there is no change in cached or uncached state, then keep whatever was pending.
        if ((currentChange & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
            currentChange |= (pendingChange & (UidRecord.CHANGE_CACHED
                    | UidRecord.CHANGE_UNCACHED));
        }
        // If this is a report of the UID being gone, then we shouldn't keep any previous
        // report of it being active or cached.  (That is, a gone uid is never active,
        // and never cached.)
        if ((currentChange & UidRecord.CHANGE_GONE) != 0) {
            currentChange &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
        }
        if ((pendingChange & UidRecord.CHANGE_CAPABILITY) != 0) {
            currentChange |= UidRecord.CHANGE_CAPABILITY;
        }
        if ((pendingChange & UidRecord.CHANGE_PROCSTATE) != 0) {
            currentChange |= UidRecord.CHANGE_PROCSTATE;
        }
        if ((pendingChange & UidRecord.CHANGE_PROCADJ) != 0) {
            currentChange |= UidRecord.CHANGE_PROCADJ;
        }
        return currentChange;
    }

    @GuardedBy("mLock")
    private ChangeRecord getOrCreateChangeRecordLocked() {
        final ChangeRecord changeRecord;
        final int size = mAvailUidChanges.size();
        if (size > 0) {
            changeRecord = mAvailUidChanges.remove(size - 1);
            if (DEBUG_UID_OBSERVERS) {
                Slog.i(TAG_UID_OBSERVERS, "Retrieving available item: " + changeRecord);
            }
        } else {
            changeRecord = new ChangeRecord();
            if (DEBUG_UID_OBSERVERS) {
                Slog.i(TAG_UID_OBSERVERS, "Allocating new item: " + changeRecord);
            }
        }
        return changeRecord;
    }

    @VisibleForTesting
    void dispatchUidsChanged() {
        final int numUidChanges;
        synchronized (mLock) {
            numUidChanges = mPendingUidChanges.size();
            if (mActiveUidChanges.length < numUidChanges) {
                mActiveUidChanges = new ChangeRecord[numUidChanges];
            }
            for (int i = 0; i < numUidChanges; i++) {
                final ChangeRecord changeRecord = mPendingUidChanges.get(i);
                mActiveUidChanges[i] = getOrCreateChangeRecordLocked();
                changeRecord.copyTo(mActiveUidChanges[i]);
                changeRecord.isPending = false;
            }
            mPendingUidChanges.clear();
            if (DEBUG_UID_OBSERVERS) {
                Slog.i(TAG_UID_OBSERVERS, "*** Delivering " + numUidChanges + " uid changes");
            }
            mUidChangeDispatchCount += numUidChanges;
        }

        int i = mUidObservers.beginBroadcast();
        while (i-- > 0) {
            dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
                    (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), numUidChanges);
        }
        mUidObservers.finishBroadcast();

        if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
            for (int j = 0; j < numUidChanges; ++j) {
                final ChangeRecord item = mActiveUidChanges[j];
                if ((item.change & UidRecord.CHANGE_GONE) != 0) {
                    mValidateUids.remove(item.uid);
                } else {
                    UidRecord validateUid = mValidateUids.get(item.uid);
                    if (validateUid == null) {
                        validateUid = new UidRecord(item.uid, null);
                        mValidateUids.put(item.uid, validateUid);
                    }
                    if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
                        validateUid.setIdle(true);
                    } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
                        validateUid.setIdle(false);
                    }
                    validateUid.setSetProcState(item.procState);
                    validateUid.setCurProcState(item.procState);
                    validateUid.setSetCapability(item.capability);
                    validateUid.setCurCapability(item.capability);
                }
            }
        }

        synchronized (mLock) {
            for (int j = 0; j < numUidChanges; j++) {
                final ChangeRecord changeRecord = mActiveUidChanges[j];
                changeRecord.isPending = false;
                mAvailUidChanges.add(changeRecord);
            }
        }
    }

    private void dispatchUidsChangedForObserver(@NonNull IUidObserver observer,
            @NonNull UidObserverRegistration reg, int changesSize) {
        if (observer == null) {
            return;
        }
        try {
            for (int j = 0; j < changesSize; j++) {
                final ChangeRecord item = mActiveUidChanges[j];
                final long start = SystemClock.uptimeMillis();
                final int change = item.change;
                // Is the observer watching this uid?
                if (!reg.isWatchingUid(item.uid)) {
                    continue;
                }
                // Does the user have permission? Don't send a non user UID change otherwise
                if (UserHandle.getUserId(item.uid) != UserHandle.getUserId(reg.mUid)
                        && !reg.mCanInteractAcrossUsers) {
                    continue;
                }
                if (change == UidRecord.CHANGE_PROCSTATE
                        && (reg.mWhich & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
                    // No-op common case: no significant change, the observer is not
                    // interested in all proc state changes.
                    continue;
                }
                if (change == UidRecord.CHANGE_PROCADJ
                        && (reg.mWhich & ActivityManager.UID_OBSERVER_PROC_OOM_ADJ) == 0) {
                    // No-op common case: no significant change, the observer is not
                    // interested in proc adj changes.
                    continue;
                }
                if ((change & UidRecord.CHANGE_IDLE) != 0) {
                    if ((reg.mWhich & ActivityManager.UID_OBSERVER_IDLE) != 0) {
                        if (DEBUG_UID_OBSERVERS) {
                            Slog.i(TAG_UID_OBSERVERS, "UID idle uid=" + item.uid);
                        }
                        observer.onUidIdle(item.uid, item.ephemeral);
                    }
                } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
                    if ((reg.mWhich & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
                        if (DEBUG_UID_OBSERVERS) {
                            Slog.i(TAG_UID_OBSERVERS, "UID active uid=" + item.uid);
                        }
                        observer.onUidActive(item.uid);
                    }
                }
                if ((reg.mWhich & ActivityManager.UID_OBSERVER_CACHED) != 0) {
                    if ((change & UidRecord.CHANGE_CACHED) != 0) {
                        if (DEBUG_UID_OBSERVERS) {
                            Slog.i(TAG_UID_OBSERVERS, "UID cached uid=" + item.uid);
                        }
                        observer.onUidCachedChanged(item.uid, true);
                    } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
                        if (DEBUG_UID_OBSERVERS) {
                            Slog.i(TAG_UID_OBSERVERS, "UID active uid=" + item.uid);
                        }
                        observer.onUidCachedChanged(item.uid, false);
                    }
                }
                if ((change & UidRecord.CHANGE_GONE) != 0) {
                    if ((reg.mWhich & ActivityManager.UID_OBSERVER_GONE) != 0) {
                        if (DEBUG_UID_OBSERVERS) {
                            Slog.i(TAG_UID_OBSERVERS, "UID gone uid=" + item.uid);
                        }
                        observer.onUidGone(item.uid, item.ephemeral);
                    }
                    if (reg.mLastProcStates != null) {
                        reg.mLastProcStates.delete(item.uid);
                    }
                } else {
                    boolean doReport = false;
                    if ((reg.mWhich & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
                        doReport = true;
                        if (reg.mCutpoint >= ActivityManager.MIN_PROCESS_STATE) {
                            final int lastState = reg.mLastProcStates.get(item.uid,
                                    ActivityManager.PROCESS_STATE_UNKNOWN);
                            if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
                                final boolean lastAboveCut = lastState <= reg.mCutpoint;
                                final boolean newAboveCut = item.procState <= reg.mCutpoint;
                                doReport = lastAboveCut != newAboveCut;
                            } else {
                                doReport = item.procState != PROCESS_STATE_NONEXISTENT;
                            }
                        }
                    }
                    if ((reg.mWhich & ActivityManager.UID_OBSERVER_CAPABILITY) != 0) {
                        doReport |= (change & UidRecord.CHANGE_CAPABILITY) != 0;
                    }
                    if (doReport) {
                        if (DEBUG_UID_OBSERVERS) {
                            Slog.i(TAG_UID_OBSERVERS, "UID CHANGED uid=" + item.uid
                                    + ": " + item.procState + ": " + item.capability);
                        }
                        if (reg.mLastProcStates != null) {
                            reg.mLastProcStates.put(item.uid, item.procState);
                        }
                        observer.onUidStateChanged(item.uid, item.procState,
                                item.procStateSeq,
                                item.capability);
                    }
                    if ((reg.mWhich & ActivityManager.UID_OBSERVER_PROC_OOM_ADJ) != 0
                            && (change & UidRecord.CHANGE_PROCADJ) != 0) {
                        observer.onUidProcAdjChanged(item.uid, item.procAdj);
                    }
                }
                final int duration = (int) (SystemClock.uptimeMillis() - start);
                if (reg.mMaxDispatchTime < duration) {
                    reg.mMaxDispatchTime = duration;
                }
                if (duration >= SLOW_UID_OBSERVER_THRESHOLD_MS) {
                    reg.mSlowDispatchCount++;
                }
            }
        } catch (RemoteException e) {
        }
    }

    UidRecord getValidateUidRecord(int uid) {
        return mValidateUids.get(uid);
    }

    void dump(@NonNull PrintWriter pw, @Nullable String dumpPackage) {
        synchronized (mLock) {
            final int count = mUidObservers.getRegisteredCallbackCount();
            boolean printed = false;
            for (int i = 0; i < count; i++) {
                final UidObserverRegistration reg = (UidObserverRegistration)
                        mUidObservers.getRegisteredCallbackCookie(i);
                if (dumpPackage == null || dumpPackage.equals(reg.mPkg)) {
                    if (!printed) {
                        pw.println("  mUidObservers:");
                        printed = true;
                    }
                    reg.dump(pw, mUidObservers.getRegisteredCallbackItem(i));
                }
            }

            if (dumpPackage == null) {
                pw.println();
                pw.print("  mUidChangeDispatchCount=");
                pw.print(mUidChangeDispatchCount);
                pw.println();
                pw.println("  Slow UID dispatches:");
                for (int i = 0; i < count; i++) {
                    final UidObserverRegistration reg = (UidObserverRegistration)
                            mUidObservers.getRegisteredCallbackCookie(i);
                    pw.print("    ");
                    pw.print(mUidObservers.getRegisteredCallbackItem(i).getClass().getTypeName());
                    pw.print(": ");
                    pw.print(reg.mSlowDispatchCount);
                    pw.print(" / Max ");
                    pw.print(reg.mMaxDispatchTime);
                    pw.println("ms");
                }
            }
        }
    }

    void dumpDebug(@NonNull ProtoOutputStream proto, @Nullable String dumpPackage) {
        synchronized (mLock) {
            final int count = mUidObservers.getRegisteredCallbackCount();
            for (int i = 0; i < count; i++) {
                final UidObserverRegistration reg = (UidObserverRegistration)
                        mUidObservers.getRegisteredCallbackCookie(i);
                if (dumpPackage == null || dumpPackage.equals(reg.mPkg)) {
                    reg.dumpDebug(proto, ActivityManagerServiceDumpProcessesProto.UID_OBSERVERS);
                }
            }
        }
    }

    boolean dumpValidateUids(@NonNull PrintWriter pw, @Nullable String dumpPackage, int dumpAppId,
            @NonNull String header, boolean needSep) {
        return mValidateUids.dump(pw, dumpPackage, dumpAppId, header, needSep);
    }

    void dumpValidateUidsProto(@NonNull ProtoOutputStream proto, @Nullable String dumpPackage,
            int dumpAppId, long fieldId) {
        mValidateUids.dumpProto(proto, dumpPackage, dumpAppId, fieldId);
    }

    static final class ChangeRecord {
        public boolean isPending;
        public int uid;
        public int change;
        public int procState;
        public int procAdj;
        public int capability;
        public boolean ephemeral;
        public long procStateSeq;

        void copyTo(@NonNull ChangeRecord changeRecord) {
            changeRecord.isPending = isPending;
            changeRecord.uid = uid;
            changeRecord.change = change;
            changeRecord.procState = procState;
            changeRecord.procAdj = procAdj;
            changeRecord.capability = capability;
            changeRecord.ephemeral = ephemeral;
            changeRecord.procStateSeq = procStateSeq;
        }
    }

    private static final class UidObserverRegistration {
        private final int mUid;
        private final String mPkg;
        private final int mWhich;
        private final int mCutpoint;
        private final boolean mCanInteractAcrossUsers;
        private final IBinder mToken;
        private int[] mUids;

        /**
         * Total # of callback calls that took more than {@link #SLOW_UID_OBSERVER_THRESHOLD_MS}.
         * We show it in dumpsys.
         */
        int mSlowDispatchCount;

        /** Max time it took for each dispatch. */
        int mMaxDispatchTime;

        final SparseIntArray mLastProcStates;

        // Please keep the enum lists in sync
        private static final int[] ORIG_ENUMS = new int[]{
                ActivityManager.UID_OBSERVER_IDLE,
                ActivityManager.UID_OBSERVER_ACTIVE,
                ActivityManager.UID_OBSERVER_GONE,
                ActivityManager.UID_OBSERVER_PROCSTATE,
                ActivityManager.UID_OBSERVER_CAPABILITY,
                ActivityManager.UID_OBSERVER_PROC_OOM_ADJ,
        };
        private static final int[] PROTO_ENUMS = new int[]{
                ActivityManagerProto.UID_OBSERVER_FLAG_IDLE,
                ActivityManagerProto.UID_OBSERVER_FLAG_ACTIVE,
                ActivityManagerProto.UID_OBSERVER_FLAG_GONE,
                ActivityManagerProto.UID_OBSERVER_FLAG_PROCSTATE,
                ActivityManagerProto.UID_OBSERVER_FLAG_CAPABILITY,
                ActivityManagerProto.UID_OBSERVER_FLAG_PROC_OOM_ADJ,
        };

        UidObserverRegistration(int uid, @NonNull String pkg, int which, int cutpoint,
                boolean canInteractAcrossUsers, @Nullable int[] uids, @NonNull IBinder token) {
            this.mUid = uid;
            this.mPkg = pkg;
            this.mWhich = which;
            this.mCutpoint = cutpoint;
            this.mCanInteractAcrossUsers = canInteractAcrossUsers;

            if (uids != null) {
                this.mUids = uids.clone();
                Arrays.sort(this.mUids);
            } else {
                this.mUids = null;
            }

            this.mToken = token;

            mLastProcStates = cutpoint >= ActivityManager.MIN_PROCESS_STATE
                    ? new SparseIntArray() : null;
        }

        boolean isWatchingUid(int uid) {
            if (mUids == null) {
                return true;
            }

            return Arrays.binarySearch(mUids, uid) >= 0;
        }

        void addUid(int uid) {
            if (mUids == null) {
                return;
            }

            int[] temp = mUids;
            mUids = new int[temp.length + 1];
            boolean inserted = false;
            for (int i = 0; i < temp.length; i++) {
                if (!inserted) {
                    if (temp[i] < uid) {
                        mUids[i] = temp[i];
                    } else if (temp[i] == uid) {
                        // Duplicate uid, no-op and fallback to the previous array
                        mUids = temp;
                        return;
                    } else {
                        mUids[i] = uid;
                        mUids[i + 1] = temp[i];
                        inserted = true;
                    }
                } else {
                    mUids[i + 1] = temp[i];
                }
            }

            if (!inserted) {
                mUids[temp.length] = uid;
            }
        }

        void removeUid(int uid) {
            if (mUids == null || mUids.length == 0) {
                return;
            }

            int[] temp = mUids;
            mUids = new int[temp.length - 1];
            boolean removed = false;
            for (int i = 0; i < temp.length; i++) {
                if (!removed) {
                    if (temp[i] == uid) {
                        removed = true;
                    } else if (i == temp.length - 1) {
                        // Uid not found, no-op and fallback to the previous array
                        mUids = temp;
                        return;
                    } else {
                        mUids[i] = temp[i];
                    }
                } else {
                    mUids[i - 1] = temp[i];
                }
            }
        }

        IBinder getToken() {
            return mToken;
        }

        void dump(@NonNull PrintWriter pw, @NonNull IUidObserver observer) {
            pw.print("    ");
            UserHandle.formatUid(pw, mUid);
            pw.print(" ");
            pw.print(mPkg);
            pw.print(" ");
            pw.print(observer.getClass().getTypeName());
            pw.print(":");
            if ((mWhich & ActivityManager.UID_OBSERVER_IDLE) != 0) {
                pw.print(" IDLE");
            }
            if ((mWhich & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
                pw.print(" ACT");
            }
            if ((mWhich & ActivityManager.UID_OBSERVER_GONE) != 0) {
                pw.print(" GONE");
            }
            if ((mWhich & ActivityManager.UID_OBSERVER_CAPABILITY) != 0) {
                pw.print(" CAP");
            }
            if ((mWhich & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
                pw.print(" STATE");
                pw.print(" (cut=");
                pw.print(mCutpoint);
                pw.print(")");
            }
            pw.println();
            if (mLastProcStates != null) {
                final int size = mLastProcStates.size();
                for (int j = 0; j < size; j++) {
                    pw.print("      Last ");
                    UserHandle.formatUid(pw, mLastProcStates.keyAt(j));
                    pw.print(": ");
                    pw.println(mLastProcStates.valueAt(j));
                }
            }
        }

        void dumpDebug(@NonNull ProtoOutputStream proto, long fieldId) {
            final long token = proto.start(fieldId);
            proto.write(UidObserverRegistrationProto.UID, mUid);
            proto.write(UidObserverRegistrationProto.PACKAGE, mPkg);
            ProtoUtils.writeBitWiseFlagsToProtoEnum(proto, UidObserverRegistrationProto.FLAGS,
                    mWhich, ORIG_ENUMS, PROTO_ENUMS);
            proto.write(UidObserverRegistrationProto.CUT_POINT, mCutpoint);
            if (mLastProcStates != null) {
                final int size = mLastProcStates.size();
                for (int i = 0; i < size; i++) {
                    final long pToken = proto.start(UidObserverRegistrationProto.LAST_PROC_STATES);
                    proto.write(UidObserverRegistrationProto.ProcState.UID,
                            mLastProcStates.keyAt(i));
                    proto.write(UidObserverRegistrationProto.ProcState.STATE,
                            mLastProcStates.valueAt(i));
                    proto.end(pToken);
                }
            }
            proto.end(token);
        }
    }
}
