summaryrefslogtreecommitdiff
path: root/cmds/statsd/src/external/StatsPullerManagerImpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cmds/statsd/src/external/StatsPullerManagerImpl.cpp')
-rw-r--r--cmds/statsd/src/external/StatsPullerManagerImpl.cpp250
1 files changed, 250 insertions, 0 deletions
diff --git a/cmds/statsd/src/external/StatsPullerManagerImpl.cpp b/cmds/statsd/src/external/StatsPullerManagerImpl.cpp
new file mode 100644
index 000000000000..4c676a70363f
--- /dev/null
+++ b/cmds/statsd/src/external/StatsPullerManagerImpl.cpp
@@ -0,0 +1,250 @@
+/*
+ * 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.
+ */
+
+#define DEBUG false
+#include "Log.h"
+
+#include <android/os/IStatsCompanionService.h>
+#include <cutils/log.h>
+#include <algorithm>
+#include <climits>
+#include "CpuTimePerUidFreqPuller.h"
+#include "CpuTimePerUidPuller.h"
+#include "ResourceHealthManagerPuller.h"
+#include "KernelUidCpuActiveTimeReader.h"
+#include "KernelUidCpuClusterTimeReader.h"
+#include "SubsystemSleepStatePuller.h"
+#include "StatsCompanionServicePuller.h"
+#include "StatsPullerManagerImpl.h"
+#include "StatsService.h"
+#include "SubsystemSleepStatePuller.h"
+#include "logd/LogEvent.h"
+#include "statslog.h"
+
+#include <iostream>
+
+using std::make_shared;
+using std::map;
+using std::shared_ptr;
+using std::string;
+using std::vector;
+using std::list;
+
+namespace android {
+namespace os {
+namespace statsd {
+
+const std::map<int, PullAtomInfo> StatsPullerManagerImpl::kAllPullAtomInfo = {
+ // wifi_bytes_transfer
+ {android::util::WIFI_BYTES_TRANSFER,
+ {{2, 3, 4, 5},
+ {},
+ 1,
+ new StatsCompanionServicePuller(android::util::WIFI_BYTES_TRANSFER)}},
+ // wifi_bytes_transfer_by_fg_bg
+ {android::util::WIFI_BYTES_TRANSFER_BY_FG_BG,
+ {{3, 4, 5, 6},
+ {2},
+ 1,
+ new StatsCompanionServicePuller(android::util::WIFI_BYTES_TRANSFER_BY_FG_BG)}},
+ // mobile_bytes_transfer
+ {android::util::MOBILE_BYTES_TRANSFER,
+ {{2, 3, 4, 5},
+ {},
+ 1,
+ new StatsCompanionServicePuller(android::util::MOBILE_BYTES_TRANSFER)}},
+ // mobile_bytes_transfer_by_fg_bg
+ {android::util::MOBILE_BYTES_TRANSFER_BY_FG_BG,
+ {{3, 4, 5, 6},
+ {2},
+ 1,
+ new StatsCompanionServicePuller(android::util::MOBILE_BYTES_TRANSFER_BY_FG_BG)}},
+ // bluetooth_bytes_transfer
+ {android::util::BLUETOOTH_BYTES_TRANSFER,
+ {{2, 3}, {}, 1, new StatsCompanionServicePuller(android::util::BLUETOOTH_BYTES_TRANSFER)}},
+ // kernel_wakelock
+ {android::util::KERNEL_WAKELOCK,
+ {{}, {}, 1, new StatsCompanionServicePuller(android::util::KERNEL_WAKELOCK)}},
+ // subsystem_sleep_state
+ {android::util::SUBSYSTEM_SLEEP_STATE, {{}, {}, 1, new SubsystemSleepStatePuller()}},
+ // cpu_time_per_freq
+ {android::util::CPU_TIME_PER_FREQ,
+ {{3}, {2}, 1, new StatsCompanionServicePuller(android::util::CPU_TIME_PER_FREQ)}},
+ // cpu_time_per_uid
+ {android::util::CPU_TIME_PER_UID, {{2, 3}, {}, 1, new CpuTimePerUidPuller()}},
+ // cpu_time_per_uid_freq
+ {android::util::CPU_TIME_PER_UID_FREQ, {{3}, {2}, 1, new CpuTimePerUidFreqPuller()}},
+ // wifi_activity_energy_info
+ {android::util::WIFI_ACTIVITY_ENERGY_INFO,
+ {{}, {}, 1, new StatsCompanionServicePuller(android::util::WIFI_ACTIVITY_ENERGY_INFO)}},
+ // modem_activity_info
+ {android::util::MODEM_ACTIVITY_INFO,
+ {{}, {}, 1, new StatsCompanionServicePuller(android::util::MODEM_ACTIVITY_INFO)}},
+ // bluetooth_activity_info
+ {android::util::BLUETOOTH_ACTIVITY_INFO,
+ {{}, {}, 1, new StatsCompanionServicePuller(android::util::BLUETOOTH_ACTIVITY_INFO)}},
+ // system_elapsed_realtime
+ {android::util::SYSTEM_ELAPSED_REALTIME,
+ {{}, {}, 1, new StatsCompanionServicePuller(android::util::SYSTEM_ELAPSED_REALTIME)}},
+ // system_uptime
+ {android::util::SYSTEM_UPTIME,
+ {{}, {}, 1, new StatsCompanionServicePuller(android::util::SYSTEM_UPTIME)}},
+ // cpu_active_time
+ {android::util::CPU_ACTIVE_TIME, {{3}, {2}, 1, new KernelUidCpuActiveTimeReader()}},
+ // cpu_cluster_time
+ {android::util::CPU_CLUSTER_TIME, {{3}, {2}, 1, new KernelUidCpuClusterTimeReader()}},
+ // disk_space
+ {android::util::DISK_SPACE,
+ {{}, {}, 1, new StatsCompanionServicePuller(android::util::DISK_SPACE)}},
+ // remaining_battery_capacity
+ {android::util::REMAINING_BATTERY_CAPACITY,
+ {{}, {}, 1, new ResourceHealthManagerPuller(android::util::REMAINING_BATTERY_CAPACITY)}},
+ // full_battery_capacity
+ {android::util::FULL_BATTERY_CAPACITY,
+ {{}, {}, 1, new ResourceHealthManagerPuller(android::util::FULL_BATTERY_CAPACITY)}}};
+
+StatsPullerManagerImpl::StatsPullerManagerImpl()
+ : mCurrentPullingInterval(LONG_MAX) {
+ mStatsCompanionService = StatsService::getStatsCompanionService();
+}
+
+bool StatsPullerManagerImpl::Pull(int tagId, vector<shared_ptr<LogEvent>>* data) {
+ VLOG("Initiating pulling %d", tagId);
+
+ if (kAllPullAtomInfo.find(tagId) != kAllPullAtomInfo.end()) {
+ bool ret = kAllPullAtomInfo.find(tagId)->second.puller->Pull(data);
+ VLOG("pulled %d items", (int)data->size());
+ return ret;
+ } else {
+ VLOG("Unknown tagId %d", tagId);
+ return false; // Return early since we don't know what to pull.
+ }
+}
+
+StatsPullerManagerImpl& StatsPullerManagerImpl::GetInstance() {
+ static StatsPullerManagerImpl instance;
+ return instance;
+}
+
+bool StatsPullerManagerImpl::PullerForMatcherExists(int tagId) const {
+ return kAllPullAtomInfo.find(tagId) != kAllPullAtomInfo.end();
+}
+
+void StatsPullerManagerImpl::RegisterReceiver(int tagId, wp<PullDataReceiver> receiver,
+ long intervalMs) {
+ AutoMutex _l(mReceiversLock);
+ auto& receivers = mReceivers[tagId];
+ for (auto it = receivers.begin(); it != receivers.end(); it++) {
+ if (it->receiver == receiver) {
+ VLOG("Receiver already registered of %d", (int)receivers.size());
+ return;
+ }
+ }
+ ReceiverInfo receiverInfo;
+ receiverInfo.receiver = receiver;
+ receiverInfo.timeInfo.first = intervalMs;
+ receivers.push_back(receiverInfo);
+
+ // Round it to the nearest minutes. This is the limit of alarm manager.
+ // In practice, we should limit it higher.
+ long roundedIntervalMs = intervalMs/1000/60 * 1000 * 60;
+ // There is only one alarm for all pulled events. So only set it to the smallest denom.
+ if (roundedIntervalMs < mCurrentPullingInterval) {
+ VLOG("Updating pulling interval %ld", intervalMs);
+ mCurrentPullingInterval = roundedIntervalMs;
+ long currentTimeMs = time(nullptr) * 1000;
+ long nextAlarmTimeMs = currentTimeMs + mCurrentPullingInterval - (currentTimeMs - mTimeBaseSec * 1000) % mCurrentPullingInterval;
+ if (mStatsCompanionService != nullptr) {
+ mStatsCompanionService->setPullingAlarms(nextAlarmTimeMs, mCurrentPullingInterval);
+ } else {
+ VLOG("Failed to update pulling interval");
+ }
+ }
+ VLOG("Puller for tagId %d registered of %d", tagId, (int)receivers.size());
+}
+
+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);
+ return;
+ }
+ auto& receivers = mReceivers.find(tagId)->second;
+ for (auto it = receivers.begin(); it != receivers.end(); it++) {
+ if (receiver == it->receiver) {
+ receivers.erase(it);
+ VLOG("Puller for tagId %d unregistered of %d", tagId, (int)receivers.size());
+ return;
+ }
+ }
+}
+
+void StatsPullerManagerImpl::OnAlarmFired() {
+ AutoMutex _l(mReceiversLock);
+
+ uint64_t currentTimeMs = time(nullptr) /60 * 60 * 1000;
+
+ vector<pair<int, vector<ReceiverInfo*>>> needToPull =
+ vector<pair<int, vector<ReceiverInfo*>>>();
+ for (auto& pair : mReceivers) {
+ vector<ReceiverInfo*> receivers = vector<ReceiverInfo*>();
+ if (pair.second.size() != 0) {
+ for (auto& receiverInfo : pair.second) {
+ if (receiverInfo.timeInfo.first + receiverInfo.timeInfo.second > currentTimeMs) {
+ receivers.push_back(&receiverInfo);
+ }
+ }
+ if (receivers.size() > 0) {
+ needToPull.push_back(make_pair(pair.first, receivers));
+ }
+ }
+ }
+
+ for (const auto& pullInfo : needToPull) {
+ vector<shared_ptr<LogEvent>> data;
+ if (Pull(pullInfo.first, &data)) {
+ for (const auto& receiverInfo : pullInfo.second) {
+ sp<PullDataReceiver> receiverPtr = receiverInfo->receiver.promote();
+ if (receiverPtr != nullptr) {
+ receiverPtr->onDataPulled(data);
+ receiverInfo->timeInfo.second = currentTimeMs;
+ } else {
+ VLOG("receiver already gone.");
+ }
+ }
+ }
+ }
+}
+
+int StatsPullerManagerImpl::ForceClearPullerCache() {
+ int totalCleared = 0;
+ for (const auto& pulledAtom : kAllPullAtomInfo) {
+ totalCleared += pulledAtom.second.puller->ForceClearCache();
+ }
+ return totalCleared;
+}
+
+int StatsPullerManagerImpl::ClearPullerCacheIfNecessary(long timestampSec) {
+ int totalCleared = 0;
+ for (const auto& pulledAtom : kAllPullAtomInfo) {
+ totalCleared += pulledAtom.second.puller->ClearCacheIfNecessary(timestampSec);
+ }
+ return totalCleared;
+}
+
+} // namespace statsd
+} // namespace os
+} // namespace android