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

Commit df1b6de0 authored by Jeffrey Huang's avatar Jeffrey Huang Committed by Android (Google) Code Review
Browse files

Merge changes Id640e568,I26348987,I9da3526d

* changes:
  Update getReports
  Update getStatsMetadata
  Update getRegisteredExperimentIds
parents 28cf3a84 04f948b4
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -85,4 +85,26 @@ interface IStatsManagerService {
     * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
     */
    void unsetBroadcastSubscriber(long configKey, long subscriberId, in String packageName);

    /**
     * Returns the most recently registered experiment IDs.
     *
     * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
     */
    long[] getRegisteredExperimentIds();

    /**
     * Fetches metadata across statsd. Returns byte array representing wire-encoded proto.
     *
     * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
     */
    byte[] getMetadata(in String packageName);

    /**
     * Fetches data for the specified configuration key. Returns a byte array representing proto
     * wire-encoded of ConfigMetricsReportList.
     *
     * Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
     */
    byte[] getData(in long key, in String packageName);
}
 No newline at end of file
+2 −2
Original line number Diff line number Diff line
@@ -89,14 +89,14 @@ interface IStatsd {
     *
     * Requires Manifest.permission.DUMP.
     */
    byte[] getData(in long key, in String packageName);
    byte[] getData(in long key, int callingUid);

    /**
     * Fetches metadata across statsd. Returns byte array representing wire-encoded proto.
     *
     * Requires Manifest.permission.DUMP.
     */
    byte[] getMetadata(in String packageName);
    byte[] getMetadata();

    /**
     * Sets a configuration with the specified config key and subscribes to updates for this
+67 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.stats;
import static com.android.server.stats.StatsCompanion.PendingIntentRef;

import android.Manifest;
import android.annotation.Nullable;
import android.app.AppOpsManager;
import android.app.PendingIntent;
import android.content.Context;
@@ -245,20 +246,85 @@ public class StatsManagerService extends IStatsManagerService.Stub {
        }
    }

    @Override
    public long[] getRegisteredExperimentIds() throws IllegalStateException {
        enforceDumpAndUsageStatsPermission(null);
        final long token = Binder.clearCallingIdentity();
        try {
            IStatsd statsd = waitForStatsd();
            if (statsd != null) {
                return statsd.getRegisteredExperimentIds();
            }
        } catch (RemoteException e) {
            Slog.e(TAG, "Failed to getRegisteredExperimentIds with statsd");
            throw new IllegalStateException(e.getMessage(), e);
        } finally {
            Binder.restoreCallingIdentity(token);
        }
        throw new IllegalStateException("Failed to connect to statsd to registerExperimentIds");
    }

    @Override
    public byte[] getMetadata(String packageName) throws IllegalStateException {
        enforceDumpAndUsageStatsPermission(packageName);
        final long token = Binder.clearCallingIdentity();
        try {
            IStatsd statsd = waitForStatsd();
            if (statsd != null) {
                return statsd.getMetadata();
            }
        } catch (RemoteException e) {
            Slog.e(TAG, "Failed to getMetadata with statsd");
            throw new IllegalStateException(e.getMessage(), e);
        } finally {
            Binder.restoreCallingIdentity(token);
        }
        throw new IllegalStateException("Failed to connect to statsd to getMetadata");
    }

    @Override
    public byte[] getData(long key, String packageName) throws IllegalStateException {
        enforceDumpAndUsageStatsPermission(packageName);
        int callingUid = Binder.getCallingUid();
        final long token = Binder.clearCallingIdentity();
        try {
            IStatsd statsd = waitForStatsd();
            if (statsd != null) {
                return statsd.getData(key, callingUid);
            }
        } catch (RemoteException e) {
            Slog.e(TAG, "Failed to getData with statsd");
            throw new IllegalStateException(e.getMessage(), e);
        } finally {
            Binder.restoreCallingIdentity(token);
        }
        throw new IllegalStateException("Failed to connect to statsd to getData");
    }

    void setStatsCompanionService(StatsCompanionService statsCompanionService) {
        mStatsCompanionService = statsCompanionService;
    }

    private void enforceDumpAndUsageStatsPermission(String packageName) {
    /**
     * Checks that the caller has both DUMP and PACKAGE_USAGE_STATS permissions. Also checks that
     * the caller has USAGE_STATS_PERMISSION_OPS for the specified packageName if it is not null.
     *
     * @param packageName The packageName to check USAGE_STATS_PERMISSION_OPS.
     */
    private void enforceDumpAndUsageStatsPermission(@Nullable String packageName) {
        int callingUid = Binder.getCallingUid();
        int callingPid = Binder.getCallingPid();

        if (callingPid == Process.myPid()) {
            return;
        }

        mContext.enforceCallingPermission(Manifest.permission.DUMP, null);
        mContext.enforceCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS, null);

        if (packageName == null) {
            return;
        }
        AppOpsManager appOpsManager = (AppOpsManager) mContext
                .getSystemService(Context.APP_OPS_SERVICE);
        switch (appOpsManager.noteOp(USAGE_STATS_PERMISSION_OPS,
+7 −21
Original line number Diff line number Diff line
@@ -1135,12 +1135,11 @@ void StatsService::OnLogEvent(LogEvent* event) {
    }
}

Status StatsService::getData(int64_t key, const String16& packageName, vector<uint8_t>* output) {
    ENFORCE_DUMP_AND_USAGE_STATS(packageName);
Status StatsService::getData(int64_t key, const int32_t callingUid, vector<uint8_t>* output) {
    ENFORCE_UID(AID_SYSTEM);

    IPCThreadState* ipc = IPCThreadState::self();
    VLOG("StatsService::getData with Pid %i, Uid %i", ipc->getCallingPid(), ipc->getCallingUid());
    ConfigKey configKey(ipc->getCallingUid(), key);
    VLOG("StatsService::getData with Uid %i", callingUid);
    ConfigKey configKey(callingUid, key);
    // The dump latency does not matter here since we do not include the current bucket, we do not
    // need to pull any new data anyhow.
    mProcessor->onDumpReport(configKey, getElapsedRealtimeNs(), false /* include_current_bucket*/,
@@ -1148,12 +1147,9 @@ Status StatsService::getData(int64_t key, const String16& packageName, vector<ui
    return Status::ok();
}

Status StatsService::getMetadata(const String16& packageName, vector<uint8_t>* output) {
    ENFORCE_DUMP_AND_USAGE_STATS(packageName);
Status StatsService::getMetadata(vector<uint8_t>* output) {
    ENFORCE_UID(AID_SYSTEM);

    IPCThreadState* ipc = IPCThreadState::self();
    VLOG("StatsService::getMetadata with Pid %i, Uid %i", ipc->getCallingPid(),
         ipc->getCallingUid());
    StatsdStats::getInstance().dumpStats(output, false); // Don't reset the counters.
    return Status::ok();
}
@@ -1477,17 +1473,7 @@ Status StatsService::sendWatchdogRollbackOccurredAtom(const int32_t rollbackType


Status StatsService::getRegisteredExperimentIds(std::vector<int64_t>* experimentIdsOut) {
    uid_t uid = IPCThreadState::self()->getCallingUid();

    // Caller must be granted these permissions
    if (!checkCallingPermission(String16(kPermissionDump))) {
        return exception(binder::Status::EX_SECURITY,
                         StringPrintf("UID %d lacks permission %s", uid, kPermissionDump));
    }
    if (!checkCallingPermission(String16(kPermissionUsage))) {
        return exception(binder::Status::EX_SECURITY,
                         StringPrintf("UID %d lacks permission %s", uid, kPermissionUsage));
    }
    ENFORCE_UID(AID_SYSTEM);
    // TODO: add verifier permission

    // Read the latest train info
+2 −3
Original line number Diff line number Diff line
@@ -99,15 +99,14 @@ public:
     * Binder call for clients to request data for this configuration key.
     */
    virtual Status getData(int64_t key,
                           const String16& packageName,
                           const int32_t callingUid,
                           vector<uint8_t>* output) override;


    /**
     * Binder call for clients to get metadata across all configs in statsd.
     */
    virtual Status getMetadata(const String16& packageName,
                               vector<uint8_t>* output) override;
    virtual Status getMetadata(vector<uint8_t>* output) override;


    /**
Loading