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

Commit 48811ee6 authored by Stanislav Zholnin's avatar Stanislav Zholnin
Browse files

Add logging operation ids.

Add operation ids which are used only for logging. They will
allow to reduce bandwidth required for logging. Mapping between
operation string ids (OPSTR_, public API) and Logging ids
is enforced by statsd CTS test.

Bug:143519689
Test: android.cts.statsd.atom.UidAtomTests#testAppOps
Test: android.cts.statsd.atom.UidAtomTests#testForegroundServiceAccessAppOp
Exempt-From-Owner-Approval: discussed  with moltmann@ in chat.

Change-Id: I2f85d6889e946219557d26b28334d4bacde06b12
Merged-In: I2f85d6889e946219557d26b28334d4bacde06b12
parent b4decfc1
Loading
Loading
Loading
Loading
+10 −14
Original line number Diff line number Diff line
@@ -3332,16 +3332,12 @@ message ForegroundServiceAppOpSessionEnded {
    optional int32 uid = 1 [(is_uid) = true];

    // The operation's name.
    // To the extent possible, preserve the mapping from AppOpsManager.OP_ constants.
    // Only these named ops are actually logged.
    enum AppOpName {
        OP_NONE = -1; // Also represents UNKNOWN.
        OP_COARSE_LOCATION = 0;
        OP_FINE_LOCATION = 1;
        OP_CAMERA = 26;
        OP_RECORD_AUDIO = 27;
    }
    optional AppOpName app_op_name = 2 [default = OP_NONE];
    // Only following four ops are logged
    // COARSE_LOCATION = 0
    // FINE_LOCATION = 1
    // CAMERA = 26
    // RECORD_AUDIO = 27
    optional android.app.AppOpEnum app_op_name = 2 [default = APP_OP_NONE];

    // The uid's permission mode for accessing the AppOp during this fgs session.
    enum Mode {
@@ -7571,8 +7567,8 @@ message AppOps {
    // Name of the package performing the op
    optional string package_name = 2;

    // operation id; maps to the OP_* constants in AppOpsManager.java
    optional int32 op_id = 3;
    // operation id
    optional android.app.AppOpEnum op_id = 3 [default = APP_OP_NONE];

    // The number of times the op was granted while the app was in the
    // foreground (only for trusted requests)
@@ -7617,8 +7613,8 @@ message AttributedAppOps {
    // above.
    optional string tag = 3;

    // operation id; maps to the OPSTR_* constants in AppOpsManager.java
    optional string op = 4;
    // operation id
    optional android.app.AppOpEnum op = 4 [default = APP_OP_NONE];

    // The number of times the op was granted while the app was in the
    // foreground (only for trusted requests)
+126 −0
Original line number Diff line number Diff line
@@ -2333,6 +2333,114 @@ public class AppOpsManager {
            false, // AUTO_REVOKE_MANAGED_BY_INSTALLER
    };

    /**
     * This maps each operation to its statsd logging code.
     */
    private static int[] sOpToLoggingId = new int[]{
            AppProtoEnums.APP_OP_COARSE_LOCATION, // OP_COARSE_LOCATION
            AppProtoEnums.APP_OP_FINE_LOCATION, // OP_FINE_LOCATION
            AppProtoEnums.APP_OP_GPS, // OP_ID__GPS
            AppProtoEnums.APP_OP_VIBRATE, // OP_VIBRATE
            AppProtoEnums.APP_OP_READ_CONTACTS, // OP_READ_CONTACTS
            AppProtoEnums.APP_OP_WRITE_CONTACTS, // OP_WRITE_CONTACTS
            AppProtoEnums.APP_OP_READ_CALL_LOG, // OP_READ_CALL_LOG
            AppProtoEnums.APP_OP_WRITE_CALL_LOG, // OP_WRITE_CALL_LOG
            AppProtoEnums.APP_OP_READ_CALENDAR, // OP_READ_CALENDAR
            AppProtoEnums.APP_OP_WRITE_CALENDAR, // OP_WRITE_CALENDAR
            AppProtoEnums.APP_OP_WIFI_SCAN, // OP_WIFI_SCAN
            AppProtoEnums.APP_OP_POST_NOTIFICATION, // OP_POST_NOTIFICATION
            AppProtoEnums.APP_OP_NEIGHBORING_CELLS, // OP_NEIGHBORING_CELLS
            AppProtoEnums.APP_OP_CALL_PHONE, // OP_CALL_PHONE
            AppProtoEnums.APP_OP_READ_SMS, // OP_READ_SMS
            AppProtoEnums.APP_OP_WRITE_SMS, // OP_WRITE_SMS
            AppProtoEnums.APP_OP_RECEIVE_SMS, // OP_RECEIVE_SMS
            AppProtoEnums.APP_OP_RECEIVE_EMERGENCY_SMS, // OP_RECEIVE_EMERGENCY_SMS
            AppProtoEnums.APP_OP_RECEIVE_MMS, // OP_RECEIVE_MMS
            AppProtoEnums.APP_OP_RECEIVE_WAP_PUSH, // OP_RECEIVE_WAP_PUSH
            AppProtoEnums.APP_OP_SEND_SMS, // OP_SEND_SMS
            AppProtoEnums.APP_OP_READ_ICC_SMS, // OP_READ_ICC_SMS
            AppProtoEnums.APP_OP_WRITE_ICC_SMS, // OP_WRITE_ICC_SMS
            AppProtoEnums.APP_OP_WRITE_SETTINGS, // OP_WRITE_SETTINGS
            AppProtoEnums.APP_OP_SYSTEM_ALERT_WINDOW, // OP_SYSTEM_ALERT_WINDOW
            AppProtoEnums.APP_OP_ACCESS_NOTIFICATIONS, // OP_ACCESS_NOTIFICATIONS
            AppProtoEnums.APP_OP_CAMERA, // OP_CAMERA
            AppProtoEnums.APP_OP_RECORD_AUDIO, // OP_RECORD_AUDIO
            AppProtoEnums.APP_OP_PLAY_AUDIO, // OP_PLAY_AUDIO
            AppProtoEnums.APP_OP_READ_CLIPBOARD, // OP_READ_CLIPBOARD
            AppProtoEnums.APP_OP_WRITE_CLIPBOARD, // OP_WRITE_CLIPBOARD
            AppProtoEnums.APP_OP_TAKE_MEDIA_BUTTONS, // OP_TAKE_MEDIA_BUTTONS
            AppProtoEnums.APP_OP_TAKE_AUDIO_FOCUS, // OP_TAKE_AUDIO_FOCUS
            AppProtoEnums.APP_OP_AUDIO_MASTER_VOLUME, // OP_AUDIO_MASTER_VOLUME
            AppProtoEnums.APP_OP_AUDIO_VOICE_VOLUME, // OP_AUDIO_VOICE_VOLUME
            AppProtoEnums.APP_OP_AUDIO_RING_VOLUME, // OP_AUDIO_RING_VOLUME
            AppProtoEnums.APP_OP_AUDIO_MEDIA_VOLUME, // OP_AUDIO_MEDIA_VOLUME
            AppProtoEnums.APP_OP_AUDIO_ALARM_VOLUME, // OP_AUDIO_ALARM_VOLUME
            AppProtoEnums.APP_OP_AUDIO_NOTIFICATION_VOLUME, // OP_AUDIO_NOTIFICATION_VOLUME
            AppProtoEnums.APP_OP_AUDIO_BLUETOOTH_VOLUME, // OP_AUDIO_BLUETOOTH_VOLUME
            AppProtoEnums.APP_OP_WAKE_LOCK, // OP_WAKE_LOCK
            AppProtoEnums.APP_OP_MONITOR_LOCATION, // OP_MONITOR_LOCATION
            AppProtoEnums.APP_OP_MONITOR_HIGH_POWER_LOCATION, // OP_MONITOR_HIGH_POWER_LOCATION
            AppProtoEnums.APP_OP_GET_USAGE_STATS, // OP_GET_USAGE_STATS
            AppProtoEnums.APP_OP_MUTE_MICROPHONE, //OP_MUTE_MICROPHONE
            AppProtoEnums.APP_OP_TOAST_WINDOW, // OP_TOAST_WINDOW
            AppProtoEnums.APP_OP_PROJECT_MEDIA, // OP_PROJECT_MEDIA
            AppProtoEnums.APP_OP_ACTIVATE_VPN, // OP_ACTIVATE_VPN
            AppProtoEnums.APP_OP_WRITE_WALLPAPER, // OP_WRITE_WALLPAPER
            AppProtoEnums.APP_OP_ASSIST_STRUCTURE, // OP_ASSIST_STRUCTURE
            AppProtoEnums.APP_OP_ASSIST_SCREENSHOT, // OP_ASSIST_SCREENSHOT
            AppProtoEnums.APP_OP_READ_PHONE_STATE, // OP_READ_PHONE_STATE
            AppProtoEnums.APP_OP_ADD_VOICEMAIL, // OP_ADD_VOICEMAIL
            AppProtoEnums.APP_OP_USE_SIP, // OP_USE_SIP
            AppProtoEnums.APP_OP_PROCESS_OUTGOING_CALLS, // OP_PROCESS_OUTGOING_CALLS
            AppProtoEnums.APP_OP_USE_FINGERPRINT, // OP_USE_FINGERPRINT
            AppProtoEnums.APP_OP_BODY_SENSORS, // OP_BODY_SENSORS
            AppProtoEnums.APP_OP_READ_CELL_BROADCASTS, // OP_READ_CELL_BROADCASTS
            AppProtoEnums.APP_OP_MOCK_LOCATION, // OP_MOCK_LOCATION
            AppProtoEnums.APP_OP_READ_EXTERNAL_STORAGE, // OP_READ_EXTERNAL_STORAGE
            AppProtoEnums.APP_OP_WRITE_EXTERNAL_STORAGE, // OP_WRITE_EXTERNAL_STORAGE
            AppProtoEnums.APP_OP_TURN_SCREEN_ON, // OP_TURN_SCREEN_ON
            AppProtoEnums.APP_OP_GET_ACCOUNTS, // OP_GET_ACCOUNTS
            AppProtoEnums.APP_OP_RUN_IN_BACKGROUND, // OP_RUN_IN_BACKGROUND
            AppProtoEnums.APP_OP_AUDIO_ACCESSIBILITY_VOLUME, // OP_AUDIO_ACCESSIBILITY_VOLUME
            AppProtoEnums.APP_OP_READ_PHONE_NUMBERS, // OP_READ_PHONE_NUMBERS
            AppProtoEnums.APP_OP_REQUEST_INSTALL_PACKAGES, // OP_REQUEST_INSTALL_PACKAGES
            AppProtoEnums.APP_OP_PICTURE_IN_PICTURE, // OP_PICTURE_IN_PICTURE
            AppProtoEnums.APP_OP_INSTANT_APP_START_FOREGROUND, // OP_INSTANT_APP_START_FOREGROUND
            AppProtoEnums.APP_OP_ANSWER_PHONE_CALLS, // OP_ANSWER_PHONE_CALLS
            AppProtoEnums.APP_OP_RUN_ANY_IN_BACKGROUND, // OP_RUN_ANY_IN_BACKGROUND
            AppProtoEnums.APP_OP_CHANGE_WIFI_STATE, // OP_CHANGE_WIFI_STATE
            AppProtoEnums.APP_OP_REQUEST_DELETE_PACKAGES, // OP_REQUEST_DELETE_PACKAGES
            AppProtoEnums.APP_OP_BIND_ACCESSIBILITY_SERVICE, // OP_BIND_ACCESSIBILITY_SERVICE
            AppProtoEnums.APP_OP_ACCEPT_HANDOVER, // OP_ACCEPT_HANDOVER
            AppProtoEnums.APP_OP_MANAGE_IPSEC_TUNNELS, // OP_MANAGE_IPSEC_TUNNELS
            AppProtoEnums.APP_OP_START_FOREGROUND, // OP_START_FOREGROUND
            AppProtoEnums.APP_OP_BLUETOOTH_SCAN, // OP_BLUETOOTH_SCAN
            AppProtoEnums.APP_OP_USE_BIOMETRIC, // OP_USE_BIOMETRIC
            AppProtoEnums.APP_OP_ACTIVITY_RECOGNITION, // OP_ACTIVITY_RECOGNITION
            AppProtoEnums.APP_OP_SMS_FINANCIAL_TRANSACTIONS, // OP_SMS_FINANCIAL_TRANSACTIONS
            AppProtoEnums.APP_OP_READ_MEDIA_AUDIO, // OP_READ_MEDIA_AUDIO
            AppProtoEnums.APP_OP_WRITE_MEDIA_AUDIO, // OP_WRITE_MEDIA_AUDIO
            AppProtoEnums.APP_OP_READ_MEDIA_VIDEO, // OP_READ_MEDIA_VIDEO
            AppProtoEnums.APP_OP_WRITE_MEDIA_VIDEO, // OP_WRITE_MEDIA_VIDEO
            AppProtoEnums.APP_OP_READ_MEDIA_IMAGES, // OP_READ_MEDIA_IMAGES
            AppProtoEnums.APP_OP_WRITE_MEDIA_IMAGES, // OP_WRITE_MEDIA_IMAGES
            AppProtoEnums.APP_OP_LEGACY_STORAGE, // OP_LEGACY_STORAGE
            AppProtoEnums.APP_OP_ACCESS_ACCESSIBILITY, // OP_ACCESS_ACCESSIBILITY
            AppProtoEnums.APP_OP_READ_DEVICE_IDENTIFIERS, // OP_READ_DEVICE_IDENTIFIERS
            AppProtoEnums.APP_OP_ACCESS_MEDIA_LOCATION, // OP_ACCESS_MEDIA_LOCATION
            AppProtoEnums.APP_OP_QUERY_ALL_PACKAGES, // OP_QUERY_ALL_PACKAGES
            AppProtoEnums.APP_OP_MANAGE_EXTERNAL_STORAGE, // OP_MANAGE_EXTERNAL_STORAGE
            AppProtoEnums.APP_OP_INTERACT_ACROSS_PROFILES, // OP_INTERACT_ACROSS_PROFILES
            AppProtoEnums.APP_OP_ACTIVATE_PLATFORM_VPN, // OP_ACTIVATE_PLATFORM_VPN
            AppProtoEnums.APP_OP_LOADER_USAGE_STATS, // OP_LOADER_USAGE_STATS
            AppProtoEnums.APP_OP_ACCESS_CALL_AUDIO, // OP_ACCESS_CALL_AUDIO
            AppProtoEnums.APP_OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED,
            // OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED
            AppProtoEnums.APP_OP_AUTO_REVOKE_MANAGED_BY_INSTALLER 
            //OP_AUTO_REVOKE_MANAGED_BY_INSTALLER
    };


    /**
     * Mapping from an app op name to the app op code.
     */
@@ -2374,6 +2482,10 @@ public class AppOpsManager {
            throw new IllegalStateException("sOpToString length " + sOpToString.length
                    + " should be " + _NUM_OP);
        }
        if (sOpToLoggingId.length != _NUM_OP) {
            throw new IllegalStateException("sOpToLoggingId length " + sOpToLoggingId.length
                    + " should be " + _NUM_OP);
        }
        if (sOpNames.length != _NUM_OP) {
            throw new IllegalStateException("sOpNames length " + sOpNames.length
                    + " should be " + _NUM_OP);
@@ -2457,6 +2569,15 @@ public class AppOpsManager {
        return sOpToString[op];
    }

    /**
     * Retrieve a logging id for the operation.
     *
     * @hide
     */
    public static int opToLoggingId(int op) {
        return sOpToLoggingId[op];
    }

    /**
     * @hide
     */
@@ -5911,6 +6032,11 @@ public class AppOpsManager {
            return mOp;
        }

        /** @hide */
        public int getLoggingOpCode() {
            return AppOpsManager.opToLoggingId(mOp);
        }

        /**
         * Gets the number times the op was accessed (performed) in the foreground.
         *
+105 −0
Original line number Diff line number Diff line
@@ -104,3 +104,108 @@ enum ProcessStateEnum {
    PROCESS_STATE_NONEXISTENT = 1019;
}

// AppOpsManager.java - operation ids for logging
enum AppOpEnum {
    APP_OP_NONE = -1;
    APP_OP_COARSE_LOCATION = 0;
    APP_OP_FINE_LOCATION = 1;
    APP_OP_GPS = 2;
    APP_OP_VIBRATE = 3;
    APP_OP_READ_CONTACTS = 4;
    APP_OP_WRITE_CONTACTS = 5;
    APP_OP_READ_CALL_LOG = 6;
    APP_OP_WRITE_CALL_LOG = 7;
    APP_OP_READ_CALENDAR = 8;
    APP_OP_WRITE_CALENDAR = 9;
    APP_OP_WIFI_SCAN = 10;
    APP_OP_POST_NOTIFICATION = 11;
    APP_OP_NEIGHBORING_CELLS = 12;
    APP_OP_CALL_PHONE = 13;
    APP_OP_READ_SMS = 14;
    APP_OP_WRITE_SMS = 15;
    APP_OP_RECEIVE_SMS = 16;
    APP_OP_RECEIVE_EMERGENCY_SMS = 17;
    APP_OP_RECEIVE_MMS = 18;
    APP_OP_RECEIVE_WAP_PUSH = 19;
    APP_OP_SEND_SMS = 20;
    APP_OP_READ_ICC_SMS = 21;
    APP_OP_WRITE_ICC_SMS = 22;
    APP_OP_WRITE_SETTINGS = 23;
    APP_OP_SYSTEM_ALERT_WINDOW = 24;
    APP_OP_ACCESS_NOTIFICATIONS = 25;
    APP_OP_CAMERA = 26;
    APP_OP_RECORD_AUDIO = 27;
    APP_OP_PLAY_AUDIO = 28;
    APP_OP_READ_CLIPBOARD = 29;
    APP_OP_WRITE_CLIPBOARD = 30;
    APP_OP_TAKE_MEDIA_BUTTONS = 31;
    APP_OP_TAKE_AUDIO_FOCUS = 32;
    APP_OP_AUDIO_MASTER_VOLUME = 33;
    APP_OP_AUDIO_VOICE_VOLUME = 34;
    APP_OP_AUDIO_RING_VOLUME = 35;
    APP_OP_AUDIO_MEDIA_VOLUME = 36;
    APP_OP_AUDIO_ALARM_VOLUME = 37;
    APP_OP_AUDIO_NOTIFICATION_VOLUME = 38;
    APP_OP_AUDIO_BLUETOOTH_VOLUME = 39;
    APP_OP_WAKE_LOCK = 40;
    APP_OP_MONITOR_LOCATION = 41;
    APP_OP_MONITOR_HIGH_POWER_LOCATION = 42;
    APP_OP_GET_USAGE_STATS = 43;
    APP_OP_MUTE_MICROPHONE = 44;
    APP_OP_TOAST_WINDOW = 45;
    APP_OP_PROJECT_MEDIA = 46;
    APP_OP_ACTIVATE_VPN = 47;
    APP_OP_WRITE_WALLPAPER = 48;
    APP_OP_ASSIST_STRUCTURE = 49;
    APP_OP_ASSIST_SCREENSHOT = 50;
    APP_OP_READ_PHONE_STATE = 51;
    APP_OP_ADD_VOICEMAIL = 52;
    APP_OP_USE_SIP = 53;
    APP_OP_PROCESS_OUTGOING_CALLS = 54;
    APP_OP_USE_FINGERPRINT = 55;
    APP_OP_BODY_SENSORS = 56;
    APP_OP_READ_CELL_BROADCASTS = 57;
    APP_OP_MOCK_LOCATION = 58;
    APP_OP_READ_EXTERNAL_STORAGE = 59;
    APP_OP_WRITE_EXTERNAL_STORAGE = 60;
    APP_OP_TURN_SCREEN_ON = 61;
    APP_OP_GET_ACCOUNTS = 62;
    APP_OP_RUN_IN_BACKGROUND = 63;
    APP_OP_AUDIO_ACCESSIBILITY_VOLUME = 64;
    APP_OP_READ_PHONE_NUMBERS = 65;
    APP_OP_REQUEST_INSTALL_PACKAGES = 66;
    APP_OP_PICTURE_IN_PICTURE = 67;
    APP_OP_INSTANT_APP_START_FOREGROUND = 68;
    APP_OP_ANSWER_PHONE_CALLS = 69;
    APP_OP_RUN_ANY_IN_BACKGROUND = 70;
    APP_OP_CHANGE_WIFI_STATE = 71;
    APP_OP_REQUEST_DELETE_PACKAGES = 72;
    APP_OP_BIND_ACCESSIBILITY_SERVICE = 73;
    APP_OP_ACCEPT_HANDOVER = 74;
    APP_OP_MANAGE_IPSEC_TUNNELS = 75;
    APP_OP_START_FOREGROUND = 76;
    APP_OP_BLUETOOTH_SCAN = 77;
    APP_OP_USE_BIOMETRIC = 78;
    APP_OP_ACTIVITY_RECOGNITION = 79;
    APP_OP_SMS_FINANCIAL_TRANSACTIONS = 80;
    APP_OP_READ_MEDIA_AUDIO = 81;
    APP_OP_WRITE_MEDIA_AUDIO = 82;
    APP_OP_READ_MEDIA_VIDEO = 83;
    APP_OP_WRITE_MEDIA_VIDEO = 84;
    APP_OP_READ_MEDIA_IMAGES = 85;
    APP_OP_WRITE_MEDIA_IMAGES = 86;
    APP_OP_LEGACY_STORAGE = 87;
    APP_OP_ACCESS_ACCESSIBILITY = 88;
    APP_OP_READ_DEVICE_IDENTIFIERS = 89;
    APP_OP_ACCESS_MEDIA_LOCATION = 90;
    APP_OP_QUERY_ALL_PACKAGES = 91;
    APP_OP_MANAGE_EXTERNAL_STORAGE = 92;
    APP_OP_INTERACT_ACROSS_PROFILES = 93;
    APP_OP_ACTIVATE_PLATFORM_VPN = 94;
    APP_OP_LOADER_USAGE_STATS = 95;
    APP_OP_ACCESS_CALL_AUDIO = 96;
    APP_OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED = 97;
    APP_OP_AUTO_REVOKE_MANAGED_BY_INSTALLER = 98;
}

+1 −17
Original line number Diff line number Diff line
@@ -1701,7 +1701,7 @@ public final class ActiveServices {
                    if (acceptances > 0 ||  rejections > 0) {
                        FrameworkStatsLog.write(
                                FrameworkStatsLog.FOREGROUND_SERVICE_APP_OP_SESSION_ENDED,
                                mProcessRecord.uid, opToEnum(op),
                                mProcessRecord.uid, AppOpsManager.opToLoggingId(op),
                                modeToEnum(mAppOpModes.get(op)),
                                acceptances, rejections
                        );
@@ -1725,22 +1725,6 @@ public final class ActiveServices {
        }
    }

    /** Maps AppOp op value to atoms.proto enum. */
    private static int opToEnum(int op) {
        switch (op) {
            case AppOpsManager.OP_COARSE_LOCATION: return FrameworkStatsLog
                    .FOREGROUND_SERVICE_APP_OP_SESSION_ENDED__APP_OP_NAME__OP_COARSE_LOCATION;
            case AppOpsManager.OP_FINE_LOCATION: return FrameworkStatsLog
                    .FOREGROUND_SERVICE_APP_OP_SESSION_ENDED__APP_OP_NAME__OP_FINE_LOCATION;
            case AppOpsManager.OP_CAMERA: return FrameworkStatsLog
                    .FOREGROUND_SERVICE_APP_OP_SESSION_ENDED__APP_OP_NAME__OP_CAMERA;
            case AppOpsManager.OP_RECORD_AUDIO: return FrameworkStatsLog
                    .FOREGROUND_SERVICE_APP_OP_SESSION_ENDED__APP_OP_NAME__OP_RECORD_AUDIO;
            default: return FrameworkStatsLog
                    .FOREGROUND_SERVICE_APP_OP_SESSION_ENDED__APP_OP_NAME__OP_NONE;
        }
    }

    private void cancelForegroundNotificationLocked(ServiceRecord r) {
        if (r.foregroundId != 0) {
            // First check to see if this app has any other active foreground services
+39 −5
Original line number Diff line number Diff line
@@ -2888,6 +2888,44 @@ public class StatsPullAtomService extends SystemService {
            HistoricalOps histOps = ops.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS,
                    TimeUnit.MILLISECONDS);
            processHistoricalOps(histOps, atomTag, pulledData);

            for (int uidIdx = 0; uidIdx < histOps.getUidCount(); uidIdx++) {
                final HistoricalUidOps uidOps = histOps.getUidOpsAt(uidIdx);
                final int uid = uidOps.getUid();
                for (int pkgIdx = 0; pkgIdx < uidOps.getPackageCount(); pkgIdx++) {
                    final HistoricalPackageOps packageOps = uidOps.getPackageOpsAt(pkgIdx);
                    for (int opIdx = 0; opIdx < packageOps.getOpCount(); opIdx++) {
                        final AppOpsManager.HistoricalOp op = packageOps.getOpAt(opIdx);

                        StatsEvent.Builder e = StatsEvent.newBuilder();
                        e.setAtomId(atomTag);
                        e.writeInt(uid);
                        e.writeString(packageOps.getPackageName());
                        e.writeInt(op.getLoggingOpCode());
                        e.writeLong(op.getForegroundAccessCount(OP_FLAGS_PULLED));
                        e.writeLong(op.getBackgroundAccessCount(OP_FLAGS_PULLED));
                        e.writeLong(op.getForegroundRejectCount(OP_FLAGS_PULLED));
                        e.writeLong(op.getBackgroundRejectCount(OP_FLAGS_PULLED));
                        e.writeLong(op.getForegroundAccessDuration(OP_FLAGS_PULLED));
                        e.writeLong(op.getBackgroundAccessDuration(OP_FLAGS_PULLED));

                        String perm = AppOpsManager.opToPermission(op.getOpCode());
                        if (perm == null) {
                            e.writeBoolean(false);
                        } else {
                            PermissionInfo permInfo;
                            try {
                                permInfo = mContext.getPackageManager().getPermissionInfo(perm, 0);
                                e.writeBoolean(permInfo.getProtection() == PROTECTION_DANGEROUS);
                            } catch (PackageManager.NameNotFoundException exception) {
                                e.writeBoolean(false);
                            }
                        }

                        pulledData.add(e.build());
                    }
                }
            }
        } catch (Throwable t) {
            // TODO: catch exceptions at a more granular level
            Slog.e(TAG, "Could not read appops", t);
@@ -3006,11 +3044,7 @@ public class StatsPullAtomService extends SystemService {
        if (atomTag == FrameworkStatsLog.ATTRIBUTED_APP_OPS) {
            e.writeString(attributionTag);
        }
        if (atomTag == FrameworkStatsLog.ATTRIBUTED_APP_OPS) {
            e.writeString(op.getOpName());
        } else {
            e.writeInt(op.getOpCode());
        }
        e.writeInt(op.getLoggingOpCode());
        e.writeLong(op.getForegroundAccessCount(OP_FLAGS_PULLED));
        e.writeLong(op.getBackgroundAccessCount(OP_FLAGS_PULLED));
        e.writeLong(op.getForegroundRejectCount(OP_FLAGS_PULLED));