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

Commit cd95d461 authored by Martijn Coenen's avatar Martijn Coenen
Browse files

Atom and puller for historical AppOps.

This atom contains information about historical AppOps performed by
applications.

Bug: 128925078
Test: builds
      adb shell cmd stats pull-source 10060

Change-Id: Iaaec0987712779e2062139d3ad0e2d4544d4d45f
parent 4d5b76d3
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
@@ -363,6 +363,7 @@ message Atom {
        AppsOnExternalStorageInfo apps_on_external_storage_info = 10057;
        FaceSettings face_settings = 10058;
        CoolingDevice cooling_device = 10059;
        AppOps app_ops = 10060;
    }

    // DO NOT USE field numbers above 100,000 in AOSP.
@@ -6339,3 +6340,41 @@ message GarageModeInfo {
    // Whether GarageMode is entered.
    optional bool is_garage_mode = 1;
}

/**
 * Historical app ops data per package.
 */
message AppOps {
    // Uid of the package requesting the op
    optional int32 uid = 1 [(is_uid) = true];

    // Nmae 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;

    // The number of times the op was granted while the app was in the
    // foreground (only for trusted requests)
    optional int64 trusted_foreground_granted_count = 4;

    // The number of times the op was granted while the app was in the
    // background (only for trusted requests)
    optional int64 trusted_background_granted_count = 5;

    // The number of times the op was rejected while the app was in the
    // foreground (only for trusted requests)
    optional int64 trusted_foreground_rejected_count = 6;

    // The number of times the op was rejected while the app was in the
    // background (only for trusted requests)
    optional int64 trusted_background_rejected_count = 7;

    // For long-running operations, total duration of the operation
    // while the app was in the foreground (only for trusted requests)
    optional int64 trusted_foreground_duration_millis = 8;

    // For long-running operations, total duration of the operation
    // while the app was in the background (only for trusted requests)
    optional int64 trusted_background_duration_millis = 9;
}
+3 −0
Original line number Diff line number Diff line
@@ -260,6 +260,9 @@ std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = {
        // Face Settings
        {android::util::FACE_SETTINGS,
         {.puller = new StatsCompanionServicePuller(android::util::FACE_SETTINGS)}},
        // App ops
        {android::util::APP_OPS,
         {.puller = new StatsCompanionServicePuller(android::util::APP_OPS)}},
};

StatsPullerManager::StatsPullerManager() : mNextPullTimeNs(NO_ALARM_UPDATE) {
+60 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */
package com.android.server.stats;

import static android.app.AppOpsManager.OP_FLAGS_ALL_TRUSTED;
import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
import static android.content.pm.PermissionInfo.PROTECTION_DANGEROUS;
import static android.os.Process.getPidsForCommands;
@@ -33,6 +34,11 @@ import android.annotation.Nullable;
import android.app.ActivityManagerInternal;
import android.app.AlarmManager;
import android.app.AlarmManager.OnAlarmListener;
import android.app.AppOpsManager;
import android.app.AppOpsManager.HistoricalOps;
import android.app.AppOpsManager.HistoricalOpsRequest;
import android.app.AppOpsManager.HistoricalPackageOps;
import android.app.AppOpsManager.HistoricalUidOps;
import android.app.ProcessMemoryHighWaterMark;
import android.app.ProcessMemoryState;
import android.app.StatsManager;
@@ -146,6 +152,8 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -154,6 +162,7 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

@@ -1941,6 +1950,53 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
        }
    }

    private void pullAppOps(long elapsedNanos, final long wallClockNanos,
            List<StatsLogEventWrapper> pulledData) {
        long token = Binder.clearCallingIdentity();
        try {
            AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);

            CompletableFuture<HistoricalOps> ops = new CompletableFuture<>();
            HistoricalOpsRequest histOpsRequest =
                    new HistoricalOpsRequest.Builder(
                            Instant.now().minus(1, ChronoUnit.HOURS).toEpochMilli(),
                            Long.MAX_VALUE).build();
            appOps.getHistoricalOps(histOpsRequest, mContext.getMainExecutor(), ops::complete);

            HistoricalOps histOps = ops.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS,
                    TimeUnit.MILLISECONDS);

            StatsLogEventWrapper e = new StatsLogEventWrapper(StatsLog.APP_OPS, elapsedNanos,
                    wallClockNanos);

            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);
                        e.writeInt(uid);
                        e.writeString(packageOps.getPackageName());
                        e.writeInt(op.getOpCode());
                        e.writeLong(op.getForegroundAccessCount(OP_FLAGS_ALL_TRUSTED));
                        e.writeLong(op.getBackgroundAccessCount(OP_FLAGS_ALL_TRUSTED));
                        e.writeLong(op.getForegroundRejectCount(OP_FLAGS_ALL_TRUSTED));
                        e.writeLong(op.getBackgroundRejectCount(OP_FLAGS_ALL_TRUSTED));
                        e.writeLong(op.getForegroundAccessDuration(OP_FLAGS_ALL_TRUSTED));
                        e.writeLong(op.getBackgroundAccessDuration(OP_FLAGS_ALL_TRUSTED));
                        pulledData.add(e);
                    }
                }
            }
        } catch (Throwable t) {
            Log.e(TAG, "Could not read appops", t);
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }


    /**
     * Add a RoleHolder atom for each package that holds a role.
     *
@@ -2331,6 +2387,10 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
                pullFaceSettings(tagId, elapsedNanos, wallClockNanos, ret);
                break;
            }
            case StatsLog.APP_OPS: {
                pullAppOps(elapsedNanos, wallClockNanos, ret);
                break;
            }
            default:
                Slog.w(TAG, "No such tagId data as " + tagId);
                return null;