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

Commit 7efd8a8c authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 4725392 from 34a0b18a to pi-release

Change-Id: Ifaf1b911565819b2bd1f466eaa61a1292868f497
parents dc934719 34a0b18a
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -485,6 +485,15 @@ void StatsLogProcessor::informPullAlarmFired(const int64_t timestampNs) {
    mStatsPullerManager.OnAlarmFired(timestampNs);
}

int64_t StatsLogProcessor::getLastReportTimeNs(const ConfigKey& key) {
    auto it = mMetricsManagers.find(key);
    if (it == mMetricsManagers.end()) {
        return 0;
    } else {
        return it->second->getLastReportTimeNs();
    }
}

}  // namespace statsd
}  // namespace os
}  // namespace android
+2 −0
Original line number Diff line number Diff line
@@ -75,6 +75,8 @@ public:

    void informPullAlarmFired(const int64_t timestampNs);

    int64_t getLastReportTimeNs(const ConfigKey& key);

private:
    // For testing only.
    inline sp<AlarmMonitor> getAnomalyAlarmMonitor() const {
+125 −92
Original line number Diff line number Diff line
@@ -27,8 +27,10 @@
#include "subscriber/SubscriberReporter.h"

#include <android-base/file.h>
#include <android-base/stringprintf.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/PermissionController.h>
#include <dirent.h>
#include <frameworks/base/cmds/statsd/src/statsd_config.pb.h>
#include <private/android_filesystem_config.h>
@@ -42,13 +44,83 @@

using namespace android;

using android::base::StringPrintf;

namespace android {
namespace os {
namespace statsd {

constexpr const char* kPermissionDump = "android.permission.DUMP";
constexpr const char* kPermissionUsage = "android.permission.PACKAGE_USAGE_STATS";

constexpr const char* kOpUsage = "android:get_usage_stats";

#define STATS_SERVICE_DIR "/data/misc/stats-service"

static binder::Status ok() {
    return binder::Status::ok();
}

static binder::Status exception(uint32_t code, const std::string& msg) {
    ALOGE("%s (%d)", msg.c_str(), code);
    return binder::Status::fromExceptionCode(code, String8(msg.c_str()));
}

binder::Status checkUid(uid_t expectedUid) {
    uid_t uid = IPCThreadState::self()->getCallingUid();
    if (uid == expectedUid || uid == AID_ROOT) {
        return ok();
    } else {
        return exception(binder::Status::EX_SECURITY,
                StringPrintf("UID %d is not expected UID %d", uid, expectedUid));
    }
}

binder::Status checkDumpAndUsageStats(const String16& packageName) {
    pid_t pid = IPCThreadState::self()->getCallingPid();
    uid_t uid = IPCThreadState::self()->getCallingUid();

    // Root, system, and shell always have access
    if (uid == AID_ROOT || uid == AID_SYSTEM || uid == AID_SHELL) {
        return ok();
    }

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

    // Caller must also have usage stats op granted
    PermissionController pc;
    switch (pc.noteOp(String16(kOpUsage), uid, packageName)) {
        case PermissionController::MODE_ALLOWED:
        case PermissionController::MODE_DEFAULT:
            return ok();
        default:
            return exception(binder::Status::EX_SECURITY,
                    StringPrintf("UID %d / PID %d lacks app-op %s", uid, pid, kOpUsage));
    }
}

#define ENFORCE_UID(uid) {                                        \
    binder::Status status = checkUid((uid));                      \
    if (!status.isOk()) {                                         \
        return status;                                            \
    }                                                             \
}

#define ENFORCE_DUMP_AND_USAGE_STATS(packageName) {               \
    binder::Status status = checkDumpAndUsageStats(packageName);  \
    if (!status.isOk()) {                                         \
        return status;                                            \
    }                                                             \
}

StatsService::StatsService(const sp<Looper>& handlerLooper)
    : mAnomalyAlarmMonitor(new AlarmMonitor(MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS,
       [](const sp<IStatsCompanionService>& sc, int64_t timeMillis) {
@@ -90,7 +162,7 @@ StatsService::StatsService(const sp<Looper>& handlerLooper)
            VLOG("Statscompanion could not find a broadcast receiver for %s",
                 key.ToString().c_str());
        } else {
            sc->sendDataBroadcast(receiver);
            sc->sendDataBroadcast(receiver, mProcessor->getLastReportTimeNs(key));
        }
    }
    );
@@ -212,7 +284,10 @@ void StatsService::dump_impl(FILE* out, bool verbose, bool proto) {
 * Implementation of the adb shell cmd stats command.
 */
status_t StatsService::command(FILE* in, FILE* out, FILE* err, Vector<String8>& args) {
    // TODO: Permission check
    uid_t uid = IPCThreadState::self()->getCallingUid();
    if (uid != AID_ROOT && uid != AID_SHELL) {
        return PERMISSION_DENIED;
    }

    const int argCount = args.size();
    if (argCount >= 1) {
@@ -377,14 +452,15 @@ status_t StatsService::cmd_trigger_broadcast(FILE* out, Vector<String8>& args) {
        print_cmd_help(out);
        return UNKNOWN_ERROR;
    }
    auto receiver = mConfigManager->GetConfigReceiver(ConfigKey(uid, StrToInt64(name)));
    ConfigKey key(uid, StrToInt64(name));
    auto receiver = mConfigManager->GetConfigReceiver(key);
    sp<IStatsCompanionService> sc = getStatsCompanionService();
    if (sc == nullptr) {
        VLOG("Could not access statsCompanion");
    } else if (receiver == nullptr) {
        VLOG("Could not find receiver for %s, %s", args[1].c_str(), args[2].c_str())
    } else {
        sc->sendDataBroadcast(receiver);
        sc->sendDataBroadcast(receiver, mProcessor->getLastReportTimeNs(key));
        VLOG("StatsService::trigger broadcast succeeded to %s, %s", args[1].c_str(),
             args[2].c_str());
    }
@@ -660,13 +736,9 @@ status_t StatsService::cmd_clear_puller_cache(FILE* out) {

Status StatsService::informAllUidData(const vector<int32_t>& uid, const vector<int64_t>& version,
                                      const vector<String16>& app) {
    VLOG("StatsService::informAllUidData was called");

    if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
        return Status::fromExceptionCode(Status::EX_SECURITY,
                                         "Only system uid can call informAllUidData");
    }
    ENFORCE_UID(AID_SYSTEM);

    VLOG("StatsService::informAllUidData was called");
    mUidMap->updateMap(getElapsedRealtimeNs(), uid, version, app);
    VLOG("StatsService::informAllUidData succeeded");

@@ -674,36 +746,26 @@ Status StatsService::informAllUidData(const vector<int32_t>& uid, const vector<i
}

Status StatsService::informOnePackage(const String16& app, int32_t uid, int64_t version) {
    VLOG("StatsService::informOnePackage was called");
    ENFORCE_UID(AID_SYSTEM);

    if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
        return Status::fromExceptionCode(Status::EX_SECURITY,
                                         "Only system uid can call informOnePackage");
    }
    VLOG("StatsService::informOnePackage was called");
    mUidMap->updateApp(getElapsedRealtimeNs(), app, uid, version);
    return Status::ok();
}

Status StatsService::informOnePackageRemoved(const String16& app, int32_t uid) {
    VLOG("StatsService::informOnePackageRemoved was called");
    ENFORCE_UID(AID_SYSTEM);

    if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
        return Status::fromExceptionCode(Status::EX_SECURITY,
                                         "Only system uid can call informOnePackageRemoved");
    }
    VLOG("StatsService::informOnePackageRemoved was called");
    mUidMap->removeApp(getElapsedRealtimeNs(), app, uid);
    mConfigManager->RemoveConfigs(uid);
    return Status::ok();
}

Status StatsService::informAnomalyAlarmFired() {
    VLOG("StatsService::informAnomalyAlarmFired was called");

    if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
        return Status::fromExceptionCode(Status::EX_SECURITY,
                                         "Only system uid can call informAnomalyAlarmFired");
    }
    ENFORCE_UID(AID_SYSTEM);

    VLOG("StatsService::informAnomalyAlarmFired was called");
    int64_t currentTimeSec = getElapsedRealtimeSec();
    std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet =
            mAnomalyAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
@@ -717,14 +779,9 @@ Status StatsService::informAnomalyAlarmFired() {
}

Status StatsService::informAlarmForSubscriberTriggeringFired() {
    VLOG("StatsService::informAlarmForSubscriberTriggeringFired was called");

    if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
        return Status::fromExceptionCode(
                Status::EX_SECURITY,
                "Only system uid can call informAlarmForSubscriberTriggeringFired");
    }
    ENFORCE_UID(AID_SYSTEM);

    VLOG("StatsService::informAlarmForSubscriberTriggeringFired was called");
    int64_t currentTimeSec = getElapsedRealtimeSec();
    std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet =
            mPeriodicAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
@@ -738,44 +795,28 @@ Status StatsService::informAlarmForSubscriberTriggeringFired() {
}

Status StatsService::informPollAlarmFired() {
    VLOG("StatsService::informPollAlarmFired was called");

    if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
        return Status::fromExceptionCode(Status::EX_SECURITY,
                                         "Only system uid can call informPollAlarmFired");
    }
    ENFORCE_UID(AID_SYSTEM);

    VLOG("StatsService::informPollAlarmFired was called");
    mProcessor->informPullAlarmFired(getElapsedRealtimeNs());

    VLOG("StatsService::informPollAlarmFired succeeded");

    return Status::ok();
}

Status StatsService::systemRunning() {
    if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
        return Status::fromExceptionCode(Status::EX_SECURITY,
                                         "Only system uid can call systemRunning");
    }
    ENFORCE_UID(AID_SYSTEM);

    // When system_server is up and running, schedule the dropbox task to run.
    VLOG("StatsService::systemRunning");

    sayHiToStatsCompanion();

    return Status::ok();
}

Status StatsService::writeDataToDisk() {
    if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
        return Status::fromExceptionCode(Status::EX_SECURITY,
                                         "Only system uid can call systemRunning");
    }
    ENFORCE_UID(AID_SYSTEM);

    VLOG("StatsService::writeDataToDisk");

    mProcessor->WriteDataToDisk();

    return Status::ok();
}

@@ -790,13 +831,9 @@ void StatsService::sayHiToStatsCompanion() {
}

Status StatsService::statsCompanionReady() {
    VLOG("StatsService::statsCompanionReady was called");

    if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
        return Status::fromExceptionCode(Status::EX_SECURITY,
                                         "Only system uid can call statsCompanionReady");
    }
    ENFORCE_UID(AID_SYSTEM);

    VLOG("StatsService::statsCompanionReady was called");
    sp<IStatsCompanionService> statsCompanion = getStatsCompanionService();
    if (statsCompanion == nullptr) {
        return Status::fromExceptionCode(
@@ -820,33 +857,31 @@ void StatsService::OnLogEvent(LogEvent* event, bool reconnectionStarts) {
    mProcessor->OnLogEvent(event, reconnectionStarts);
}

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

    IPCThreadState* ipc = IPCThreadState::self();
    VLOG("StatsService::getData with Pid %i, Uid %i", ipc->getCallingPid(), ipc->getCallingUid());
    if (!checkCallingPermission(String16(kPermissionDump))) {
        return Status::fromExceptionCode(binder::Status::EX_SECURITY);
    }
    ConfigKey configKey(ipc->getCallingUid(), key);
    mProcessor->onDumpReport(configKey, getElapsedRealtimeNs(),
                             false /* include_current_bucket*/, output);
    return Status::ok();
}

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

    IPCThreadState* ipc = IPCThreadState::self();
    VLOG("StatsService::getMetadata with Pid %i, Uid %i", ipc->getCallingPid(),
         ipc->getCallingUid());
    if (!checkCallingPermission(String16(kPermissionDump))) {
        return Status::fromExceptionCode(binder::Status::EX_SECURITY);
    }
    StatsdStats::getInstance().dumpStats(output, false); // Don't reset the counters.
    return Status::ok();
}

Status StatsService::addConfiguration(int64_t key, const vector <uint8_t>& config) {
    if (!checkCallingPermission(String16(kPermissionDump))) {
        return Status::fromExceptionCode(binder::Status::EX_SECURITY);
    }
Status StatsService::addConfiguration(int64_t key, const vector <uint8_t>& config,
                                      const String16& packageName) {
    ENFORCE_DUMP_AND_USAGE_STATS(packageName);

    IPCThreadState* ipc = IPCThreadState::self();
    if (addConfigurationChecked(ipc->getCallingUid(), key, config)) {
        return Status::ok();
@@ -869,30 +904,29 @@ bool StatsService::addConfigurationChecked(int uid, int64_t key, const vector<ui
    return true;
}

Status StatsService::removeDataFetchOperation(int64_t key) {
    if (!checkCallingPermission(String16(kPermissionDump))) {
        return Status::fromExceptionCode(binder::Status::EX_SECURITY);
    }
Status StatsService::removeDataFetchOperation(int64_t key, const String16& packageName) {
    ENFORCE_DUMP_AND_USAGE_STATS(packageName);

    IPCThreadState* ipc = IPCThreadState::self();
    ConfigKey configKey(ipc->getCallingUid(), key);
    mConfigManager->RemoveConfigReceiver(configKey);
    return Status::ok();
}

Status StatsService::setDataFetchOperation(int64_t key, const sp<android::IBinder>& intentSender) {
    if (!checkCallingPermission(String16(kPermissionDump))) {
        return Status::fromExceptionCode(binder::Status::EX_SECURITY);
    }
Status StatsService::setDataFetchOperation(int64_t key,
                                           const sp<android::IBinder>& intentSender,
                                           const String16& packageName) {
    ENFORCE_DUMP_AND_USAGE_STATS(packageName);

    IPCThreadState* ipc = IPCThreadState::self();
    ConfigKey configKey(ipc->getCallingUid(), key);
    mConfigManager->SetConfigReceiver(configKey, intentSender);
    return Status::ok();
}

Status StatsService::removeConfiguration(int64_t key) {
    if (!checkCallingPermission(String16(kPermissionDump))) {
        return Status::fromExceptionCode(binder::Status::EX_SECURITY);
    }
Status StatsService::removeConfiguration(int64_t key, const String16& packageName) {
    ENFORCE_DUMP_AND_USAGE_STATS(packageName);

    IPCThreadState* ipc = IPCThreadState::self();
    ConfigKey configKey(ipc->getCallingUid(), key);
    mConfigManager->RemoveConfig(configKey);
@@ -902,11 +936,11 @@ Status StatsService::removeConfiguration(int64_t key) {

Status StatsService::setBroadcastSubscriber(int64_t configId,
                                            int64_t subscriberId,
                                            const sp<android::IBinder>& intentSender) {
                                            const sp<android::IBinder>& intentSender,
                                            const String16& packageName) {
    ENFORCE_DUMP_AND_USAGE_STATS(packageName);

    VLOG("StatsService::setBroadcastSubscriber called.");
    if (!checkCallingPermission(String16(kPermissionDump))) {
        return Status::fromExceptionCode(binder::Status::EX_SECURITY);
    }
    IPCThreadState* ipc = IPCThreadState::self();
    ConfigKey configKey(ipc->getCallingUid(), configId);
    SubscriberReporter::getInstance()
@@ -915,11 +949,11 @@ Status StatsService::setBroadcastSubscriber(int64_t configId,
}

Status StatsService::unsetBroadcastSubscriber(int64_t configId,
                                              int64_t subscriberId) {
                                              int64_t subscriberId,
                                              const String16& packageName) {
    ENFORCE_DUMP_AND_USAGE_STATS(packageName);

    VLOG("StatsService::unsetBroadcastSubscriber called.");
    if (!checkCallingPermission(String16(kPermissionDump))) {
        return Status::fromExceptionCode(binder::Status::EX_SECURITY);
    }
    IPCThreadState* ipc = IPCThreadState::self();
    ConfigKey configKey(ipc->getCallingUid(), configId);
    SubscriberReporter::getInstance()
@@ -927,7 +961,6 @@ Status StatsService::unsetBroadcastSubscriber(int64_t configId,
    return Status::ok();
}


void StatsService::binderDied(const wp <IBinder>& who) {
    ALOGW("statscompanion service died");
    mProcessor->WriteDataToDisk();
+19 −8
Original line number Diff line number Diff line
@@ -81,36 +81,44 @@ public:
    /**
     * Binder call for clients to request data for this configuration key.
     */
    virtual Status getData(int64_t key, vector<uint8_t>* output) override;
    virtual Status getData(int64_t key,
                           const String16& packageName,
                           vector<uint8_t>* output) override;


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


    /**
     * Binder call to let clients send a configuration and indicate they're interested when they
     * should requestData for this configuration.
     */
    virtual Status addConfiguration(int64_t key, const vector<uint8_t>& config) override;
    virtual Status addConfiguration(int64_t key,
                                    const vector<uint8_t>& config,
                                    const String16& packageName) override;

    /**
     * Binder call to let clients register the data fetch operation for a configuration.
     */
    virtual Status setDataFetchOperation(int64_t key,
                                         const sp<android::IBinder>& intentSender) override;
                                         const sp<android::IBinder>& intentSender,
                                         const String16& packageName) override;

    /**
     * Binder call to remove the data fetch operation for the specified config key.
     */
    virtual Status removeDataFetchOperation(int64_t key) override;
    virtual Status removeDataFetchOperation(int64_t key,
                                            const String16& packageName) override;

    /**
     * Binder call to allow clients to remove the specified configuration.
     */
    virtual Status removeConfiguration(int64_t key) override;
    virtual Status removeConfiguration(int64_t key,
                                       const String16& packageName) override;

    /**
     * Binder call to associate the given config's subscriberId with the given intentSender.
@@ -118,12 +126,15 @@ public:
     */
    virtual Status setBroadcastSubscriber(int64_t configId,
                                          int64_t subscriberId,
                                          const sp<android::IBinder>& intentSender) override;
                                          const sp<android::IBinder>& intentSender,
                                          const String16& packageName) override;

    /**
     * Binder call to unassociate the given config's subscriberId with any intentSender.
     */
    virtual Status unsetBroadcastSubscriber(int64_t configId, int64_t subscriberId) override;
    virtual Status unsetBroadcastSubscriber(int64_t configId,
                                            int64_t subscriberId,
                                            const String16& packageName) override;

    /** Inform statsCompanion that statsd is ready. */
    virtual void sayHiToStatsCompanion();
+4 −3
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ namespace statsd {

#ifdef __ANDROID__

const string kAndroid = "android";
const string kApp1 = "app1.sharing.1";
const int kConfigKey = 789130123;  // Randomly chosen to avoid collisions with existing configs.

@@ -35,12 +36,12 @@ void SendConfig(StatsService& service, const StatsdConfig& config) {
    config.SerializeToString(&str);
    std::vector<uint8_t> configAsVec(str.begin(), str.end());
    bool success;
    service.addConfiguration(kConfigKey, configAsVec);
    service.addConfiguration(kConfigKey, configAsVec, String16(kAndroid.c_str()));
}

ConfigMetricsReport GetReports(StatsService& service) {
    vector<uint8_t> output;
    service.getData(kConfigKey, &output);
    service.getData(kConfigKey, String16(kAndroid.c_str()), &output);
    ConfigMetricsReportList reports;
    reports.ParseFromArray(output.data(), output.size());
    EXPECT_EQ(1, reports.reports_size());
Loading