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

Commit 4f716290 authored by Bookatz's avatar Bookatz
Browse files

StatsManager throws exceptions

When StatsManager fails to connect to statsd, it now throws an exception
for the caller to catch. It also throws an exception of the config being
added is of an unreadable format.

Due to backwards compatibility issues, the old APIs could not be
changed, so new ones were made to replace the old ones. The old ones are
now temporary and will be removed when the compatibility issue is
resolved.

Bug: 77648233
Test: gts-tradefed run gts-dev --module GtsStatsdHostTestCases
Change-Id: Ibea05883a29b9b3ef9927d2f8fe295eb99832ab7
parent 135d82ac
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -383,12 +383,18 @@ package android.app {
  }

  public final class StatsManager {
    method public void addConfig(long, byte[]) throws android.app.StatsManager.StatsUnavailableException;
    method public boolean addConfiguration(long, byte[]);
    method public byte[] getData(long);
    method public byte[] getMetadata();
    method public byte[] getReports(long) throws android.app.StatsManager.StatsUnavailableException;
    method public byte[] getStatsMetadata() throws android.app.StatsManager.StatsUnavailableException;
    method public void removeConfig(long) throws android.app.StatsManager.StatsUnavailableException;
    method public boolean removeConfiguration(long);
    method public void setBroadcastSubscriber(android.app.PendingIntent, long, long) throws android.app.StatsManager.StatsUnavailableException;
    method public boolean setBroadcastSubscriber(long, long, android.app.PendingIntent);
    method public boolean setDataFetchOperation(long, android.app.PendingIntent);
    method public void setFetchReportsOperation(android.app.PendingIntent, long) throws android.app.StatsManager.StatsUnavailableException;
    field public static final java.lang.String ACTION_STATSD_STARTED = "android.app.action.STATSD_STARTED";
    field public static final java.lang.String EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES = "android.app.extra.STATS_BROADCAST_SUBSCRIBER_COOKIES";
    field public static final java.lang.String EXTRA_STATS_CONFIG_KEY = "android.app.extra.STATS_CONFIG_KEY";
@@ -398,6 +404,11 @@ package android.app {
    field public static final java.lang.String EXTRA_STATS_SUBSCRIPTION_RULE_ID = "android.app.extra.STATS_SUBSCRIPTION_RULE_ID";
  }

  public static class StatsManager.StatsUnavailableException extends android.util.AndroidException {
    ctor public StatsManager.StatsUnavailableException(java.lang.String);
    ctor public StatsManager.StatsUnavailableException(java.lang.String, java.lang.Throwable);
  }

  public class VrManager {
    method public void setAndBindVrCompositor(android.content.ComponentName);
    method public void setPersistentVrModeEnabled(boolean);
+49 −74
Original line number Diff line number Diff line
@@ -780,8 +780,6 @@ Status StatsService::writeDataToDisk() {
}

void StatsService::sayHiToStatsCompanion() {
    // TODO: This method needs to be private. It is temporarily public and unsecured for testing
    // purposes.
    sp<IStatsCompanionService> statsCompanion = getStatsCompanionService();
    if (statsCompanion != nullptr) {
        VLOG("Telling statsCompanion that statsd is ready");
@@ -825,42 +823,37 @@ void StatsService::OnLogEvent(LogEvent* event) {
Status StatsService::getData(int64_t key, vector<uint8_t>* output) {
    IPCThreadState* ipc = IPCThreadState::self();
    VLOG("StatsService::getData with Pid %i, Uid %i", ipc->getCallingPid(), ipc->getCallingUid());
    if (checkCallingPermission(String16(kPermissionDump))) {
    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();
    } else {
        return Status::fromExceptionCode(binder::Status::EX_SECURITY);
    }
}

Status StatsService::getMetadata(vector<uint8_t>* output) {
    IPCThreadState* ipc = IPCThreadState::self();
    VLOG("StatsService::getMetadata with Pid %i, Uid %i", ipc->getCallingPid(),
         ipc->getCallingUid());
    if (checkCallingPermission(String16(kPermissionDump))) {
        StatsdStats::getInstance().dumpStats(output, false); // Don't reset the counters.
        return Status::ok();
    } else {
    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,
                                      bool* success) {
Status StatsService::addConfiguration(int64_t key, const vector <uint8_t>& config) {
    if (!checkCallingPermission(String16(kPermissionDump))) {
        return Status::fromExceptionCode(binder::Status::EX_SECURITY);
    }
    IPCThreadState* ipc = IPCThreadState::self();
    if (checkCallingPermission(String16(kPermissionDump))) {
    if (addConfigurationChecked(ipc->getCallingUid(), key, config)) {
            *success = true;
        } else {
            *success = false;
        }
        return Status::ok();
    } else {
        *success = false;
        return Status::fromExceptionCode(binder::Status::EX_SECURITY);
        ALOGE("Could not parse malformatted StatsdConfig");
        return Status::fromExceptionCode(binder::Status::EX_ILLEGAL_ARGUMENT,
                                         "config does not correspond to a StatsdConfig proto");
    }
}

@@ -876,80 +869,62 @@ bool StatsService::addConfigurationChecked(int uid, int64_t key, const vector<ui
    return true;
}

Status StatsService::removeDataFetchOperation(int64_t key, bool* success) {
Status StatsService::removeDataFetchOperation(int64_t key) {
    if (!checkCallingPermission(String16(kPermissionDump))) {
        return Status::fromExceptionCode(binder::Status::EX_SECURITY);
    }
    IPCThreadState* ipc = IPCThreadState::self();
    if (checkCallingPermission(String16(kPermissionDump))) {
    ConfigKey configKey(ipc->getCallingUid(), key);
    mConfigManager->RemoveConfigReceiver(configKey);
        *success = true;
    return Status::ok();
    } else {
        *success = false;
        return Status::fromExceptionCode(binder::Status::EX_SECURITY);
    }
}

Status StatsService::setDataFetchOperation(int64_t key, const sp<android::IBinder>& intentSender,
                                           bool* success) {
Status StatsService::setDataFetchOperation(int64_t key, const sp<android::IBinder>& intentSender) {
    if (!checkCallingPermission(String16(kPermissionDump))) {
        return Status::fromExceptionCode(binder::Status::EX_SECURITY);
    }
    IPCThreadState* ipc = IPCThreadState::self();
    if (checkCallingPermission(String16(kPermissionDump))) {
    ConfigKey configKey(ipc->getCallingUid(), key);
    mConfigManager->SetConfigReceiver(configKey, intentSender);
        *success = true;
    return Status::ok();
    } else {
        *success = false;
        return Status::fromExceptionCode(binder::Status::EX_SECURITY);
    }
}

Status StatsService::removeConfiguration(int64_t key, bool* success) {
Status StatsService::removeConfiguration(int64_t key) {
    if (!checkCallingPermission(String16(kPermissionDump))) {
        return Status::fromExceptionCode(binder::Status::EX_SECURITY);
    }
    IPCThreadState* ipc = IPCThreadState::self();
    if (checkCallingPermission(String16(kPermissionDump))) {
    ConfigKey configKey(ipc->getCallingUid(), key);
    mConfigManager->RemoveConfig(configKey);
    SubscriberReporter::getInstance().removeConfig(configKey);
        *success = true;
    return Status::ok();
    } else {
        *success = false;
        return Status::fromExceptionCode(binder::Status::EX_SECURITY);
    }
}

Status StatsService::setBroadcastSubscriber(int64_t configId,
                                            int64_t subscriberId,
                                            const sp<android::IBinder>& intentSender,
                                            bool* success) {
                                            const sp<android::IBinder>& intentSender) {
    VLOG("StatsService::setBroadcastSubscriber called.");
    if (!checkCallingPermission(String16(kPermissionDump))) {
        return Status::fromExceptionCode(binder::Status::EX_SECURITY);
    }
    IPCThreadState* ipc = IPCThreadState::self();
    if (checkCallingPermission(String16(kPermissionDump))) {
    ConfigKey configKey(ipc->getCallingUid(), configId);
    SubscriberReporter::getInstance()
            .setBroadcastSubscriber(configKey, subscriberId, intentSender);
        *success = true;
    return Status::ok();
    } else {
        *success = false;
        return Status::fromExceptionCode(binder::Status::EX_SECURITY);
    }
}

Status StatsService::unsetBroadcastSubscriber(int64_t configId,
                                              int64_t subscriberId,
                                              bool* success) {
                                              int64_t subscriberId) {
    VLOG("StatsService::unsetBroadcastSubscriber called.");
    if (!checkCallingPermission(String16(kPermissionDump))) {
        return Status::fromExceptionCode(binder::Status::EX_SECURITY);
    }
    IPCThreadState* ipc = IPCThreadState::self();
    if (checkCallingPermission(String16(kPermissionDump))) {
    ConfigKey configKey(ipc->getCallingUid(), configId);
    SubscriberReporter::getInstance()
            .unsetBroadcastSubscriber(configKey, subscriberId);
        *success = true;
    return Status::ok();
    } else {
        *success = false;
        return Status::fromExceptionCode(binder::Status::EX_SECURITY);
    }
}


+7 −12
Original line number Diff line number Diff line
@@ -94,24 +94,23 @@ public:
     * 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,
                                    bool* success) override;
    virtual Status addConfiguration(int64_t key, const vector<uint8_t>& config) 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,
                                         bool* success) override;
    virtual Status setDataFetchOperation(int64_t key,
                                         const sp<android::IBinder>& intentSender) override;

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

    /**
     * Binder call to allow clients to remove the specified configuration.
     */
    virtual Status removeConfiguration(int64_t key, bool* success) override;
    virtual Status removeConfiguration(int64_t key) override;

    /**
     * Binder call to associate the given config's subscriberId with the given intentSender.
@@ -119,17 +118,13 @@ public:
     */
    virtual Status setBroadcastSubscriber(int64_t configId,
                                          int64_t subscriberId,
                                          const sp<android::IBinder>& intentSender,
                                          bool* success) override;
                                          const sp<android::IBinder>& intentSender) override;

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

    // TODO: public for testing since statsd doesn't run when system starts. Change to private
    // later.
    /** Inform statsCompanion that statsd is ready. */
    virtual void sayHiToStatsCompanion();

+0 −5
Original line number Diff line number Diff line
@@ -116,11 +116,6 @@ int main(int /*argc*/, char** /*argv*/) {
        ALOGE("Failed to add service");
        return -1;
    }

    // TODO: This line is temporary, since statsd doesn't start up automatically (and therefore
    // the call in StatsService::SystemRunning() won't ever be called right now).
    // TODO: Are you sure? Don't we need to reconnect to the system process if we get restarted?
    //  --joeo
    service->sayHiToStatsCompanion();

    // Start the log reader thread
+1 −1
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@ 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, &success);
    service.addConfiguration(kConfigKey, configAsVec);
}

ConfigMetricsReport GetReports(StatsService& service) {
Loading