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

Commit 31eb67b3 authored by yro's avatar yro
Browse files

Adds aidl definitions and their implementations for binder transfer of

statsd entries to clients. This change only includes changes on statds
side and does not include java library for clients to import. Java
library will be a separate change as it requires system api review.

Test: statsd, statsd_test
Change-Id: I306c6e9687801668cc0145b12d38406bfe634775
parent ce741680
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -270,6 +270,7 @@ LOCAL_SRC_FILES += \
	core/java/android/os/IRecoverySystemProgressListener.aidl \
	core/java/android/os/IRemoteCallback.aidl \
	core/java/android/os/ISchedulingPolicyService.aidl \
	core/java/android/os/IStatsCallbacks.aidl \
	core/java/android/os/IStatsCompanionService.aidl \
	core/java/android/os/IStatsManager.aidl \
	core/java/android/os/IThermalEventListener.aidl \
+1 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
LOCAL_PATH:= $(call my-dir)

statsd_common_src := \
    ../../core/java/android/os/IStatsCallbacks.aidl \
    ../../core/java/android/os/IStatsCompanionService.aidl \
    ../../core/java/android/os/IStatsManager.aidl \
    src/stats_log.proto \
+38 −2
Original line number Diff line number Diff line
@@ -33,8 +33,9 @@ namespace android {
namespace os {
namespace statsd {

StatsLogProcessor::StatsLogProcessor(const sp<UidMap>& uidMap)
    : m_dropbox_writer("all-logs"), mUidMap(uidMap) {
StatsLogProcessor::StatsLogProcessor(const sp<UidMap>& uidMap,
                                     const std::function<void(const vector<uint8_t>&)>& pushLog)
    : m_dropbox_writer("all-logs"), mUidMap(uidMap), mPushLog(pushLog) {
}

StatsLogProcessor::~StatsLogProcessor() {
@@ -91,6 +92,41 @@ void StatsLogProcessor::OnConfigRemoved(const ConfigKey& key) {
    }
}

void StatsLogProcessor::addEventMetricData(const EventMetricData& eventMetricData) {
    // TODO: Replace this code when MetricsManager.onDumpReport() is ready to
    // get a list of byte arrays.
    flushIfNecessary(eventMetricData);
    const int numBytes = eventMetricData.ByteSize();
    char buffer[numBytes];
    eventMetricData.SerializeToArray(&buffer[0], numBytes);
    string bufferString(buffer, numBytes);
    mEvents.push_back(bufferString);
    mBufferSize += eventMetricData.ByteSize();
}

void StatsLogProcessor::flushIfNecessary(const EventMetricData& eventMetricData) {
    if (eventMetricData.ByteSize() + mBufferSize > kMaxSerializedBytes) {
      flush();
    }
}

void StatsLogProcessor::flush() {
    StatsLogReport logReport;
    for (string eventBuffer : mEvents) {
        EventMetricData eventFromBuffer;
        eventFromBuffer.ParseFromString(eventBuffer);
        EventMetricData* newEntry = logReport.mutable_event_metrics()->add_data();
        newEntry->CopyFrom(eventFromBuffer);
    }

    const int numBytes = logReport.ByteSize();
    vector<uint8_t> logReportBuffer(numBytes);
    logReport.SerializeToArray(&logReportBuffer[0], numBytes);
    mPushLog(logReportBuffer);
    mEvents.clear();
    mBufferSize = 0;
}

}  // namespace statsd
}  // namespace os
}  // namespace android
+32 −1
Original line number Diff line number Diff line
@@ -33,7 +33,8 @@ namespace statsd {

class StatsLogProcessor : public ConfigListener {
public:
    StatsLogProcessor(const sp<UidMap>& uidMap);
    StatsLogProcessor(const sp<UidMap>& uidMap,
                      const std::function<void(const vector<uint8_t>&)>& pushLog);
    virtual ~StatsLogProcessor();

    virtual void OnLogEvent(const LogEvent& event);
@@ -44,6 +45,9 @@ public:
    // TODO: Once we have the ProtoOutputStream in c++, we can just return byte array.
    std::vector<StatsLogReport> onDumpReport(const ConfigKey& key);

    /* Request a flush through a binder call. */
    void flush();

private:
    // TODO: use EventMetrics to log the events.
    DropboxWriter m_dropbox_writer;
@@ -51,6 +55,33 @@ private:
    std::unordered_map<ConfigKey, std::unique_ptr<MetricsManager>> mMetricsManagers;

    sp<UidMap> mUidMap;  // Reference to the UidMap to lookup app name and version for each uid.

    /* Max *serialized* size of the logs kept in memory before flushing through binder call.
       Proto lite does not implement the SpaceUsed() function which gives the in memory byte size.
       So we cap memory usage by limiting the serialized size. Note that protobuf's in memory size
       is higher than its serialized size.
     */
    static const size_t kMaxSerializedBytes = 16 * 1024;

    /* List of data that was captured for a single metric over a given interval of time. */
    vector<string> mEvents;

    /* Current *serialized* size of the logs kept in memory.
       To save computation, we will not calculate the size of the StatsLogReport every time when a
       new entry is added, which would recursively call ByteSize() on every log entry. Instead, we
       keep the sum of all individual stats log entry sizes. The size of a proto is approximately
       the sum of the size of all member protos.
     */
    size_t mBufferSize = 0;

    /* Check if the buffer size exceeds the max buffer size when the new entry is added, and flush
       the logs to dropbox if true. */
    void flushIfNecessary(const EventMetricData& eventMetricData);

    /* Append event metric data to StatsLogReport. */
    void addEventMetricData(const EventMetricData& eventMetricData);

    std::function<void(const vector<uint8_t>&)> mPushLog;
};

}  // namespace statsd
+37 −1
Original line number Diff line number Diff line
@@ -68,7 +68,9 @@ StatsService::StatsService(const sp<Looper>& handlerLooper)
    mStatsPullerManager = new StatsPullerManager();
    mUidMap = new UidMap();
    mConfigManager = new ConfigManager();
    mProcessor = new StatsLogProcessor(mUidMap);
    mProcessor = new StatsLogProcessor(mUidMap, [this](const vector<uint8_t>& log) {
      pushLog(log);
    });

    mConfigManager->AddListener(mProcessor);

@@ -507,6 +509,40 @@ void StatsService::OnLogEvent(const LogEvent& event) {
    mProcessor->OnLogEvent(event);
}

Status StatsService::requestPush() {
    mProcessor->flush();
    return Status::ok();
}

Status StatsService::pushLog(const vector<uint8_t>& log) {
    std::lock_guard<std::mutex> lock(mLock);
    for (size_t i = 0; i < mCallbacks.size(); i++) {
        mCallbacks[i]->onReceiveLogs((vector<uint8_t>*)&log);
    }
    return Status::ok();
}

Status StatsService::subscribeStatsLog(const sp<IStatsCallbacks>& callback) {
    std::lock_guard<std::mutex> lock(mLock);
    for (size_t i = 0; i < mCallbacks.size(); i++) {
        if (mCallbacks[i] == callback) {
           return Status::fromStatusT(-errno);
        }
    }
    mCallbacks.add(callback);
    IInterface::asBinder(callback)->linkToDeath(this);
    return Status::ok();
}

void StatsService::binderDied(const wp<IBinder>& who) {
    for (size_t i = 0; i < mCallbacks.size(); i++) {
        if (IInterface::asBinder(mCallbacks[i]) == who) {
            mCallbacks.removeAt(i);
            break;
        }
    }
}

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