summaryrefslogtreecommitdiff
path: root/cmds/statsd/src/external/ResourcePowerManagerPuller.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cmds/statsd/src/external/ResourcePowerManagerPuller.cpp')
-rw-r--r--cmds/statsd/src/external/ResourcePowerManagerPuller.cpp165
1 files changed, 165 insertions, 0 deletions
diff --git a/cmds/statsd/src/external/ResourcePowerManagerPuller.cpp b/cmds/statsd/src/external/ResourcePowerManagerPuller.cpp
new file mode 100644
index 000000000000..3ee636dfcde5
--- /dev/null
+++ b/cmds/statsd/src/external/ResourcePowerManagerPuller.cpp
@@ -0,0 +1,165 @@
+/*
+ * 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 true // STOPSHIP if true
+#include "Log.h"
+
+#include <android/hardware/power/1.0/IPower.h>
+#include <android/hardware/power/1.1/IPower.h>
+#include <fcntl.h>
+#include <hardware/power.h>
+#include <hardware_legacy/power.h>
+#include <inttypes.h>
+#include <semaphore.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include "external/ResourcePowerManagerPuller.h"
+#include "external/StatsPuller.h"
+
+#include "logd/LogEvent.h"
+#include "statslog.h"
+
+using android::hardware::hidl_vec;
+using android::hardware::power::V1_0::IPower;
+using android::hardware::power::V1_0::PowerStatePlatformSleepState;
+using android::hardware::power::V1_0::PowerStateVoter;
+using android::hardware::power::V1_0::Status;
+using android::hardware::power::V1_1::PowerStateSubsystem;
+using android::hardware::power::V1_1::PowerStateSubsystemSleepState;
+using android::hardware::Return;
+using android::hardware::Void;
+
+using std::make_shared;
+using std::shared_ptr;
+
+namespace android {
+namespace os {
+namespace statsd {
+
+sp<android::hardware::power::V1_0::IPower> gPowerHalV1_0 = nullptr;
+sp<android::hardware::power::V1_1::IPower> gPowerHalV1_1 = nullptr;
+std::mutex gPowerHalMutex;
+bool gPowerHalExists = true;
+
+bool getPowerHal() {
+ if (gPowerHalExists && gPowerHalV1_0 == nullptr) {
+ gPowerHalV1_0 = android::hardware::power::V1_0::IPower::getService();
+ if (gPowerHalV1_0 != nullptr) {
+ gPowerHalV1_1 = android::hardware::power::V1_1::IPower::castFrom(gPowerHalV1_0);
+ ALOGI("Loaded power HAL service");
+ } else {
+ ALOGW("Couldn't load power HAL service");
+ gPowerHalExists = false;
+ }
+ }
+ return gPowerHalV1_0 != nullptr;
+}
+
+bool ResourcePowerManagerPuller::Pull(const int tagId, vector<shared_ptr<LogEvent>>* data) {
+ std::lock_guard<std::mutex> lock(gPowerHalMutex);
+
+ if (!getPowerHal()) {
+ ALOGE("Power Hal not loaded");
+ return false;
+ }
+
+ uint64_t timestamp = time(nullptr) * NS_PER_SEC;
+
+ data->clear();
+ Return<void> ret = gPowerHalV1_0->getPlatformLowPowerStats(
+ [&data, timestamp](hidl_vec<PowerStatePlatformSleepState> states, Status status) {
+
+ if (status != Status::SUCCESS) return;
+
+ for (size_t i = 0; i < states.size(); i++) {
+ const PowerStatePlatformSleepState& state = states[i];
+
+ auto statePtr = make_shared<LogEvent>(
+ android::util::POWER_STATE_PLATFORM_SLEEP_STATE_PULLED, timestamp);
+ statePtr->write(state.name);
+ statePtr->write(state.residencyInMsecSinceBoot);
+ statePtr->write(state.totalTransitions);
+ statePtr->write(state.supportedOnlyInSuspend);
+ statePtr->init();
+ data->push_back(statePtr);
+ VLOG("powerstate: %s, %lld, %lld, %d", state.name.c_str(),
+ (long long)state.residencyInMsecSinceBoot,
+ (long long)state.totalTransitions, state.supportedOnlyInSuspend ? 1 : 0);
+ for (auto voter : state.voters) {
+ auto voterPtr =
+ make_shared<LogEvent>(android::util::POWER_STATE_VOTER_PULLED, timestamp);
+ voterPtr->write(state.name);
+ voterPtr->write(voter.name);
+ voterPtr->write(voter.totalTimeInMsecVotedForSinceBoot);
+ voterPtr->write(voter.totalNumberOfTimesVotedSinceBoot);
+ voterPtr->init();
+ data->push_back(voterPtr);
+ VLOG("powerstatevoter: %s, %s, %lld, %lld", state.name.c_str(),
+ voter.name.c_str(), (long long)voter.totalTimeInMsecVotedForSinceBoot,
+ (long long)voter.totalNumberOfTimesVotedSinceBoot);
+ }
+ }
+ });
+ if (!ret.isOk()) {
+ ALOGE("getLowPowerStats() failed: power HAL service not available");
+ gPowerHalV1_0 = nullptr;
+ return false;
+ }
+
+ // Trying to cast to IPower 1.1, this will succeed only for devices supporting 1.1
+ sp<android::hardware::power::V1_1::IPower> gPowerHal_1_1 =
+ android::hardware::power::V1_1::IPower::castFrom(gPowerHalV1_0);
+ if (gPowerHal_1_1 != nullptr) {
+ ret = gPowerHal_1_1->getSubsystemLowPowerStats(
+ [&data, timestamp](hidl_vec<PowerStateSubsystem> subsystems, Status status) {
+
+ if (status != Status::SUCCESS) return;
+
+ if (subsystems.size() > 0) {
+ for (size_t i = 0; i < subsystems.size(); i++) {
+ const PowerStateSubsystem& subsystem = subsystems[i];
+ for (size_t j = 0; j < subsystem.states.size(); j++) {
+ const PowerStateSubsystemSleepState& state = subsystem.states[j];
+ auto subsystemStatePtr = make_shared<LogEvent>(
+ android::util::POWER_STATE_SUBSYSTEM_SLEEP_STATE_PULLED, timestamp);
+ subsystemStatePtr->write(subsystem.name);
+ subsystemStatePtr->write(state.name);
+ subsystemStatePtr->write(state.residencyInMsecSinceBoot);
+ subsystemStatePtr->write(state.totalTransitions);
+ subsystemStatePtr->write(state.lastEntryTimestampMs);
+ subsystemStatePtr->write(state.supportedOnlyInSuspend);
+ subsystemStatePtr->init();
+ data->push_back(subsystemStatePtr);
+ VLOG("subsystemstate: %s, %s, %lld, %lld, %lld",
+ subsystem.name.c_str(), state.name.c_str(),
+ (long long)state.residencyInMsecSinceBoot,
+ (long long)state.totalTransitions,
+ (long long)state.lastEntryTimestampMs);
+ }
+ }
+ }
+ });
+ }
+ return true;
+}
+
+} // namespace statsd
+} // namespace os
+} // namespace android