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

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

Merge "Unit tests for ValueMetricProducer StatsPullerManager is refactored so...

Merge "Unit tests for ValueMetricProducer StatsPullerManager is refactored so that we can mock it. It may need more refactor pass to make is safer for longer runs."
parents 542bdb14 6736c893
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ statsd_common_src := \
    src/external/ResourcePowerManagerPuller.cpp \
    src/external/CpuTimePerUidPuller.cpp \
    src/external/CpuTimePerUidFreqPuller.cpp \
    src/external/StatsPullerManager.cpp \
    src/external/StatsPullerManagerImpl.cpp \
    src/logd/LogEvent.cpp \
    src/logd/LogListener.cpp \
    src/logd/LogReader.cpp \
@@ -164,7 +164,8 @@ LOCAL_SRC_FILES := \
    tests/metrics/OringDurationTracker_test.cpp \
    tests/metrics/MaxDurationTracker_test.cpp \
    tests/metrics/CountMetricProducer_test.cpp \
    tests/metrics/EventMetricProducer_test.cpp
    tests/metrics/EventMetricProducer_test.cpp \
    tests/metrics/ValueMetricProducer_test.cpp

LOCAL_STATIC_LIBRARIES := \
    libgmock
+1 −1
Original line number Diff line number Diff line
@@ -157,7 +157,7 @@ private:
    /**
     * Fetches external metrics.
     */
    StatsPullerManager& mStatsPullerManager = StatsPullerManager::GetInstance();
    StatsPullerManager mStatsPullerManager;

    /**
     * Tracks the configurations that have been passed to statsd.
+22 −54
Original line number Diff line number Diff line
@@ -16,71 +16,39 @@

#pragma once

#include <android/os/IStatsCompanionService.h>
#include <binder/IServiceManager.h>
#include <utils/RefBase.h>
#include <utils/String16.h>
#include <utils/String8.h>
#include <utils/threads.h>
#include <string>
#include <unordered_map>
#include <vector>
#include "PullDataReceiver.h"
#include "StatsPuller.h"
#include "logd/LogEvent.h"
#include "StatsPullerManagerImpl.h"

namespace android {
namespace os {
namespace statsd {

class StatsPullerManager : public virtual RefBase {
class StatsPullerManager{
 public:
    static StatsPullerManager& GetInstance();
  virtual ~StatsPullerManager() {}

    void RegisterReceiver(int tagId, sp<PullDataReceiver> receiver, long intervalMs);
  virtual void RegisterReceiver(int tagId, wp<PullDataReceiver> receiver, long intervalMs) {
    mPullerManager.RegisterReceiver(tagId, receiver, intervalMs);
  };

    void UnRegisterReceiver(int tagId, sp<PullDataReceiver> receiver);
  virtual void UnRegisterReceiver(int tagId, wp<PullDataReceiver> receiver) {
    mPullerManager.UnRegisterReceiver(tagId, receiver);
  };

  // Verify if we know how to pull for this matcher
    bool PullerForMatcherExists(int tagId);
  bool PullerForMatcherExists(int tagId) {
    return mPullerManager.PullerForMatcherExists(tagId);
  }

    void OnAlarmFired();
  void OnAlarmFired() {
    mPullerManager.OnAlarmFired();
  }

    bool Pull(const int pullCode, vector<std::shared_ptr<LogEvent>>* data);
  virtual bool Pull(const int tagId, vector<std::shared_ptr<LogEvent>>* data) {
    return mPullerManager.Pull(tagId, data);
  }

 private:
    StatsPullerManager();

    // use this to update alarm
    sp<IStatsCompanionService> mStatsCompanionService = nullptr;

    sp<IStatsCompanionService> get_stats_companion_service();

    // mapping from simple matcher tagId to puller
    std::map<int, std::shared_ptr<StatsPuller>> mPullers;

      typedef struct {
        // pull_interval_sec : last_pull_time_sec
        std::pair<uint64_t, uint64_t> timeInfo;
        sp<PullDataReceiver> receiver;
      } ReceiverInfo;

    // mapping from simple matcher tagId to receivers
    std::map<int, std::vector<ReceiverInfo>> mReceivers;

    Mutex mReceiversLock;

    long mCurrentPullingInterval;

    // for pulled metrics, it is important for the buckets to be aligned to multiple of smallest
    // bucket size. All pulled metrics start pulling based on this time, so that they can be
    // correctly attributed to the correct buckets. Pulled data attach a timestamp which is the
    // request time.
    const long mPullStartTimeMs;

    long get_pull_start_time_ms();

    LogEvent parse_pulled_data(String16 data);
  StatsPullerManagerImpl& mPullerManager = StatsPullerManagerImpl::GetInstance();
};

}  // namespace statsd
+22 −16
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@
#include "CpuTimePerUidPuller.h"
#include "ResourcePowerManagerPuller.h"
#include "StatsCompanionServicePuller.h"
#include "StatsPullerManager.h"
#include "StatsPullerManagerImpl.h"
#include "StatsService.h"
#include "logd/LogEvent.h"
#include "statslog.h"
@@ -37,12 +37,13 @@ using std::map;
using std::shared_ptr;
using std::string;
using std::vector;
using std::list;

namespace android {
namespace os {
namespace statsd {

StatsPullerManager::StatsPullerManager()
StatsPullerManagerImpl::StatsPullerManagerImpl()
    : mCurrentPullingInterval(LONG_MAX), mPullStartTimeMs(get_pull_start_time_ms()) {
    shared_ptr<StatsPuller> statsCompanionServicePuller = make_shared<StatsCompanionServicePuller>();
    shared_ptr<StatsPuller> resourcePowerManagerPuller = make_shared<ResourcePowerManagerPuller>();
@@ -71,7 +72,7 @@ StatsPullerManager::StatsPullerManager()
    mStatsCompanionService = StatsService::getStatsCompanionService();
}

bool StatsPullerManager::Pull(int tagId, vector<shared_ptr<LogEvent>>* data) {
bool StatsPullerManagerImpl::Pull(int tagId, vector<shared_ptr<LogEvent>>* data) {
    if (DEBUG) ALOGD("Initiating pulling %d", tagId);

    if (mPullers.find(tagId) != mPullers.end()) {
@@ -82,26 +83,26 @@ bool StatsPullerManager::Pull(int tagId, vector<shared_ptr<LogEvent>>* data) {
    }
}

StatsPullerManager& StatsPullerManager::GetInstance() {
    static StatsPullerManager instance;
StatsPullerManagerImpl& StatsPullerManagerImpl::GetInstance() {
    static StatsPullerManagerImpl instance;
    return instance;
}

bool StatsPullerManager::PullerForMatcherExists(int tagId) {
bool StatsPullerManagerImpl::PullerForMatcherExists(int tagId) {
    return mPullers.find(tagId) != mPullers.end();
}

long StatsPullerManager::get_pull_start_time_ms() {
long StatsPullerManagerImpl::get_pull_start_time_ms() {
    // TODO: limit and align pull intervals to 10min boundaries if this turns out to be a problem
    return time(nullptr) * 1000;
}

void StatsPullerManager::RegisterReceiver(int tagId, sp<PullDataReceiver> receiver,
void StatsPullerManagerImpl::RegisterReceiver(int tagId, wp<PullDataReceiver> receiver,
                                              long intervalMs) {
    AutoMutex _l(mReceiversLock);
    vector<ReceiverInfo>& receivers = mReceivers[tagId];
    auto& receivers = mReceivers[tagId];
    for (auto it = receivers.begin(); it != receivers.end(); it++) {
        if (it->receiver.get() == receiver.get()) {
        if (it->receiver == receiver) {
            VLOG("Receiver already registered of %d", (int)receivers.size());
            return;
        }
@@ -124,7 +125,7 @@ void StatsPullerManager::RegisterReceiver(int tagId, sp<PullDataReceiver> receiv
    VLOG("Puller for tagId %d registered of %d", tagId, (int)receivers.size());
}

void StatsPullerManager::UnRegisterReceiver(int tagId, sp<PullDataReceiver> receiver) {
void StatsPullerManagerImpl::UnRegisterReceiver(int tagId, wp<PullDataReceiver> receiver) {
    AutoMutex _l(mReceiversLock);
    if (mReceivers.find(tagId) == mReceivers.end()) {
        VLOG("Unknown pull code or no receivers: %d", tagId);
@@ -132,7 +133,7 @@ void StatsPullerManager::UnRegisterReceiver(int tagId, sp<PullDataReceiver> rece
    }
    auto& receivers = mReceivers.find(tagId)->second;
    for (auto it = receivers.begin(); it != receivers.end(); it++) {
        if (receiver.get() == it->receiver.get()) {
        if (receiver == it->receiver) {
            receivers.erase(it);
            VLOG("Puller for tagId %d unregistered of %d", tagId, (int)receivers.size());
            return;
@@ -140,7 +141,7 @@ void StatsPullerManager::UnRegisterReceiver(int tagId, sp<PullDataReceiver> rece
    }
}

void StatsPullerManager::OnAlarmFired() {
void StatsPullerManagerImpl::OnAlarmFired() {
    AutoMutex _l(mReceiversLock);

    uint64_t currentTimeMs = time(nullptr) * 1000;
@@ -165,8 +166,13 @@ void StatsPullerManager::OnAlarmFired() {
        vector<shared_ptr<LogEvent>> data;
        if (Pull(pullInfo.first, &data)) {
            for (const auto& receiverInfo : pullInfo.second) {
                receiverInfo->receiver->onDataPulled(data);
                sp<PullDataReceiver> receiverPtr = receiverInfo->receiver.promote();
                if (receiverPtr != nullptr) {
                    receiverPtr->onDataPulled(data);
                    receiverInfo->timeInfo.second = currentTimeMs;
                } else {
                    VLOG("receiver already gone.");
                }
            }
        }
    }
+87 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <android/os/IStatsCompanionService.h>
#include <binder/IServiceManager.h>
#include <utils/RefBase.h>
#include <utils/threads.h>
#include <string>
#include <unordered_map>
#include <vector>
#include <list>
#include "PullDataReceiver.h"
#include "StatsPuller.h"
#include "logd/LogEvent.h"

namespace android {
namespace os {
namespace statsd {

class StatsPullerManagerImpl : public virtual RefBase {
public:
    static StatsPullerManagerImpl& GetInstance();

    void RegisterReceiver(int tagId, wp<PullDataReceiver> receiver, long intervalMs);

    void UnRegisterReceiver(int tagId, wp<PullDataReceiver> receiver);

    // Verify if we know how to pull for this matcher
    bool PullerForMatcherExists(int tagId);

    void OnAlarmFired();

    bool Pull(const int tagId, vector<std::shared_ptr<LogEvent>>* data);

private:
    StatsPullerManagerImpl();

    // use this to update alarm
    sp<IStatsCompanionService> mStatsCompanionService = nullptr;

    sp<IStatsCompanionService> get_stats_companion_service();

    // mapping from simple matcher tagId to puller
    std::map<int, std::shared_ptr<StatsPuller>> mPullers;

    typedef struct {
        // pull_interval_sec : last_pull_time_sec
        std::pair<uint64_t, uint64_t> timeInfo;
        wp<PullDataReceiver> receiver;
    } ReceiverInfo;

    // mapping from simple matcher tagId to receivers
    std::map<int, std::list<ReceiverInfo>> mReceivers;

    Mutex mReceiversLock;

    long mCurrentPullingInterval;

    // for pulled metrics, it is important for the buckets to be aligned to multiple of smallest
    // bucket size. All pulled metrics start pulling based on this time, so that they can be
    // correctly attributed to the correct buckets. Pulled data attach a timestamp which is the
    // request time.
    const long mPullStartTimeMs;

    long get_pull_start_time_ms();

    LogEvent parse_pulled_data(String16 data);
};

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