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

Commit e63e6fc6 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "statsd & statscompanion communication more robust"

parents 6512f69c b487b553
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -40,8 +40,8 @@ include $(CLEAR_VARS)
LOCAL_MODULE := statsd

LOCAL_SRC_FILES := \
    ../../core/java/android/os/IStatsManager.aidl \
    ../../core/java/android/os/IStatsCompanionService.aidl \
    ../../core/java/android/os/IStatsManager.aidl \
    src/StatsService.cpp \
    src/AnomalyMonitor.cpp \
    src/LogEntryPrinter.cpp \
@@ -119,6 +119,7 @@ LOCAL_C_INCLUDES += $(LOCAL_PATH)/src \
	STATSD_PROTO_INCLUDES

LOCAL_SRC_FILES := \
    ../../core/java/android/os/IStatsCompanionService.aidl \
    ../../core/java/android/os/IStatsManager.aidl \
    src/StatsService.cpp \
    tests/indexed_priority_queue_test.cpp \
+25 −34
Original line number Diff line number Diff line
@@ -19,10 +19,9 @@

#include <AnomalyMonitor.h>

#include <binder/IServiceManager.h>
#include <cutils/log.h>

namespace statsd {
using namespace android::os::statsd;

AnomalyMonitor::AnomalyMonitor(uint32_t minDiffToUpdateRegisteredAlarmTimeSec)
        : mRegisteredAlarmTimeSec(0),
@@ -32,7 +31,23 @@ AnomalyMonitor::AnomalyMonitor(uint32_t minDiffToUpdateRegisteredAlarmTimeSec)
AnomalyMonitor::~AnomalyMonitor() {
}

void AnomalyMonitor::setStatsCompanionService(sp<IStatsCompanionService> statsCompanionService) {
    std::lock_guard<std::mutex> lock(mLock);
    sp<IStatsCompanionService> tmpForLock = mStatsCompanionService;
    mStatsCompanionService = statsCompanionService;
    if (statsCompanionService == nullptr) {
        if (DEBUG) ALOGD("Erasing link to statsCompanionService");
        return;
    }
    if (DEBUG) ALOGD("Creating link to statsCompanionService");
    const sp<const AnomalyAlarm> top = mPq.top();
    if (top != nullptr) {
        updateRegisteredAlarmTime_l(top->timestampSec);
    }
}

void AnomalyMonitor::add(sp<const AnomalyAlarm> alarm) {
    std::lock_guard<std::mutex> lock(mLock);
    if (alarm == nullptr) {
        ALOGW("Asked to add a null alarm.");
        return;
@@ -42,70 +57,46 @@ void AnomalyMonitor::add(sp<const AnomalyAlarm> alarm) {
        ALOGW("Asked to add a 0-time alarm.");
        return;
    }
    std::lock_guard<std::mutex> lock(mLock);
    // TODO: Ensure that refractory period is respected.
    if (DEBUG) ALOGD("Adding alarm with time %u", alarm->timestampSec);
    mPq.push(alarm);
    if (mRegisteredAlarmTimeSec < 1 ||
            alarm->timestampSec + mMinUpdateTimeSec < mRegisteredAlarmTimeSec) {
        updateRegisteredAlarmTime(alarm->timestampSec);
        updateRegisteredAlarmTime_l(alarm->timestampSec);
    }
}

void AnomalyMonitor::remove(sp<const AnomalyAlarm> alarm) {
    std::lock_guard<std::mutex> lock(mLock);
    if (alarm == nullptr) {
        ALOGW("Asked to remove a null alarm.");
        return;
    }
    std::lock_guard<std::mutex> lock(mLock);
    if (DEBUG) ALOGD("Removing alarm with time %u", alarm->timestampSec);
    mPq.remove(alarm);
    if (mPq.empty()) {
        if (DEBUG) ALOGD("Queue is empty. Cancel any alarm.");
        mRegisteredAlarmTimeSec = 0;
        // TODO: Make this resistant to doing work when companion is not ready yet
        sp<IStatsCompanionService> statsCompanionService = getStatsCompanion_l();
        if (statsCompanionService != nullptr) {
            statsCompanionService->cancelAnomalyAlarm();
        if (mStatsCompanionService != nullptr) {
            mStatsCompanionService->cancelAnomalyAlarm();
        }
        return;
    }
    uint32_t soonestAlarmTimeSec = mPq.top()->timestampSec;
    if (DEBUG) ALOGD("Soonest alarm is %u", soonestAlarmTimeSec);
    if (soonestAlarmTimeSec > mRegisteredAlarmTimeSec + mMinUpdateTimeSec) {
        updateRegisteredAlarmTime(soonestAlarmTimeSec);
        updateRegisteredAlarmTime_l(soonestAlarmTimeSec);
    }
}

void AnomalyMonitor::updateRegisteredAlarmTime(uint32_t timestampSec) {
void AnomalyMonitor::updateRegisteredAlarmTime_l(uint32_t timestampSec) {
    if (DEBUG) ALOGD("Updating reg alarm time to %u", timestampSec);
    mRegisteredAlarmTimeSec = timestampSec;
    sp<IStatsCompanionService> statsCompanionService = getStatsCompanion_l();
    if (statsCompanionService != nullptr) {
        statsCompanionService->setAnomalyAlarm(secToMs(mRegisteredAlarmTimeSec));
    }
}

sp<IStatsCompanionService> AnomalyMonitor::getStatsCompanion_l() {
    if (mStatsCompanion != nullptr) {
        return mStatsCompanion;
    }
    // Get statscompanion service from service manager
    const sp<IServiceManager> sm(defaultServiceManager());
    if (sm != nullptr) {
        const String16 name("statscompanion");
        mStatsCompanion =
                interface_cast<IStatsCompanionService>(sm->checkService(name));
        if (mStatsCompanion == nullptr) {
            ALOGW("statscompanion service unavailable!");
            return nullptr;
    if (mStatsCompanionService != nullptr) {
        mStatsCompanionService->setAnomalyAlarm(secToMs(mRegisteredAlarmTimeSec));
    }
}
    return mStatsCompanion;
}

int64_t AnomalyMonitor::secToMs(uint32_t timeSec) {
    return ((int64_t) timeSec) * 1000;
}

}  // namespace statsd
 No newline at end of file
+17 −9
Original line number Diff line number Diff line
@@ -24,9 +24,11 @@
#include <queue>
#include <vector>

using namespace android::os;
using namespace android;
using namespace android::os;

namespace android {
namespace os {
namespace statsd {

/**
@@ -52,7 +54,7 @@ struct AnomalyAlarm : public RefBase {
/**
 * Manages alarms for Anomaly Detection.
 */
class AnomalyMonitor {
class AnomalyMonitor : public RefBase {
 public:
    /**
     * @param minDiffToUpdateRegisteredAlarmTimeSec If the soonest alarm differs
@@ -62,6 +64,14 @@ class AnomalyMonitor {
    AnomalyMonitor(uint32_t minDiffToUpdateRegisteredAlarmTimeSec);
    ~AnomalyMonitor();

    /**
     * Tells AnomalyMonitor what IStatsCompanionService to use and, if
     * applicable, immediately registers an existing alarm with it.
     * If nullptr, AnomalyMonitor will continue to add/remove alarms, but won't
     * update IStatsCompanionService (until such time as it is set non-null).
     */
    void setStatsCompanionService(sp<IStatsCompanionService> statsCompanionService);

    /**
     * Adds the given alarm (reference) to the queue.
     */
@@ -84,7 +94,6 @@ class AnomalyMonitor {
    }

 private:
    /** Lock for accessing/writing to mPq. */
    std::mutex mLock;

    /**
@@ -103,11 +112,11 @@ class AnomalyMonitor {
    /**
     * Binder interface for communicating with StatsCompanionService.
     */
    sp<IStatsCompanionService> mStatsCompanion;
    sp<IStatsCompanionService> mStatsCompanionService = nullptr;

    /**
     * Amount by which the soonest projected alarm must differ from
     * mRegisteredAlarmTimeSec before updateRegisteredAlarmTime is called.
     * mRegisteredAlarmTimeSec before updateRegisteredAlarmTime_l is called.
     */
    uint32_t mMinUpdateTimeSec;

@@ -115,15 +124,14 @@ class AnomalyMonitor {
     * Updates the alarm registered with StatsCompanionService to the given time.
     * Also correspondingly updates mRegisteredAlarmTimeSec.
     */
    void updateRegisteredAlarmTime(uint32_t timestampSec);

    /** Returns the StatsCompanionService. */
    sp<IStatsCompanionService> getStatsCompanion_l();
    void updateRegisteredAlarmTime_l(uint32_t timestampSec);

    /** Converts uint32 timestamp in seconds to a Java long in msec. */
    int64_t secToMs(uint32_t timeSec);
};

} // namespace statsd
} // namespace os
} // namespace android

#endif // ANOMALY_MONITOR_H
 No newline at end of file
+65 −4
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */

#define LOG_TAG "statsd"
#define DEBUG true

#include "StatsService.h"
#include "DropboxReader.h"
@@ -37,6 +38,7 @@ using android::os::statsd::StatsdConfig;

// ================================================================================
StatsService::StatsService(const sp<Looper>& handlerLooper)
        : mAnomalyMonitor(new AnomalyMonitor(2)) // TODO: Change this based on the config
{
    ALOGD("stats service constructed");
}
@@ -164,14 +166,14 @@ StatsService::doLoadConfig(FILE* in)
Status
StatsService::informAnomalyAlarmFired()
{
    ALOGD("StatsService::informAnomalyAlarmFired was called");
    if (DEBUG) ALOGD("StatsService::informAnomalyAlarmFired was called");

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

    ALOGD("StatsService::informAnomalyAlarmFired succeeded");
    if (DEBUG) ALOGD("StatsService::informAnomalyAlarmFired succeeded");
    // TODO: check through all counters/timers and see if an anomaly has indeed occurred.

    return Status::ok();
@@ -180,14 +182,14 @@ StatsService::informAnomalyAlarmFired()
Status
StatsService::informPollAlarmFired()
{
    ALOGD("StatsService::informPollAlarmFired was called");
    if (DEBUG) ALOGD("StatsService::informPollAlarmFired was called");

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

    ALOGD("StatsService::informPollAlarmFired succeeded");
    if (DEBUG) ALOGD("StatsService::informPollAlarmFired succeeded");
    // TODO: determine what services to poll and poll (or ask StatsCompanionService to poll) them.

    return Status::ok();
@@ -204,6 +206,8 @@ StatsService::systemRunning()
    // When system_server is up and running, schedule the dropbox task to run.
    ALOGD("StatsService::systemRunning");

    sayHiToStatsCompanion();

    return Status::ok();
}

@@ -223,3 +227,60 @@ StatsService::printCmdHelp(FILE* out) {
    fprintf(out, "\t print-stats-log [tag_required] [timestamp_nsec_optional]\n");
    fprintf(out, "\t config\t Loads a new config from command-line (must be proto in wire-encoded format).\n");
}

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) {
        if (DEBUG) ALOGD("Telling statsCompanion that statsd is ready");
        statsCompanion->statsdReady();
    } else {
        if (DEBUG) ALOGD("Could not access statsCompanion");
    }
}

Status
StatsService::statsCompanionReady()
{
    if (DEBUG) ALOGD("StatsService::statsCompanionReady was called");

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

    sp<IStatsCompanionService> statsCompanion = getStatsCompanionService();
    if (statsCompanion == nullptr) {
        return Status::fromExceptionCode(Status::EX_NULL_POINTER,
                                         "statscompanion unavailable despite it contacting statsd!");
    }
    if (DEBUG) ALOGD("StatsService::statsCompanionReady linking to statsCompanion.");
    IInterface::asBinder(statsCompanion)->linkToDeath(new StatsdDeathRecipient(mAnomalyMonitor));
    mAnomalyMonitor->setStatsCompanionService(statsCompanion);

    return Status::ok();
}

sp<IStatsCompanionService>
StatsService::getStatsCompanionService() {
    sp<IStatsCompanionService> statsCompanion = nullptr;
    // Get statscompanion service from service manager
    const sp<IServiceManager> sm(defaultServiceManager());
    if (sm != nullptr) {
        const String16 name("statscompanion");
        statsCompanion = interface_cast<IStatsCompanionService>(sm->checkService(name));
        if (statsCompanion == nullptr) {
            ALOGW("statscompanion service unavailable!");
            return nullptr;
        }
    }
    return statsCompanion;
}

void
StatsdDeathRecipient::binderDied(const wp<IBinder>& who) {
    ALOGW("statscompanion service died");
    mAnmlyMntr->setStatsCompanionService(nullptr);
}
 No newline at end of file
+33 −0
Original line number Diff line number Diff line
@@ -17,9 +17,11 @@
#ifndef STATS_SERVICE_H
#define STATS_SERVICE_H

#include "AnomalyMonitor.h"
#include "StatsLogProcessor.h"

#include <android/os/BnStatsManager.h>
#include <android/os/IStatsCompanionService.h>
#include <binder/IResultReceiver.h>
#include <binder/IShellCallback.h>
#include <frameworks/base/cmds/statsd/src/statsd_config.pb.h>
@@ -32,7 +34,9 @@ using namespace android;
using namespace android::base;
using namespace android::binder;
using namespace android::os;
using namespace android::os::statsd;
using namespace std;

using android::os::statsd::StatsdConfig;

// ================================================================================
@@ -49,17 +53,46 @@ public:

    virtual Status systemRunning();

    // Inform statsd that statsCompanion is ready.
    virtual Status statsCompanionReady();

    virtual Status informAnomalyAlarmFired();

    virtual Status informPollAlarmFired();

    virtual status_t setProcessor(const sp<StatsLogProcessor>& main_processor);

    // 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();

private:
    sp<StatsLogProcessor> m_processor; // Reference to the processor for updating configs.

    status_t doPrintStatsLog(FILE* out, const Vector<String8>& args);

    void printCmdHelp(FILE* out);

    status_t doLoadConfig(FILE* in);

    const sp<AnomalyMonitor> mAnomalyMonitor;  // TODO: Move this to a more logical file/class

 private:
    /** Fetches the StatsCompanionService. */
    sp<IStatsCompanionService> getStatsCompanionService();
};

// --- StatsdDeathRecipient ---
class StatsdDeathRecipient : public IBinder::DeathRecipient {
public:
    StatsdDeathRecipient(sp<AnomalyMonitor> anomalyMonitor)
            : mAnmlyMntr(anomalyMonitor) {
    }

    virtual void binderDied(const wp<IBinder>& who);

private:
    const sp<AnomalyMonitor> mAnmlyMntr;
};

#endif // STATS_SERVICE_H
Loading