Remove power stats HAL 1.0 service
Bug: 179527556
Test: dumpsys android.hardware.power.stats.IPowerStats/default
Test: device boot and examined logs to make sure no errors related to
missing power stats 1.0
Change-Id: Ib8cc394f9968edaf948a2d9700e9f7fcaa5b9dc0
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 10cf0fb..1ca5183 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -72,3 +72,8 @@
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/bin/hw/android.hardware.usb@1.3-service.slider)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/etc/init/android.hardware.usb@1.3-service.slider.rc)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/etc/vintf/manifest/android.hardware.usb@1.3-service.slider.xml)
+
+# Power Stats HAL 1.0 to AIDL
+$(call add-clean-step, rm -f $(PRODUCT_OUT)/vendor/bin/hw/android.hardware.power.stats@1.0-service.gs101)
+$(call add-clean-step, rm -f $(PRODUCT_OUT)/vendor/etc/init/android.hardware.power.stats@1.0-service.gs101.rc)
+$(call add-clean-step, rm -f $(PRODUCT_OUT)/vendor/etc/vintf/manifest/android.hardware.power.stats@1.0-service.gs101.xml)
diff --git a/device.mk b/device.mk
index 194ba72..065d503 100644
--- a/device.mk
+++ b/device.mk
@@ -365,10 +365,6 @@
# PowerStats HAL
PRODUCT_PACKAGES += \
- android.hardware.power.stats@1.0-service.gs101
-
-# PowerStats AIDL HAL
-PRODUCT_PACKAGES += \
android.hardware.power.stats-service.pixel
# dumpstate HAL
diff --git a/powerstats/Android.bp b/powerstats/Android.bp
index fa73e51..7c7066c 100644
--- a/powerstats/Android.bp
+++ b/powerstats/Android.bp
@@ -23,50 +23,11 @@
}
cc_binary {
- // TODO(b/167628903) : remove this
- name: "android.hardware.power.stats@1.0-service.gs101",
- header_libs: [
- "device_kernel_headers",
- ],
- relative_install_path: "hw",
- init_rc: ["android.hardware.power.stats@1.0-service.gs101.rc"],
- vintf_fragments: ["android.hardware.power.stats@1.0-service.gs101.xml"],
- srcs: [
- "AocStateResidencyDataProvider.cpp",
- "DvfsStateResidencyDataProvider.cpp",
- "RailDataProvider.cpp",
- "service.cpp",
- "UfsStateResidencyDataProvider.cpp",
- ],
- cflags: [
- "-Wall",
- "-Werror",
- ],
- static_libs: [
- "libpixelpowerstats",
- ],
- shared_libs: [
- "android.hardware.power.stats@1.0",
- "pixelpowerstats_provider_aidl_interface-cpp",
- "libbase",
- "libbinder",
- "libcutils",
- "libfmq",
- "libhidlbase",
- "liblog",
- "libutils",
- ],
- vendor: true,
-}
-
-cc_binary {
name: "android.hardware.power.stats-service.pixel",
init_rc: ["android.hardware.power.stats-service.pixel.rc"],
vintf_fragments: ["android.hardware.power.stats-service.pixel.xml"],
srcs: [
- "AocStateResidencyDataProviderAidl.cpp",
- "DvfsStateResidencyDataProviderAidl.cpp",
- "serviceaidl.cpp"
+ "*.cpp",
],
cflags: [
"-Wall",
diff --git a/powerstats/AocStateResidencyDataProvider.cpp b/powerstats/AocStateResidencyDataProvider.cpp
index 41c75bc..c64496d 100644
--- a/powerstats/AocStateResidencyDataProvider.cpp
+++ b/powerstats/AocStateResidencyDataProvider.cpp
@@ -13,29 +13,25 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#define LOG_TAG "libpixelpowerstats"
#include "AocStateResidencyDataProvider.h"
#include <android-base/logging.h>
-#include <utility>
-
+namespace aidl {
namespace android {
namespace hardware {
-namespace google {
-namespace pixel {
-namespace powerstats {
+namespace power {
+namespace stats {
-AocStateResidencyDataProvider::AocStateResidencyDataProvider(
- std::vector<std::pair<uint32_t, std::string>> ids,
- std::vector<std::pair<std::string, std::string>> states) {
+AocStateResidencyDataProvider::AocStateResidencyDataProvider(std::vector<std::pair<std::string,
+ std::string>> ids, std::vector<std::pair<std::string, std::string>> states) {
// AoC stats are reported in ticks of 244.140625ns. The transform
// function converts ticks to milliseconds.
// 1000000 / 244.140625 = 4096.
static const uint64_t AOC_CLK = 4096;
std::function<uint64_t(uint64_t)> aocTickToMs = [](uint64_t a) { return a / AOC_CLK; };
- StateResidencyConfig config = {
+ GenericStateResidencyDataProvider::StateResidencyConfig config = {
.entryCountSupported = true,
.entryCountPrefix = "Counter:",
.totalTimeSupported = true,
@@ -45,61 +41,88 @@
.lastEntryPrefix = "Time last entered:",
.lastEntryTransform = aocTickToMs,
};
- uint32_t state_id;
- for (auto &id : ids) {
- state_id = 1;
- for (auto &state : states) {
+ for (const auto &id : ids) {
+ for (const auto &state : states) {
std::vector<std::pair<std::string, std::string>> aocStateHeaders = {
- std::make_pair(state.first, ""),
+ std::make_pair(state.first, ""),
};
+ std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> cfgs;
+ cfgs.emplace_back(generateGenericStateResidencyConfigs(config, aocStateHeaders),
+ id.first, "");
std::unique_ptr<GenericStateResidencyDataProvider> sdp(
- new GenericStateResidencyDataProvider(id.second + state.second));
- sdp->addEntity(id.first, PowerEntityConfig(state_id++, "",
- generateGenericStateResidencyConfigs(
- config, aocStateHeaders)));
- mProviders.push_back(std::move(sdp));
+ new GenericStateResidencyDataProvider(id.second + state.second, cfgs));
+ mProviders[id.first].push_back(std::move(sdp));
}
}
}
-bool AocStateResidencyDataProvider::getResults(
- std::unordered_map<uint32_t, PowerEntityStateResidencyResult> &results) {
- for (auto &provider : mProviders) {
- provider->getResults(results);
- }
- return true;
-}
-
-std::vector<PowerEntityStateSpace> AocStateResidencyDataProvider::getStateSpaces() {
- // Return state spaces based on all configured providers.
+bool AocStateResidencyDataProvider::getStateResidencies(
+ std::unordered_map<std::string, std::vector<StateResidency>> *residencies) {
// States from the same power entity are merged.
- std::map<uint32_t, PowerEntityStateSpace> stateSpaces;
- for (auto &provider : mProviders) {
- for (auto &stateSpace : provider->getStateSpaces()) {
- auto it = stateSpaces.find(stateSpace.powerEntityId);
- if (it != stateSpaces.end()) {
- auto &states = it->second.states;
- auto size = states.size();
- states.resize(size + stateSpace.states.size());
- for (uint32_t i = 0; i < stateSpace.states.size(); i++) {
- states[size + i] = stateSpace.states[i];
+ bool ret = true;
+ for (const auto &providerList : mProviders) {
+ int32_t stateId = 0;
+ std::string curEntity = providerList.first;
+ std::vector<StateResidency> stateResidencies;
+
+ // Iterate over each provider in the providerList, appending each of the states
+ for (const auto &provider : providerList.second) {
+ std::unordered_map<std::string, std::vector<StateResidency>> residency;
+ ret &= provider->getStateResidencies(&residency);
+
+ // Each provider should only return data for curEntity but checking anyway
+ if (residency.find(curEntity) != residency.end()) {
+ for (auto &r : residency.at(curEntity)) {
+ /*
+ * Modifying stateId here because we are stitching together infos from
+ * multiple GenericStateResidencyDataProviders. stateId must be modified
+ * to maintain uniqueness for a given entity
+ */
+ r.id = stateId++;
+ stateResidencies.push_back(r);
}
- } else {
- stateSpaces.insert(std::pair<uint32_t, PowerEntityStateSpace>(
- stateSpace.powerEntityId, stateSpace));
}
}
- }
- std::vector<PowerEntityStateSpace> ret;
- for (auto &stateSpace : stateSpaces) {
- ret.push_back(stateSpace.second);
+ residencies->emplace(curEntity, stateResidencies);
}
return ret;
}
-} // namespace powerstats
-} // namespace pixel
-} // namespace google
+std::unordered_map<std::string, std::vector<State>> AocStateResidencyDataProvider::getInfo() {
+ // States from the same power entity are merged
+ std::unordered_map<std::string, std::vector<State>> infos;
+ for (const auto &providerList : mProviders) {
+ int32_t stateId = 0;
+ std::string curEntity = providerList.first;
+ std::vector<State> stateInfos;
+
+ // Iterate over each provider in the providerList, appending each of the states
+ for (const auto &provider : providerList.second) {
+ std::unordered_map<std::string, std::vector<State>> info = provider->getInfo();
+
+ // Each provider should only return data for curEntity but checking anyway
+ if (info.find(curEntity) != info.end()) {
+ for (auto &i : info.at(curEntity)) {
+ /*
+ * Modifying stateId because we are stitching together infos from
+ * multiple GenericStateResidencyDataProviders. stateId must be modified
+ * to maintain uniqueness for a given entity
+ */
+ i.id = stateId++;
+ stateInfos.push_back(i);
+ }
+ }
+ }
+
+ infos.emplace(curEntity, stateInfos);
+ }
+
+ return infos;
+}
+
+} // namespace stats
+} // namespace power
} // namespace hardware
} // namespace android
+} // namespace aidl
diff --git a/powerstats/AocStateResidencyDataProvider.h b/powerstats/AocStateResidencyDataProvider.h
index eef7ce7..5008912 100644
--- a/powerstats/AocStateResidencyDataProvider.h
+++ b/powerstats/AocStateResidencyDataProvider.h
@@ -13,35 +13,33 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#ifndef HARDWARE_GOOGLE_PIXEL_POWERSTATS_AOCSTATERESIDENCYDATAPROVIDER_H
-#define HARDWARE_GOOGLE_PIXEL_POWERSTATS_AOCSTATERESIDENCYDATAPROVIDER_H
+#pragma once
-#include <pixelpowerstats/GenericStateResidencyDataProvider.h>
-#include <pixelpowerstats/PowerStats.h>
+#include <dataproviders/GenericStateResidencyDataProvider.h>
+#include <PowerStatsAidl.h>
+namespace aidl {
namespace android {
namespace hardware {
-namespace google {
-namespace pixel {
-namespace powerstats {
+namespace power {
+namespace stats {
-class AocStateResidencyDataProvider : public IStateResidencyDataProvider {
+class AocStateResidencyDataProvider : public PowerStats::IStateResidencyDataProvider {
public:
- AocStateResidencyDataProvider(std::vector<std::pair<uint32_t, std::string>> ids,
+ AocStateResidencyDataProvider(std::vector<std::pair<std::string, std::string>> ids,
std::vector<std::pair<std::string, std::string>> states);
~AocStateResidencyDataProvider() = default;
- bool getResults(
- std::unordered_map<uint32_t, PowerEntityStateResidencyResult> &results) override;
- std::vector<PowerEntityStateSpace> getStateSpaces() override;
+ bool getStateResidencies(
+ std::unordered_map<std::string, std::vector<StateResidency>> *residencies) override;
+ std::unordered_map<std::string, std::vector<State>> getInfo() override;
private:
- std::vector<std::unique_ptr<GenericStateResidencyDataProvider>> mProviders;
+ std::unordered_map<std::string /* entity name */,
+ std::vector<std::unique_ptr<GenericStateResidencyDataProvider>> /* providers */> mProviders;
};
-} // namespace powerstats
-} // namespace pixel
-} // namespace google
+} // namespace stats
+} // namespace power
} // namespace hardware
} // namespace android
-
-#endif // HARDWARE_GOOGLE_PIXEL_POWERSTATS_AOCSTATERESIDENCYDATAPROVIDER_H
+} // namespace aidl
\ No newline at end of file
diff --git a/powerstats/AocStateResidencyDataProviderAidl.cpp b/powerstats/AocStateResidencyDataProviderAidl.cpp
deleted file mode 100644
index 3759a66..0000000
--- a/powerstats/AocStateResidencyDataProviderAidl.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-#include "AocStateResidencyDataProviderAidl.h"
-
-#include <android-base/logging.h>
-
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace power {
-namespace stats {
-
-AocStateResidencyDataProvider::AocStateResidencyDataProvider(std::vector<std::pair<std::string,
- std::string>> ids, std::vector<std::pair<std::string, std::string>> states) {
- // AoC stats are reported in ticks of 244.140625ns. The transform
- // function converts ticks to milliseconds.
- // 1000000 / 244.140625 = 4096.
- static const uint64_t AOC_CLK = 4096;
- std::function<uint64_t(uint64_t)> aocTickToMs = [](uint64_t a) { return a / AOC_CLK; };
- GenericStateResidencyDataProvider::StateResidencyConfig config = {
- .entryCountSupported = true,
- .entryCountPrefix = "Counter:",
- .totalTimeSupported = true,
- .totalTimePrefix = "Cumulative time:",
- .totalTimeTransform = aocTickToMs,
- .lastEntrySupported = true,
- .lastEntryPrefix = "Time last entered:",
- .lastEntryTransform = aocTickToMs,
- };
- for (const auto &id : ids) {
- for (const auto &state : states) {
- std::vector<std::pair<std::string, std::string>> aocStateHeaders = {
- std::make_pair(state.first, ""),
- };
- std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> cfgs;
- cfgs.emplace_back(generateGenericStateResidencyConfigs(config, aocStateHeaders),
- id.first, "");
- std::unique_ptr<GenericStateResidencyDataProvider> sdp(
- new GenericStateResidencyDataProvider(id.second + state.second, cfgs));
- mProviders[id.first].push_back(std::move(sdp));
- }
- }
-}
-
-bool AocStateResidencyDataProvider::getStateResidencies(
- std::unordered_map<std::string, std::vector<StateResidency>> *residencies) {
- // States from the same power entity are merged.
- bool ret = true;
- for (const auto &providerList : mProviders) {
- int32_t stateId = 0;
- std::string curEntity = providerList.first;
- std::vector<StateResidency> stateResidencies;
-
- // Iterate over each provider in the providerList, appending each of the states
- for (const auto &provider : providerList.second) {
- std::unordered_map<std::string, std::vector<StateResidency>> residency;
- ret &= provider->getStateResidencies(&residency);
-
- // Each provider should only return data for curEntity but checking anyway
- if (residency.find(curEntity) != residency.end()) {
- for (auto &r : residency.at(curEntity)) {
- /*
- * Modifying stateId here because we are stitching together infos from
- * multiple GenericStateResidencyDataProviders. stateId must be modified
- * to maintain uniqueness for a given entity
- */
- r.id = stateId++;
- stateResidencies.push_back(r);
- }
- }
- }
-
- residencies->emplace(curEntity, stateResidencies);
- }
- return ret;
-}
-
-std::unordered_map<std::string, std::vector<State>> AocStateResidencyDataProvider::getInfo() {
- // States from the same power entity are merged
- std::unordered_map<std::string, std::vector<State>> infos;
- for (const auto &providerList : mProviders) {
- int32_t stateId = 0;
- std::string curEntity = providerList.first;
- std::vector<State> stateInfos;
-
- // Iterate over each provider in the providerList, appending each of the states
- for (const auto &provider : providerList.second) {
- std::unordered_map<std::string, std::vector<State>> info = provider->getInfo();
-
- // Each provider should only return data for curEntity but checking anyway
- if (info.find(curEntity) != info.end()) {
- for (auto &i : info.at(curEntity)) {
- /*
- * Modifying stateId because we are stitching together infos from
- * multiple GenericStateResidencyDataProviders. stateId must be modified
- * to maintain uniqueness for a given entity
- */
- i.id = stateId++;
- stateInfos.push_back(i);
- }
- }
- }
-
- infos.emplace(curEntity, stateInfos);
- }
-
- return infos;
-}
-
-} // namespace stats
-} // namespace power
-} // namespace hardware
-} // namespace android
-} // namespace aidl
diff --git a/powerstats/AocStateResidencyDataProviderAidl.h b/powerstats/AocStateResidencyDataProviderAidl.h
deleted file mode 100644
index 5008912..0000000
--- a/powerstats/AocStateResidencyDataProviderAidl.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2020 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 <dataproviders/GenericStateResidencyDataProvider.h>
-#include <PowerStatsAidl.h>
-
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace power {
-namespace stats {
-
-class AocStateResidencyDataProvider : public PowerStats::IStateResidencyDataProvider {
- public:
- AocStateResidencyDataProvider(std::vector<std::pair<std::string, std::string>> ids,
- std::vector<std::pair<std::string, std::string>> states);
- ~AocStateResidencyDataProvider() = default;
- bool getStateResidencies(
- std::unordered_map<std::string, std::vector<StateResidency>> *residencies) override;
- std::unordered_map<std::string, std::vector<State>> getInfo() override;
-
- private:
- std::unordered_map<std::string /* entity name */,
- std::vector<std::unique_ptr<GenericStateResidencyDataProvider>> /* providers */> mProviders;
-};
-
-} // namespace stats
-} // namespace power
-} // namespace hardware
-} // namespace android
-} // namespace aidl
\ No newline at end of file
diff --git a/powerstats/DvfsStateResidencyDataProvider.cpp b/powerstats/DvfsStateResidencyDataProvider.cpp
index 95289bd..511159e 100644
--- a/powerstats/DvfsStateResidencyDataProvider.cpp
+++ b/powerstats/DvfsStateResidencyDataProvider.cpp
@@ -13,8 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#define LOG_TAG "libpixelpowerstats"
-
#include "DvfsStateResidencyDataProvider.h"
#include <android-base/logging.h>
@@ -29,97 +27,90 @@
using android::base::StartsWith;
using android::base::Trim;
+static const std::string nameSuffix = "-DVFS";
+
+namespace aidl {
namespace android {
namespace hardware {
-namespace google {
-namespace pixel {
-namespace powerstats {
+namespace power {
+namespace stats {
-DvfsStateResidencyDataProvider::DvfsStateResidencyDataProvider(std::string path, uint64_t clockRate)
- : mPath(std::move(path)), mClockRate(clockRate) {}
+DvfsStateResidencyDataProvider::DvfsStateResidencyDataProvider(std::string path, uint64_t clockRate,
+ std::vector<Config> cfgs)
+ : mPath(std::move(path)), mClockRate(clockRate), mPowerEntities(std::move(cfgs)) {}
-void DvfsStateResidencyDataProvider::addEntity(
- uint32_t id, std::string name, std::vector<std::pair<std::string, std::string>> states) {
- mPowerEntities.push_back({id, name, states});
-}
-
-int32_t DvfsStateResidencyDataProvider::matchEntity(char *line) {
- for (auto const &entity : mPowerEntities) {
- if (entity.powerEntityName == Trim(std::string(line))) {
- return entity.powerEntityId;
+int32_t DvfsStateResidencyDataProvider::matchEntity(char const *line) {
+ for (int32_t i = 0; i < mPowerEntities.size(); i++) {
+ if (mPowerEntities[i].powerEntityName == Trim(std::string(line))) {
+ return i;
}
}
return -1;
}
-int32_t DvfsStateResidencyDataProvider::matchState(char *line, int32_t entityId) {
- uint32_t stateId = 0;
- for (auto const &entity : mPowerEntities) {
- if (entityId == entity.powerEntityId) {
- for (auto const &state : entity.states) {
- if (StartsWith(Trim(std::string(line)), state.second)) {
- return stateId;
- }
- stateId++;
- }
- return -1;
+int32_t DvfsStateResidencyDataProvider::matchState(char const *line, const Config& powerEntity) {
+ for (int32_t i = 0; i < powerEntity.states.size(); i++) {
+ if (StartsWith(Trim(std::string(line)), powerEntity.states[i].second)) {
+ return i;
}
}
return -1;
}
-bool DvfsStateResidencyDataProvider::parseState(char *line, uint64_t &duration, uint64_t &count) {
+bool DvfsStateResidencyDataProvider::parseState(char const *line, uint64_t *duration,
+ uint64_t *count) {
std::vector<std::string> parts = Split(line, " ");
if (parts.size() != 7) {
return false;
}
- if (!ParseUint(Trim(parts[3]), &count)) {
+ if (!ParseUint(Trim(parts[3]), count)) {
return false;
}
- if (!ParseUint(Trim(parts[6]), &duration)) {
+ if (!ParseUint(Trim(parts[6]), duration)) {
return false;
}
return true;
}
-bool DvfsStateResidencyDataProvider::getResults(
- std::unordered_map<uint32_t, PowerEntityStateResidencyResult> &results) {
+bool DvfsStateResidencyDataProvider::getStateResidencies(
+ std::unordered_map<std::string, std::vector<StateResidency>> *residencies) {
std::unique_ptr<FILE, decltype(&fclose)> fp(fopen(mPath.c_str(), "r"), fclose);
if (!fp) {
- PLOG(ERROR) << __func__ << ":Failed to open file " << mPath
- << " Error = " << strerror(errno);
+ PLOG(ERROR) << __func__ << ":Failed to open file " << mPath;
return false;
}
- for (auto const &stateSpace : getStateSpaces()) {
- PowerEntityStateResidencyResult result = {.powerEntityId = stateSpace.powerEntityId};
- result.stateResidencyData.resize(stateSpace.states.size());
- for (uint32_t i = 0; i < result.stateResidencyData.size(); i++) {
- result.stateResidencyData[i].powerEntityStateId =
- stateSpace.states[i].powerEntityStateId;
+ for (const Config &powerEntity : mPowerEntities) {
+ std::vector<StateResidency> stateResidency(powerEntity.states.size());
+ for (int32_t i = 0; i < stateResidency.size(); i++) {
+ stateResidency[i].id = i;
}
- results.insert(std::make_pair(stateSpace.powerEntityId, result));
+ residencies->emplace(powerEntity.powerEntityName + nameSuffix, stateResidency);
}
size_t len = 0;
char *line = nullptr;
- int32_t temp = -1, entityId = -1, stateId = -1;
+ int32_t temp, powerEntityIndex, stateId = -1;
uint64_t duration, count;
+ auto it = residencies->end();
while (getline(&line, &len, fp.get()) != -1) {
temp = matchEntity(line);
- // Assign entityId only when a new valid entity is encountered.
+ // Assign new index only when a new valid entity is encountered.
if (temp >= 0) {
- entityId = temp;
+ powerEntityIndex = temp;
+ it = residencies->find(mPowerEntities[powerEntityIndex].powerEntityName + nameSuffix);
}
- if (entityId >= 0) {
- stateId = matchState(line, entityId);
+
+ if (it != residencies->end()) {
+ stateId = matchState(line, mPowerEntities[powerEntityIndex]);
+
if (stateId >= 0) {
- if (parseState(line, duration, count)) {
- results[entityId].stateResidencyData[stateId].totalTimeInStateMs =
+ if (parseState(line, &duration, &count)) {
+ it->second[stateId].totalTimeInStateMs =
duration / mClockRate;
- results[entityId].stateResidencyData[stateId].totalStateEntryCount = count;
+ it->second[stateId].totalStateEntryCount = count;
} else {
LOG(ERROR) << "Failed to parse duration and count from [" << std::string(line)
<< "]";
@@ -134,25 +125,25 @@
return true;
}
-std::vector<PowerEntityStateSpace> DvfsStateResidencyDataProvider::getStateSpaces() {
- std::vector<PowerEntityStateSpace> stateSpaces;
- stateSpaces.reserve(mPowerEntities.size());
+std::unordered_map<std::string, std::vector<State>> DvfsStateResidencyDataProvider::getInfo() {
+ std::unordered_map<std::string, std::vector<State>> info;
for (auto const &entity : mPowerEntities) {
- PowerEntityStateSpace s = {.powerEntityId = entity.powerEntityId};
- s.states.resize(entity.states.size());
- uint32_t stateId = 0;
+ std::vector<State> stateInfo(entity.states.size());
+ int32_t stateId = 0;
for (auto const &state : entity.states) {
- s.states[stateId] = {.powerEntityStateId = stateId,
- .powerEntityStateName = state.first};
+ stateInfo[stateId] = State{
+ .id = stateId,
+ .name = state.first
+ };
stateId++;
}
- stateSpaces.emplace_back(s);
+ info.emplace(entity.powerEntityName + nameSuffix, stateInfo);
}
- return stateSpaces;
+ return info;
}
-} // namespace powerstats
-} // namespace pixel
-} // namespace google
+} // namespace stats
+} // namespace power
} // namespace hardware
} // namespace android
+} // namespace aidl
diff --git a/powerstats/DvfsStateResidencyDataProvider.h b/powerstats/DvfsStateResidencyDataProvider.h
index ffa1414..ca8ab22 100644
--- a/powerstats/DvfsStateResidencyDataProvider.h
+++ b/powerstats/DvfsStateResidencyDataProvider.h
@@ -13,71 +13,56 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#ifndef HARDWARE_GOOGLE_PIXEL_POWERSTATS_DVFSSTATERESIDENCYDATAPROVIDER_H
-#define HARDWARE_GOOGLE_PIXEL_POWERSTATS_DVFSSTATERESIDENCYDATAPROVIDER_H
+#pragma once
-#include <pixelpowerstats/PowerStats.h>
+#include <PowerStatsAidl.h>
+namespace aidl {
namespace android {
namespace hardware {
-namespace google {
-namespace pixel {
-namespace powerstats {
+namespace power {
+namespace stats {
-class DvfsStateResidencyDataProvider : public IStateResidencyDataProvider {
+class DvfsStateResidencyDataProvider : public PowerStats::IStateResidencyDataProvider {
public:
- /*
- * path - path to dvfs sysfs node.
- * clockRate - clock rate in KHz.
- */
- DvfsStateResidencyDataProvider(std::string path, uint64_t clockRate);
- ~DvfsStateResidencyDataProvider() = default;
-
- /*
- * id - the power entity id
- * name - the power entity name to parse from sysfs node
- * frequencies - list of pairs (frequency display name, frequency in sysfs
- * node).
- */
- void addEntity(uint32_t id, std::string name,
- std::vector<std::pair<std::string, std::string>> frequencies);
-
- /*
- * See IStateResidencyDataProvider::getResults.
- */
- bool getResults(
- std::unordered_map<uint32_t, PowerEntityStateResidencyResult> &results) override;
-
- /*
- * See IStateResidencyDataProvider::getStateSpaces.
- */
- std::vector<PowerEntityStateSpace> getStateSpaces() override;
-
- private:
- int32_t matchEntity(char *line);
- int32_t matchState(char *line, int32_t entityId);
- bool parseState(char *line, uint64_t &duration, uint64_t &count);
-
- const std::string mPath;
- const uint64_t mClockRate;
-
- struct config {
- // Power entity id.
- uint32_t powerEntityId;
-
+ class Config {
+ public:
// Power entity name to parse.
std::string powerEntityName;
// List of state pairs (name to display, name to parse).
std::vector<std::pair<std::string, std::string>> states;
};
- std::vector<config> mPowerEntities;
+ /*
+ * path - path to dvfs sysfs node.
+ * clockRate - clock rate in KHz.
+ */
+ DvfsStateResidencyDataProvider(std::string path, uint64_t clockRate, std::vector<Config> cfgs);
+ ~DvfsStateResidencyDataProvider() = default;
+
+ /*
+ * See IStateResidencyDataProvider::getStateResidencies
+ */
+ bool getStateResidencies(
+ std::unordered_map<std::string, std::vector<StateResidency>> *residencies) override;
+
+ /*
+ * See IStateResidencyDataProvider::getInfo
+ */
+ std::unordered_map<std::string, std::vector<State>> getInfo() override;
+
+ private:
+ int32_t matchEntity(char const *line);
+ int32_t matchState(char const *line, const Config& powerEntity);
+ bool parseState(char const *line, uint64_t *duration, uint64_t *count);
+
+ const std::string mPath;
+ const uint64_t mClockRate;
+ std::vector<Config> mPowerEntities;
};
-} // namespace powerstats
-} // namespace pixel
-} // namespace google
+} // namespace stats
+} // namespace power
} // namespace hardware
} // namespace android
-
-#endif // HARDWARE_GOOGLE_PIXEL_POWERSTATS_DVFSSTATERESIDENCYDATAPROVIDER_H
+} // namespace aidl
diff --git a/powerstats/DvfsStateResidencyDataProviderAidl.cpp b/powerstats/DvfsStateResidencyDataProviderAidl.cpp
deleted file mode 100644
index ca6ea9a..0000000
--- a/powerstats/DvfsStateResidencyDataProviderAidl.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-#include "DvfsStateResidencyDataProviderAidl.h"
-
-#include <android-base/logging.h>
-#include <android-base/parseint.h>
-#include <android-base/strings.h>
-
-#include <string>
-#include <utility>
-
-using android::base::ParseUint;
-using android::base::Split;
-using android::base::StartsWith;
-using android::base::Trim;
-
-static const std::string nameSuffix = "-DVFS";
-
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace power {
-namespace stats {
-
-DvfsStateResidencyDataProvider::DvfsStateResidencyDataProvider(std::string path, uint64_t clockRate,
- std::vector<Config> cfgs)
- : mPath(std::move(path)), mClockRate(clockRate), mPowerEntities(std::move(cfgs)) {}
-
-int32_t DvfsStateResidencyDataProvider::matchEntity(char const *line) {
- for (int32_t i = 0; i < mPowerEntities.size(); i++) {
- if (mPowerEntities[i].powerEntityName == Trim(std::string(line))) {
- return i;
- }
- }
- return -1;
-}
-
-int32_t DvfsStateResidencyDataProvider::matchState(char const *line, const Config& powerEntity) {
- for (int32_t i = 0; i < powerEntity.states.size(); i++) {
- if (StartsWith(Trim(std::string(line)), powerEntity.states[i].second)) {
- return i;
- }
- }
- return -1;
-}
-
-bool DvfsStateResidencyDataProvider::parseState(char const *line, uint64_t *duration,
- uint64_t *count) {
- std::vector<std::string> parts = Split(line, " ");
- if (parts.size() != 7) {
- return false;
- }
- if (!ParseUint(Trim(parts[3]), count)) {
- return false;
- }
- if (!ParseUint(Trim(parts[6]), duration)) {
- return false;
- }
- return true;
-}
-
-bool DvfsStateResidencyDataProvider::getStateResidencies(
- std::unordered_map<std::string, std::vector<StateResidency>> *residencies) {
- std::unique_ptr<FILE, decltype(&fclose)> fp(fopen(mPath.c_str(), "r"), fclose);
- if (!fp) {
- PLOG(ERROR) << __func__ << ":Failed to open file " << mPath;
- return false;
- }
-
- for (const Config &powerEntity : mPowerEntities) {
- std::vector<StateResidency> stateResidency(powerEntity.states.size());
- for (int32_t i = 0; i < stateResidency.size(); i++) {
- stateResidency[i].id = i;
- }
- residencies->emplace(powerEntity.powerEntityName + nameSuffix, stateResidency);
- }
-
- size_t len = 0;
- char *line = nullptr;
-
- int32_t temp, powerEntityIndex, stateId = -1;
- uint64_t duration, count;
- auto it = residencies->end();
-
- while (getline(&line, &len, fp.get()) != -1) {
- temp = matchEntity(line);
- // Assign new index only when a new valid entity is encountered.
- if (temp >= 0) {
- powerEntityIndex = temp;
- it = residencies->find(mPowerEntities[powerEntityIndex].powerEntityName + nameSuffix);
- }
-
- if (it != residencies->end()) {
- stateId = matchState(line, mPowerEntities[powerEntityIndex]);
-
- if (stateId >= 0) {
- if (parseState(line, &duration, &count)) {
- it->second[stateId].totalTimeInStateMs =
- duration / mClockRate;
- it->second[stateId].totalStateEntryCount = count;
- } else {
- LOG(ERROR) << "Failed to parse duration and count from [" << std::string(line)
- << "]";
- return false;
- }
- }
- }
- }
-
- free(line);
-
- return true;
-}
-
-std::unordered_map<std::string, std::vector<State>> DvfsStateResidencyDataProvider::getInfo() {
- std::unordered_map<std::string, std::vector<State>> info;
- for (auto const &entity : mPowerEntities) {
- std::vector<State> stateInfo(entity.states.size());
- int32_t stateId = 0;
- for (auto const &state : entity.states) {
- stateInfo[stateId] = State{
- .id = stateId,
- .name = state.first
- };
- stateId++;
- }
- info.emplace(entity.powerEntityName + nameSuffix, stateInfo);
- }
- return info;
-}
-
-} // namespace stats
-} // namespace power
-} // namespace hardware
-} // namespace android
-} // namespace aidl
diff --git a/powerstats/DvfsStateResidencyDataProviderAidl.h b/powerstats/DvfsStateResidencyDataProviderAidl.h
deleted file mode 100644
index ca8ab22..0000000
--- a/powerstats/DvfsStateResidencyDataProviderAidl.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2020 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 <PowerStatsAidl.h>
-
-namespace aidl {
-namespace android {
-namespace hardware {
-namespace power {
-namespace stats {
-
-class DvfsStateResidencyDataProvider : public PowerStats::IStateResidencyDataProvider {
- public:
- class Config {
- public:
- // Power entity name to parse.
- std::string powerEntityName;
-
- // List of state pairs (name to display, name to parse).
- std::vector<std::pair<std::string, std::string>> states;
- };
- /*
- * path - path to dvfs sysfs node.
- * clockRate - clock rate in KHz.
- */
- DvfsStateResidencyDataProvider(std::string path, uint64_t clockRate, std::vector<Config> cfgs);
- ~DvfsStateResidencyDataProvider() = default;
-
- /*
- * See IStateResidencyDataProvider::getStateResidencies
- */
- bool getStateResidencies(
- std::unordered_map<std::string, std::vector<StateResidency>> *residencies) override;
-
- /*
- * See IStateResidencyDataProvider::getInfo
- */
- std::unordered_map<std::string, std::vector<State>> getInfo() override;
-
- private:
- int32_t matchEntity(char const *line);
- int32_t matchState(char const *line, const Config& powerEntity);
- bool parseState(char const *line, uint64_t *duration, uint64_t *count);
-
- const std::string mPath;
- const uint64_t mClockRate;
- std::vector<Config> mPowerEntities;
-};
-
-} // namespace stats
-} // namespace power
-} // namespace hardware
-} // namespace android
-} // namespace aidl
diff --git a/powerstats/RailDataProvider.cpp b/powerstats/RailDataProvider.cpp
deleted file mode 100644
index d0efc17..0000000
--- a/powerstats/RailDataProvider.cpp
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Copyright (C) 2018 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 LOG_TAG "libpixelpowerstats"
-
-#include "RailDataProvider.h"
-
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <android-base/properties.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#include <inttypes.h>
-#include <stdlib.h>
-
-#include <algorithm>
-#include <exception>
-#include <thread>
-
-namespace android {
-namespace hardware {
-namespace google {
-namespace pixel {
-namespace powerstats {
-
-#define MAX_FILE_PATH_LEN 128
-#define MAX_DEVICE_NAME_LEN 64
-#define MAX_QUEUE_SIZE 8192
-
-constexpr char kIioDirRoot[] = "/sys/bus/iio/devices/";
-const char *const kDeviceNames[] = {"s2mpg10-odpm", "s2mpg11-odpm"};
-constexpr char kDeviceType[] = "iio:device";
-constexpr uint32_t MAX_SAMPLING_RATE = 10;
-constexpr uint64_t WRITE_TIMEOUT_NS = 1000000000;
-
-#define MAX_RAIL_NAME_LEN 50
-#define STR(s) #s
-#define XSTR(s) STR(s)
-
-void RailDataProvider::findIioPowerMonitorNodes() {
- struct dirent *ent;
- int fd;
- char devName[MAX_DEVICE_NAME_LEN];
- char filePath[MAX_FILE_PATH_LEN];
- DIR *iioDir = opendir(kIioDirRoot);
- if (!iioDir) {
- ALOGE("Error opening directory: %s, error: %d", kIioDirRoot, errno);
- return;
- }
- while (ent = readdir(iioDir), ent) {
- if (strcmp(ent->d_name, ".") != 0 && strcmp(ent->d_name, "..") != 0 &&
- strlen(ent->d_name) > strlen(kDeviceType) &&
- strncmp(ent->d_name, kDeviceType, strlen(kDeviceType)) == 0) {
- snprintf(filePath, MAX_FILE_PATH_LEN, "%s/%s", ent->d_name, "name");
- fd = openat(dirfd(iioDir), filePath, O_RDONLY);
- if (fd < 0) {
- ALOGW("Failed to open directory: %s, error: %d", filePath, errno);
- continue;
- }
- if (read(fd, devName, MAX_DEVICE_NAME_LEN) < 0) {
- ALOGW("Failed to read device name from file: %s(%d)", filePath, fd);
- close(fd);
- continue;
- }
-
- for (const auto &kDeviceName : kDeviceNames) {
- if (strncmp(devName, kDeviceName, strlen(kDeviceName)) == 0) {
- snprintf(filePath, MAX_FILE_PATH_LEN, "%s/%s", kIioDirRoot, ent->d_name);
- mOdpm.devicePaths.push_back(filePath);
- }
- }
- close(fd);
- }
- }
- closedir(iioDir);
- return;
-}
-
-size_t RailDataProvider::parsePowerRails() {
- std::string data;
- std::string railFileName;
- std::string spsFileName;
- uint32_t index = 0;
- uint32_t samplingRate;
- for (const auto &path : mOdpm.devicePaths) {
- railFileName = path + "/enabled_rails";
- spsFileName = path + "/sampling_rate";
- if (!android::base::ReadFileToString(spsFileName, &data)) {
- ALOGW("Error reading file: %s", spsFileName.c_str());
- continue;
- }
- samplingRate = strtoul(data.c_str(), NULL, 10);
- if (!samplingRate || samplingRate == ULONG_MAX) {
- ALOGE("Error parsing: %s", spsFileName.c_str());
- break;
- }
- if (!android::base::ReadFileToString(railFileName, &data)) {
- ALOGW("Error reading file: %s", railFileName.c_str());
- continue;
- }
- std::istringstream railNames(data);
- std::string line;
- while (std::getline(railNames, line)) {
- std::vector<std::string> words = android::base::Split(line, ":][");
- if (words.size() == 4) {
- const std::string channelName = words[1];
- if (mOdpm.railsInfo.count(channelName) == 0) {
- const std::string subsysName = words[3];
- mOdpm.railsInfo.emplace(channelName, RailData{.devicePath = path,
- .index = index,
- .subsysName = subsysName,
- .samplingRate = samplingRate});
- index++;
- } else {
- ALOGW("There exists rails with the same name (not supported): %s." \
- " Only the last occurrence of rail energy will be provided.",
- channelName.c_str());
- }
- } else {
- ALOGW("Unexpected format in file: %s", railFileName.c_str());
- }
- }
- }
- return index;
-}
-
-int RailDataProvider::parseIioEnergyNodeString(const std::string &contents, OnDeviceMmt &odpm) {
- std::istringstream energyData(contents);
- std::string line;
-
- int ret = 0;
- uint64_t timestamp = 0;
- bool timestampRead = false;
-
- while (std::getline(energyData, line)) {
- bool parseLineSuccess = false;
-
- if (timestampRead == false) {
- /* Read timestamp from boot (ms) */
- if (sscanf(line.c_str(), "t=%" PRIu64, ×tamp) == 1) {
- if (timestamp == 0 || timestamp == ULLONG_MAX) {
- ALOGW("Potentially wrong timestamp: %" PRIu64, timestamp);
- }
- timestampRead = true;
- parseLineSuccess = true;
- }
-
- } else {
- /* Read rail energy */
- uint64_t energy = 0;
- char railNameRaw[MAX_RAIL_NAME_LEN + 1];
- if (sscanf(line.c_str(),
- "CH%*d(T=%*" PRIu64 ")[%" XSTR(MAX_RAIL_NAME_LEN) "[^]]], %" PRIu64,
- railNameRaw, &energy) == 2) {
- std::string railName(railNameRaw);
-
- /* If the count == 0, the rail may not be enabled */
- /* The count cannot be > 1; mChannelIds is a map */
- if (odpm.railsInfo.count(railName) == 1) {
- size_t index = odpm.railsInfo[railName].index;
- odpm.reading[index].index = index;
- odpm.reading[index].timestamp = timestamp;
- odpm.reading[index].energy = energy;
- if (odpm.reading[index].energy == ULLONG_MAX) {
- ALOGW("Potentially wrong energy value on rail: %s", railName.c_str());
- }
- }
- parseLineSuccess = true;
- }
- }
-
- if (parseLineSuccess == false) {
- ret = -1;
- break;
- }
- }
-
- return ret;
-}
-
-int RailDataProvider::parseIioEnergyNode(std::string devName) {
- int ret;
- std::string data;
- std::string fileName = devName + "/energy_value";
- if (!android::base::ReadFileToString(fileName, &data)) {
- ALOGE("Error reading file: %s", fileName.c_str());
- return -1;
- }
-
- ret = parseIioEnergyNodeString(data, mOdpm);
- if (ret != 0) {
- ALOGW("Unexpected format in file: %s", fileName.c_str());
- }
- return ret;
-}
-
-Status RailDataProvider::parseIioEnergyNodes() {
- Status ret = Status::SUCCESS;
- if (mOdpm.hwEnabled == false) {
- return Status::NOT_SUPPORTED;
- }
-
- for (const auto &devicePath : mOdpm.devicePaths) {
- if (parseIioEnergyNode(devicePath) < 0) {
- ALOGE("Error in parsing power stats");
- ret = Status::FILESYSTEM_ERROR;
- break;
- }
- }
- return ret;
-}
-
-RailDataProvider::RailDataProvider() {
- findIioPowerMonitorNodes();
- size_t numRails = parsePowerRails();
- if (mOdpm.devicePaths.empty() || numRails == 0) {
- mOdpm.hwEnabled = false;
- } else {
- mOdpm.hwEnabled = true;
- mOdpm.reading.resize(numRails);
- }
-}
-
-Return<void> RailDataProvider::getRailInfo(IPowerStats::getRailInfo_cb _hidl_cb) {
- hidl_vec<RailInfo> rInfo;
- Status ret = Status::SUCCESS;
- size_t index;
- std::lock_guard<std::mutex> _lock(mOdpm.mLock);
- if (mOdpm.hwEnabled == false) {
- ALOGI("getRailInfo not supported");
- _hidl_cb(rInfo, Status::NOT_SUPPORTED);
- return Void();
- }
- rInfo.resize(mOdpm.railsInfo.size());
- for (const auto &railData : mOdpm.railsInfo) {
- index = railData.second.index;
- rInfo[index].railName = railData.first;
- rInfo[index].subsysName = railData.second.subsysName;
- rInfo[index].index = index;
- rInfo[index].samplingRate = railData.second.samplingRate;
- }
- _hidl_cb(rInfo, ret);
- return Void();
-}
-
-Return<void> RailDataProvider::getEnergyData(const hidl_vec<uint32_t> &railIndices,
- IPowerStats::getEnergyData_cb _hidl_cb) {
- hidl_vec<EnergyData> eVal;
- std::lock_guard<std::mutex> _lock(mOdpm.mLock);
- Status ret = parseIioEnergyNodes();
-
- if (ret != Status::SUCCESS) {
- ALOGE("Failed to getEnergyData");
- _hidl_cb(eVal, ret);
- return Void();
- }
-
- if (railIndices.size() == 0) {
- eVal.resize(mOdpm.railsInfo.size());
- memcpy(&eVal[0], &mOdpm.reading[0], mOdpm.reading.size() * sizeof(EnergyData));
- } else {
- eVal.resize(railIndices.size());
- int i = 0;
- for (const auto &railIndex : railIndices) {
- if (railIndex >= mOdpm.reading.size()) {
- ret = Status::INVALID_INPUT;
- eVal.resize(0);
- break;
- }
- memcpy(&eVal[i], &mOdpm.reading[railIndex], sizeof(EnergyData));
- i++;
- }
- }
- _hidl_cb(eVal, ret);
- return Void();
-}
-
-Return<void> RailDataProvider::streamEnergyData(uint32_t timeMs, uint32_t samplingRate,
- IPowerStats::streamEnergyData_cb _hidl_cb) {
- std::lock_guard<std::mutex> _lock(mOdpm.mLock);
- if (mOdpm.fmqSynchronized != nullptr) {
- _hidl_cb(MessageQueueSync::Descriptor(), 0, 0, Status::INSUFFICIENT_RESOURCES);
- return Void();
- }
- uint32_t sps = std::min(samplingRate, MAX_SAMPLING_RATE);
- uint32_t numSamples = timeMs * sps / 1000;
- mOdpm.fmqSynchronized.reset(new (std::nothrow) MessageQueueSync(MAX_QUEUE_SIZE, true));
- if (mOdpm.fmqSynchronized == nullptr || mOdpm.fmqSynchronized->isValid() == false) {
- mOdpm.fmqSynchronized = nullptr;
- _hidl_cb(MessageQueueSync::Descriptor(), 0, 0, Status::INSUFFICIENT_RESOURCES);
- return Void();
- }
- std::thread pollThread = std::thread([this, sps, numSamples]() {
- uint64_t sleepTimeUs = 1000000 / sps;
- uint32_t currSamples = 0;
- while (currSamples < numSamples) {
- mOdpm.mLock.lock();
- if (parseIioEnergyNodes() == Status::SUCCESS) {
- mOdpm.fmqSynchronized->writeBlocking(&mOdpm.reading[0], mOdpm.reading.size(),
- WRITE_TIMEOUT_NS);
- mOdpm.mLock.unlock();
- currSamples++;
- if (usleep(sleepTimeUs) < 0) {
- ALOGW("Sleep interrupted");
- break;
- }
- } else {
- mOdpm.mLock.unlock();
- break;
- }
- }
- mOdpm.mLock.lock();
- mOdpm.fmqSynchronized = nullptr;
- mOdpm.mLock.unlock();
- return;
- });
- pollThread.detach();
- _hidl_cb(*(mOdpm.fmqSynchronized)->getDesc(), numSamples, mOdpm.reading.size(),
- Status::SUCCESS);
- return Void();
-}
-
-} // namespace powerstats
-} // namespace pixel
-} // namespace google
-} // namespace hardware
-} // namespace android
diff --git a/powerstats/RailDataProvider.h b/powerstats/RailDataProvider.h
deleted file mode 100644
index 61313e2..0000000
--- a/powerstats/RailDataProvider.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef ANDROID_HARDWARE_POWERSTATS_RAILDATAPROVIDER_H
-#define ANDROID_HARDWARE_POWERSTATS_RAILDATAPROVIDER_H
-
-#include <fmq/MessageQueue.h>
-#include <pixelpowerstats/PowerStats.h>
-
-namespace android {
-namespace hardware {
-namespace google {
-namespace pixel {
-namespace powerstats {
-
-typedef MessageQueue<EnergyData, kSynchronizedReadWrite> MessageQueueSync;
-struct RailData {
- std::string devicePath;
- uint32_t index;
- std::string subsysName;
- uint32_t samplingRate;
-};
-
-struct OnDeviceMmt {
- std::mutex mLock;
- bool hwEnabled;
- std::vector<std::string> devicePaths;
- std::map<std::string, RailData> railsInfo;
- std::vector<EnergyData> reading;
- std::unique_ptr<MessageQueueSync> fmqSynchronized;
-};
-
-class RailDataProvider : public IRailDataProvider {
-public:
- RailDataProvider();
- // Methods from ::android::hardware::power::stats::V1_0::IPowerStats follow.
- Return<void> getRailInfo(IPowerStats::getRailInfo_cb _hidl_cb) override;
- Return<void> getEnergyData(const hidl_vec<uint32_t>& railIndices,
- IPowerStats::getEnergyData_cb _hidl_cb) override;
- Return<void> streamEnergyData(uint32_t timeMs, uint32_t samplingRate,
- IPowerStats::streamEnergyData_cb _hidl_cb) override;
- private:
- OnDeviceMmt mOdpm;
- void findIioPowerMonitorNodes();
- size_t parsePowerRails();
- int parseIioEnergyNodeString(const std::string &contents,
- OnDeviceMmt &odpm);
- int parseIioEnergyNode(std::string devName);
- Status parseIioEnergyNodes();
-};
-
-} // namespace powerstats
-} // namespace pixel
-} // namespace google
-} // namespace hardware
-} // namespace android
-
-#endif // ANDROID_HARDWARE_POWERSTATS_RAILDATAPROVIDER_H
diff --git a/powerstats/UfsStateResidencyDataProvider.cpp b/powerstats/UfsStateResidencyDataProvider.cpp
deleted file mode 100644
index 7ca6f3b..0000000
--- a/powerstats/UfsStateResidencyDataProvider.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2020 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 LOG_TAG "libpixelpowerstats"
-
-#include "UfsStateResidencyDataProvider.h"
-
-#include <android-base/logging.h>
-#include <android-base/parseint.h>
-#include <android-base/strings.h>
-
-#include <string>
-#include <utility>
-
-using android::base::ParseUint;
-using android::base::Split;
-using android::base::StartsWith;
-using android::base::Trim;
-
-namespace android {
-namespace hardware {
-namespace google {
-namespace pixel {
-namespace powerstats {
-
-const uint32_t HIBERNATE_STATE_ID = 0;
-
-UfsStateResidencyDataProvider::UfsStateResidencyDataProvider(uint32_t powerEntityId)
- : mPowerEntityId(powerEntityId) {}
-
-bool UfsStateResidencyDataProvider::getResults(
- std::unordered_map<uint32_t, PowerEntityStateResidencyResult> &results) {
- PowerEntityStateResidencyResult result = {
- .powerEntityId = mPowerEntityId,
- .stateResidencyData = {{.powerEntityStateId = HIBERNATE_STATE_ID}}};
-
- // The transform function converts microseconds to milliseconds.
- std::function<uint64_t(uint64_t)> usecToMs = [](uint64_t a) { return a / 1000; };
-
- std::string prefix = "/sys/bus/platform/devices/14700000.ufs/ufs_stats/";
-
- result.stateResidencyData[0].totalTimeInStateMs =
- usecToMs(readStat(prefix + "hibern8_total_us"));
- result.stateResidencyData[0].totalStateEntryCount = readStat(prefix + "hibern8_exit_cnt");
- result.stateResidencyData[0].lastEntryTimestampMs =
- usecToMs(readStat(prefix + "last_hibern8_enter_time"));
- results.insert(std::make_pair(mPowerEntityId, result));
- return true;
-}
-
-std::vector<PowerEntityStateSpace> UfsStateResidencyDataProvider::getStateSpaces() {
- return {{.powerEntityId = mPowerEntityId,
- .states = {{.powerEntityStateId = HIBERNATE_STATE_ID,
- .powerEntityStateName = "HIBERN8"}}}};
-}
-
-uint64_t UfsStateResidencyDataProvider::readStat(std::string path) {
- std::unique_ptr<FILE, decltype(&fclose)> fp(fopen(path.c_str(), "r"), fclose);
- if (!fp) {
- PLOG(ERROR) << __func__ << ":Failed to open file " << path
- << " Error = " << strerror(errno);
- return 0;
- }
- const size_t size = 20;
- char buf[size];
- (void)fread(&buf, sizeof(char), size, fp.get());
- uint64_t ret;
- if (!ParseUint(Trim(std::string(buf)), &ret)) {
- LOG(ERROR) << "Failed to parse uint64 from [" << std::string(buf) << "]";
- }
- return ret;
-}
-
-} // namespace powerstats
-} // namespace pixel
-} // namespace google
-} // namespace hardware
-} // namespace android
diff --git a/powerstats/UfsStateResidencyDataProvider.h b/powerstats/UfsStateResidencyDataProvider.h
deleted file mode 100644
index 8d1ea73..0000000
--- a/powerstats/UfsStateResidencyDataProvider.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-#ifndef HARDWARE_GOOGLE_PIXEL_POWERSTATS_UFSSTATERESIDENCYDATAPROVIDER_H
-#define HARDWARE_GOOGLE_PIXEL_POWERSTATS_UFSSTATERESIDENCYDATAPROVIDER_H
-
-#include <pixelpowerstats/PowerStats.h>
-
-namespace android {
-namespace hardware {
-namespace google {
-namespace pixel {
-namespace powerstats {
-
-class UfsStateResidencyDataProvider : public IStateResidencyDataProvider {
- public:
- /*
- * powerEntityId - id for the UFS power entity.
- */
- UfsStateResidencyDataProvider(uint32_t powerEntityId);
- ~UfsStateResidencyDataProvider() = default;
-
- /*
- * See IStateResidencyDataProvider::getResults.
- */
- bool getResults(
- std::unordered_map<uint32_t, PowerEntityStateResidencyResult> &results) override;
-
- /*
- * See IStateResidencyDataProvider::getStateSpaces.
- */
- std::vector<PowerEntityStateSpace> getStateSpaces() override;
-
- private:
- uint64_t readStat(std::string path);
-
- uint32_t mPowerEntityId;
-};
-
-} // namespace powerstats
-} // namespace pixel
-} // namespace google
-} // namespace hardware
-} // namespace android
-
-#endif // HARDWARE_GOOGLE_PIXEL_POWERSTATS_UFSSTATERESIDENCYDATAPROVIDER_H
diff --git a/powerstats/android.hardware.power.stats@1.0-service.gs101.rc b/powerstats/android.hardware.power.stats@1.0-service.gs101.rc
deleted file mode 100644
index afc3580..0000000
--- a/powerstats/android.hardware.power.stats@1.0-service.gs101.rc
+++ /dev/null
@@ -1,5 +0,0 @@
-service vendor.power.stats-hal-1-0 /vendor/bin/hw/android.hardware.power.stats@1.0-service.gs101
- interface android.hardware.power.stats@1.0::IPowerStats default
- class hal
- user system
- group system
diff --git a/powerstats/android.hardware.power.stats@1.0-service.gs101.xml b/powerstats/android.hardware.power.stats@1.0-service.gs101.xml
deleted file mode 100644
index 2e9956f..0000000
--- a/powerstats/android.hardware.power.stats@1.0-service.gs101.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<manifest version="1.0" type="device">
- <hal format="hidl">
- <name>android.hardware.power.stats</name>
- <transport>hwbinder</transport>
- <version>1.0</version>
- <interface>
- <name>IPowerStats</name>
- <instance>default</instance>
- </interface>
- </hal>
-</manifest>
diff --git a/powerstats/service.cpp b/powerstats/service.cpp
index 4cf1f35..632de32 100644
--- a/powerstats/service.cpp
+++ b/powerstats/service.cpp
@@ -14,313 +14,174 @@
* limitations under the License.
*/
-#define LOG_TAG "android.hardware.power.stats@1.0-service.gs101"
+#define LOG_TAG "android.hardware.power.stats-service.pixel"
-#include <android/log.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-#include <binder/ProcessState.h>
-#include <hidl/HidlTransportSupport.h>
-#include <pixelpowerstats/AidlStateResidencyDataProvider.h>
-#include <pixelpowerstats/GenericStateResidencyDataProvider.h>
-#include <pixelpowerstats/PowerStats.h>
-
+#include <PowerStatsAidl.h>
#include "AocStateResidencyDataProvider.h"
#include "DvfsStateResidencyDataProvider.h"
-#include "RailDataProvider.h"
-#include "UfsStateResidencyDataProvider.h"
+#include <dataproviders/DisplayStateResidencyDataProvider.h>
+#include <dataproviders/GenericStateResidencyDataProvider.h>
+#include <dataproviders/IioEnergyMeterDataProvider.h>
+#include <dataproviders/PowerStatsEnergyConsumer.h>
+#include <dataproviders/PowerStatsEnergyAttribution.h>
+#include <dataproviders/PixelStateResidencyDataProvider.h>
-using android::OK;
-using android::sp;
-using android::status_t;
+#include <android-base/logging.h>
+#include <android-base/properties.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <log/log.h>
-// libhwbinder:
-using android::hardware::configureRpcThreadpool;
-using android::hardware::joinRpcThreadpool;
+using aidl::android::hardware::power::stats::AocStateResidencyDataProvider;
+using aidl::android::hardware::power::stats::DisplayStateResidencyDataProvider;
+using aidl::android::hardware::power::stats::DvfsStateResidencyDataProvider;
+using aidl::android::hardware::power::stats::EnergyConsumerType;
+using aidl::android::hardware::power::stats::GenericStateResidencyDataProvider;
+using aidl::android::hardware::power::stats::IioEnergyMeterDataProvider;
+using aidl::android::hardware::power::stats::PixelStateResidencyDataProvider;
+using aidl::android::hardware::power::stats::PowerStats;
+using aidl::android::hardware::power::stats::PowerStatsEnergyConsumer;
-// Generated HIDL files
-using android::hardware::power::stats::V1_0::IPowerStats;
-using android::hardware::power::stats::V1_0::PowerEntityType;
-using android::hardware::power::stats::V1_0::implementation::PowerStats;
+constexpr char kBootHwSoCRev[] = "ro.boot.hw.soc.rev";
-// Pixel specific
-using android::hardware::google::pixel::powerstats::AidlStateResidencyDataProvider;
-using android::hardware::google::pixel::powerstats::AocStateResidencyDataProvider;
-using android::hardware::google::pixel::powerstats::DvfsStateResidencyDataProvider;
-using android::hardware::google::pixel::powerstats::generateGenericStateResidencyConfigs;
-using android::hardware::google::pixel::powerstats::GenericStateResidencyDataProvider;
-using android::hardware::google::pixel::powerstats::PowerEntityConfig;
-using android::hardware::google::pixel::powerstats::RailDataProvider;
-using android::hardware::google::pixel::powerstats::StateResidencyConfig;
-using android::hardware::google::pixel::powerstats::UfsStateResidencyDataProvider;
-
-// A constant to represnt the number of nanoseconds in one millisecond.
-static const int NS_TO_MS = 1000000;
-
-void addAoCStats(PowerStats *const service) {
+void addAoC(std::shared_ptr<PowerStats> p) {
std::string prefix = "/sys/devices/platform/19000000.aoc/control/";
// Add AoC cores (a32, ff1, hf0, and hf1)
- std::vector<std::pair<uint32_t, std::string>> coreIds = {
- {service->addPowerEntity("AoC-A32", PowerEntityType::SUBSYSTEM), prefix + "a32_"},
- {service->addPowerEntity("AoC-FF1", PowerEntityType::SUBSYSTEM), prefix + "ff1_"},
- {service->addPowerEntity("AoC-HF1", PowerEntityType::SUBSYSTEM), prefix + "hf1_"},
- {service->addPowerEntity("AoC-HF0", PowerEntityType::SUBSYSTEM), prefix + "hf0_"},
+ std::vector<std::pair<std::string, std::string>> coreIds = {
+ {"AoC-A32", prefix + "a32_"},
+ {"AoC-FF1", prefix + "ff1_"},
+ {"AoC-HF1", prefix + "hf1_"},
+ {"AoC-HF0", prefix + "hf0_"},
};
std::vector<std::pair<std::string, std::string>> coreStates = {
{"DWN", "off"}, {"RET", "retention"}, {"WFI", "wfi"}};
- service->addStateResidencyDataProvider(new AocStateResidencyDataProvider(coreIds, coreStates));
+ p->addStateResidencyDataProvider(std::make_shared<AocStateResidencyDataProvider>(coreIds,
+ coreStates));
// Add AoC voltage stats
- std::vector<std::pair<uint32_t, std::string>> voltageIds = {
- {service->addPowerEntity("AoC-Voltage", PowerEntityType::SUBSYSTEM),
- prefix + "voltage_"},
+ std::vector<std::pair<std::string, std::string>> voltageIds = {
+ {"AoC-Voltage", prefix + "voltage_"},
};
std::vector<std::pair<std::string, std::string>> voltageStates = {{"NOM", "nominal"},
{"SUD", "super_underdrive"},
{"UUD", "ultra_underdrive"},
{"UD", "underdrive"}};
- service->addStateResidencyDataProvider(
- new AocStateResidencyDataProvider(voltageIds, voltageStates));
+ p->addStateResidencyDataProvider(
+ std::make_shared<AocStateResidencyDataProvider>(voltageIds, voltageStates));
// Add AoC monitor mode
- std::vector<std::pair<uint32_t, std::string>> monitorIds = {
- {service->addPowerEntity("AoC", PowerEntityType::SUBSYSTEM), prefix + "monitor_"},
+ std::vector<std::pair<std::string, std::string>> monitorIds = {
+ {"AoC", prefix + "monitor_"},
};
std::vector<std::pair<std::string, std::string>> monitorStates = {
{"MON", "mode"},
};
- service->addStateResidencyDataProvider(
- new AocStateResidencyDataProvider(monitorIds, monitorStates));
+ p->addStateResidencyDataProvider(
+ std::make_shared<AocStateResidencyDataProvider>(monitorIds, monitorStates));
}
-void addCpuCStateStats(PowerStats *const service) {
- // CPU stats are reported in nanoseconds. The transform function
- // converts nanoseconds to milliseconds.
- std::function<uint64_t(uint64_t)> cpuNsToMs = [](uint64_t a) { return a / NS_TO_MS; };
- StateResidencyConfig cStateConfig = {
- .entryCountSupported = true,
- .entryCountPrefix = "down_count:",
- .totalTimeSupported = true,
- .totalTimePrefix = "total_down_time_ns:",
- .totalTimeTransform = cpuNsToMs,
- .lastEntrySupported = true,
- .lastEntryPrefix = "last_down_time_ns:",
- .lastEntryTransform = cpuNsToMs,
- };
+void addDvfsStats(std::shared_ptr<PowerStats> p) {
+ // A constant to represent the number of nanoseconds in one millisecond
+ const int NS_TO_MS = 1000000;
- sp<GenericStateResidencyDataProvider> cStateSdp = new GenericStateResidencyDataProvider(
- "/sys/devices/platform/1742048c.acpm_stats/core_stats");
- for (std::string state :
- {"CORE00", "CORE01", "CORE02", "CORE03", "CORE10", "CORE11", "CORE20", "CORE21"}) {
- cStateSdp->addEntity(service->addPowerEntity(state, PowerEntityType::SUBSYSTEM),
- PowerEntityConfig("CORES:", generateGenericStateResidencyConfigs(
- cStateConfig,
- {std::make_pair("DOWN", state)})));
- }
- for (std::string state : {"CLUSTER0", "CLUSTER1", "CLUSTER2"}) {
- cStateSdp->addEntity(
- service->addPowerEntity(state, PowerEntityType::SUBSYSTEM),
- PowerEntityConfig("CLUSTERS:",
- generateGenericStateResidencyConfigs(
- cStateConfig, {std::make_pair("DOWN", state)})));
- }
- service->addStateResidencyDataProvider(cStateSdp);
+ std::vector<DvfsStateResidencyDataProvider::Config> cfgs;
+
+ cfgs.push_back({"MIF", {
+ std::make_pair("3172KHz", "3172000"),
+ std::make_pair("2730KHz", "2730000"),
+ std::make_pair("2535KHz", "2535000"),
+ std::make_pair("2288KHz", "2288000"),
+ std::make_pair("2028KHz", "2028000"),
+ std::make_pair("1716KHz", "1716000"),
+ std::make_pair("1539KHz", "1539000"),
+ std::make_pair("1352KHz", "1352000"),
+ std::make_pair("1014KHz", "1014000"),
+ std::make_pair("845KHz", "845000"),
+ std::make_pair("676KHz", "676000"),
+ std::make_pair("546KHz", "546000"),
+ std::make_pair("421KHz", "421000"),
+ std::make_pair("0KHz", "0"),
+ }});
+
+ cfgs.push_back({"CL0", {
+ std::make_pair("2024KHz", "2024000"),
+ std::make_pair("1950KHz", "1950000"),
+ std::make_pair("1868KHz", "1868000"),
+ std::make_pair("1803KHz", "1803000"),
+ std::make_pair("1745KHz", "1745000"),
+ std::make_pair("1704KHz", "1704000"),
+ std::make_pair("1598KHz", "1598000"),
+ std::make_pair("1459KHz", "1459000"),
+ std::make_pair("1401KHz", "1401000"),
+ std::make_pair("1328KHz", "1328000"),
+ std::make_pair("1197KHz", "1197000"),
+ std::make_pair("1098KHz", "1098000"),
+ std::make_pair("930KHz", "930000"),
+ std::make_pair("889KHz", "889000"),
+ std::make_pair("738KHz", "738000"),
+ std::make_pair("574KHz", "574000"),
+ std::make_pair("300KHz", "300000"),
+ std::make_pair("0KHz", "0"),
+ }});
+
+ cfgs.push_back({"CL1", {
+ std::make_pair("2253KHz", "2253000"),
+ std::make_pair("2130KHz", "2130000"),
+ std::make_pair("1999KHz", "1999000"),
+ std::make_pair("1836KHz", "1836000"),
+ std::make_pair("1663KHz", "1663000"),
+ std::make_pair("1491KHz", "1491000"),
+ std::make_pair("1328KHz", "1328000"),
+ std::make_pair("1197KHz", "1197000"),
+ std::make_pair("1024KHz", "1024000"),
+ std::make_pair("910KHz", "910000"),
+ std::make_pair("799KHz", "799000"),
+ std::make_pair("696KHz", "696000"),
+ std::make_pair("533KHz", "533000"),
+ std::make_pair("400KHz", "400000"),
+ std::make_pair("0KHz", "0"),
+ }});
+
+ cfgs.push_back({"CL2", {
+ std::make_pair("2630KHz", "2630000"),
+ std::make_pair("2507KHz", "2507000"),
+ std::make_pair("2401KHz", "2401000"),
+ std::make_pair("2302KHz", "2302000"),
+ std::make_pair("2252KHz", "2252000"),
+ std::make_pair("2188KHz", "2188000"),
+ std::make_pair("2048KHz", "2048000"),
+ std::make_pair("1901KHz", "1901000"),
+ std::make_pair("1826KHz", "1826000"),
+ std::make_pair("1745KHz", "1745000"),
+ std::make_pair("1582KHz", "1582000"),
+ std::make_pair("1426KHz", "1426000"),
+ std::make_pair("1277KHz", "1277000"),
+ std::make_pair("1237KHz", "1237000"),
+ std::make_pair("1106KHz", "1106000"),
+ std::make_pair("984KHz", "984000"),
+ std::make_pair("851KHz", "851000"),
+ std::make_pair("848KHz", "848000"),
+ std::make_pair("500KHz", "500000"),
+ std::make_pair("0KHz", "0"),
+ }});
+
+ cfgs.push_back({"TPU", {
+ std::make_pair("1066MHz", "1066000000"),
+ }});
+
+ p->addStateResidencyDataProvider(std::make_shared<DvfsStateResidencyDataProvider>(
+ "/sys/devices/platform/1742048c.acpm_stats/fvp_stats", NS_TO_MS, cfgs));
}
-void addDvfsStats(PowerStats *const service) {
- sp<DvfsStateResidencyDataProvider> dvfsSdp = new DvfsStateResidencyDataProvider(
- "/sys/devices/platform/1742048c.acpm_stats/fvp_stats", NS_TO_MS);
+void addSoC(std::shared_ptr<PowerStats> p) {
+ // A constant to represent the number of nanoseconds in one millisecond.
+ const int NS_TO_MS = 1000000;
- dvfsSdp->addEntity(service->addPowerEntity("MIF-DVFS", PowerEntityType::SUBSYSTEM), "MIF",
- {
- std::make_pair("3172KHz", "3172000"),
- std::make_pair("2730KHz", "2730000"),
- std::make_pair("2535KHz", "2535000"),
- std::make_pair("2288KHz", "2288000"),
- std::make_pair("2028KHz", "2028000"),
- std::make_pair("1716KHz", "1716000"),
- std::make_pair("1539KHz", "1539000"),
- std::make_pair("1352KHz", "1352000"),
- std::make_pair("1014KHz", "1014000"),
- std::make_pair("845KHz", "845000"),
- std::make_pair("676KHz", "676000"),
- std::make_pair("546KHz", "546000"),
- std::make_pair("421KHz", "421000"),
- std::make_pair("0KHz", "0"),
- });
-
- dvfsSdp->addEntity(service->addPowerEntity("CL0-DVFS", PowerEntityType::SUBSYSTEM), "CL0",
- {
- std::make_pair("2196KHz", "2196000"),
- std::make_pair("2098KHz", "2098000"),
- std::make_pair("2024KHz", "2024000"),
- std::make_pair("1950KHz", "1950000"),
- std::make_pair("1868KHz", "1868000"),
- std::make_pair("1745KHz", "1745000"),
- std::make_pair("1598KHz", "1598000"),
- std::make_pair("1459KHz", "1459000"),
- std::make_pair("1328KHz", "1328000"),
- std::make_pair("1197KHz", "1197000"),
- std::make_pair("1098KHz", "1098000"),
- std::make_pair("889KHz", "889000"),
- std::make_pair("738KHz", "738000"),
- std::make_pair("574KHz", "574000"),
- std::make_pair("300KHz", "300000"),
- std::make_pair("0KHz", "0"),
- });
-
- dvfsSdp->addEntity(service->addPowerEntity("CL1-DVFS", PowerEntityType::SUBSYSTEM), "CL1",
- {
- std::make_pair("2466KHz", "2466000"),
- std::make_pair("2393KHz", "2393000"),
- std::make_pair("2348KHz", "2348000"),
- std::make_pair("2253KHz", "2253000"),
- std::make_pair("2130KHz", "2130000"),
- std::make_pair("1999KHz", "1999000"),
- std::make_pair("1836KHz", "1836000"),
- std::make_pair("1663KHz", "1663000"),
- std::make_pair("1491KHz", "1491000"),
- std::make_pair("1328KHz", "1328000"),
- std::make_pair("1197KHz", "1197000"),
- std::make_pair("1024KHz", "1024000"),
- std::make_pair("910KHz", "910000"),
- std::make_pair("799KHz", "799000"),
- std::make_pair("696KHz", "696000"),
- std::make_pair("533KHz", "533000"),
- std::make_pair("400KHz", "400000"),
- std::make_pair("0KHz", "0"),
- });
-
- dvfsSdp->addEntity(service->addPowerEntity("CL2-DVFS", PowerEntityType::SUBSYSTEM), "CL2",
- {
- std::make_pair("3195KHz", "3195000"),
- std::make_pair("3097KHz", "3097000"),
- std::make_pair("2999KHz", "2999000"),
- std::make_pair("2900KHz", "2900000"),
- std::make_pair("2802KHz", "2802000"),
- std::make_pair("2704KHz", "2704000"),
- std::make_pair("2630KHz", "2630000"),
- std::make_pair("2507KHz", "2507000"),
- std::make_pair("2401KHz", "2401000"),
- std::make_pair("2302KHz", "2302000"),
- std::make_pair("2188KHz", "2188000"),
- std::make_pair("2048KHz", "2048000"),
- std::make_pair("1901KHz", "1901000"),
- std::make_pair("1745KHz", "1745000"),
- std::make_pair("1582KHz", "1582000"),
- std::make_pair("1426KHz", "1426000"),
- std::make_pair("1237KHz", "1237000"),
- std::make_pair("1106KHz", "1106000"),
- std::make_pair("984KHz", "984000"),
- std::make_pair("848KHz", "848000"),
- std::make_pair("500KHz", "500000"),
- std::make_pair("0KHz", "0"),
- });
-
- // TODO(sujee): Complete frequency table for TPU.
- dvfsSdp->addEntity(service->addPowerEntity("TPU-DVFS", PowerEntityType::SUBSYSTEM), "TPU",
- {
- std::make_pair("1066MHz", "1066000000"),
- });
-
- service->addStateResidencyDataProvider(dvfsSdp);
-}
-
-void addGPUStats(PowerStats *const service) {
- StateResidencyConfig gpuStateConfig = {
- .entryCountSupported = true,
- .entryCountPrefix = "count = ",
- .totalTimeSupported = true,
- .totalTimePrefix = "total_time = ",
- .lastEntrySupported = true,
- .lastEntryPrefix = "last_entry_time = ",
- };
-
- sp<GenericStateResidencyDataProvider> gpu = new GenericStateResidencyDataProvider(
- "/sys/devices/platform/1c500000.mali/power_stats");
-
- PowerEntityConfig onOffConfig("Summary stats: (times in ms)",
- generateGenericStateResidencyConfigs(
- gpuStateConfig, {{"DOWN", "OFF:"}, {"UP", "ON:"}}));
- gpu->addEntity(service->addPowerEntity("GPU", PowerEntityType::SUBSYSTEM), onOffConfig);
-
- PowerEntityConfig DVFSConfig(
- "DVFS stats: (times in ms)",
- generateGenericStateResidencyConfigs(gpuStateConfig, {{"996MHz", "996000:"},
- {"885MHz", "885000:"},
- {"750MHz", "750000:"},
- {"434MHz", "434000:"},
- {"302MHz", "302000:"},
- {"151MHz", "151000:"}}));
- gpu->addEntity(service->addPowerEntity("GPU-DVFS", PowerEntityType::SUBSYSTEM), DVFSConfig);
- service->addStateResidencyDataProvider(gpu);
-}
-
-void addNFCStats(PowerStats *const service) {
- StateResidencyConfig nfcStateConfig = {
- .entryCountSupported = true,
- .entryCountPrefix = "Cumulative count:",
- .totalTimeSupported = true,
- .totalTimePrefix = "Cumulative duration msec:",
- .lastEntrySupported = true,
- .lastEntryPrefix = "Last entry timestamp msec:",
- };
- std::vector<std::pair<std::string, std::string>> nfcStateHeaders = {
- std::make_pair("IDLE", "Idle mode:"),
- std::make_pair("ACTIVE", "Active mode:"),
- std::make_pair("ACTIVE-RW", "Active Reader/Writer mode:"),
- };
-
- sp<GenericStateResidencyDataProvider> nfcSdp = new GenericStateResidencyDataProvider(
- "/sys/devices/platform/10960000.hsi2c/i2c-4/4-0008/power_stats");
- nfcSdp->addEntity(service->addPowerEntity("NFC", PowerEntityType::SUBSYSTEM),
- PowerEntityConfig("NFC subsystem", generateGenericStateResidencyConfigs(
- nfcStateConfig, nfcStateHeaders)));
- service->addStateResidencyDataProvider(nfcSdp);
-}
-
-void addPCIeStats(PowerStats *const service) {
- // Add PCIe power entities for Modem and WiFi
- StateResidencyConfig pcieStateConfig = {
- .entryCountSupported = true,
- .entryCountPrefix = "Cumulative count:",
- .totalTimeSupported = true,
- .totalTimePrefix = "Cumulative duration msec:",
- .lastEntrySupported = true,
- .lastEntryPrefix = "Last entry timestamp msec:",
- };
- std::vector<std::pair<std::string, std::string>> pcieStateHeaders = {
- std::make_pair("UP", "Link up:"),
- std::make_pair("DOWN", "Link down:"),
- };
-
- // Add PCIe - Modem
- sp<GenericStateResidencyDataProvider> pcieModemSdp = new GenericStateResidencyDataProvider(
- "/sys/devices/platform/11920000.pcie/power_stats");
- uint32_t pcieModemId = service->addPowerEntity("PCIe-Modem", PowerEntityType::SUBSYSTEM);
- pcieModemSdp->addEntity(
- pcieModemId,
- PowerEntityConfig("Version: 1", generateGenericStateResidencyConfigs(
- pcieStateConfig, pcieStateHeaders)));
- service->addStateResidencyDataProvider(pcieModemSdp);
-
- // Add PCIe - WiFi
- sp<GenericStateResidencyDataProvider> pcieWifiSdp = new GenericStateResidencyDataProvider(
- "/sys/devices/platform/14520000.pcie/power_stats");
- uint32_t pcieWifiId = service->addPowerEntity("PCIe-WiFi", PowerEntityType::SUBSYSTEM);
- pcieWifiSdp->addEntity(
- pcieWifiId,
- PowerEntityConfig("Version: 1", generateGenericStateResidencyConfigs(
- pcieStateConfig, pcieStateHeaders)));
- service->addStateResidencyDataProvider(pcieWifiSdp);
-}
-
-void addSocStats(PowerStats *const service) {
// ACPM stats are reported in nanoseconds. The transform function
// converts nanoseconds to milliseconds.
std::function<uint64_t(uint64_t)> acpmNsToMs = [](uint64_t a) { return a / NS_TO_MS; };
- StateResidencyConfig lpmStateConfig = {
+ const GenericStateResidencyDataProvider::StateResidencyConfig lpmStateConfig = {
.entryCountSupported = true,
.entryCountPrefix = "success_count:",
.totalTimeSupported = true,
@@ -330,7 +191,7 @@
.lastEntryPrefix = "last_entry_time_ns:",
.lastEntryTransform = acpmNsToMs,
};
- StateResidencyConfig downStateConfig = {
+ const GenericStateResidencyDataProvider::StateResidencyConfig downStateConfig = {
.entryCountSupported = true,
.entryCountPrefix = "down_count:",
.totalTimeSupported = true,
@@ -340,7 +201,7 @@
.lastEntryPrefix = "last_down_time_ns:",
.lastEntryTransform = acpmNsToMs,
};
- StateResidencyConfig reqStateConfig = {
+ const GenericStateResidencyDataProvider::StateResidencyConfig reqStateConfig = {
.entryCountSupported = true,
.entryCountPrefix = "req_up_count:",
.totalTimeSupported = true,
@@ -351,141 +212,312 @@
.lastEntryTransform = acpmNsToMs,
};
- std::vector<std::pair<std::string, std::string>> powerStateHeaders = {
+ const std::vector<std::pair<std::string, std::string>> powerStateHeaders = {
std::make_pair("SICD", "SICD"),
std::make_pair("SLEEP", "SLEEP"),
std::make_pair("SLEEP_SLCMON", "SLEEP_SLCMON"),
std::make_pair("STOP", "STOP"),
};
- std::vector<std::pair<std::string, std::string>> mifReqStateHeaders = {
+ const std::vector<std::pair<std::string, std::string>> mifReqStateHeaders = {
std::make_pair("AOC", "AOC"),
std::make_pair("GSA", "GSA"),
};
- std::vector<std::pair<std::string, std::string>> slcReqStateHeaders = {
+ const std::vector<std::pair<std::string, std::string>> slcReqStateHeaders = {
std::make_pair("AOC", "AOC"),
};
- sp<GenericStateResidencyDataProvider> socSdp = new GenericStateResidencyDataProvider(
- "/sys/devices/platform/1742048c.acpm_stats/soc_stats");
+ std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> cfgs;
+ cfgs.emplace_back(generateGenericStateResidencyConfigs(lpmStateConfig, powerStateHeaders),
+ "LPM", "LPM:");
+ cfgs.emplace_back(generateGenericStateResidencyConfigs(downStateConfig, powerStateHeaders),
+ "MIF", "MIF:");
+ cfgs.emplace_back(generateGenericStateResidencyConfigs(reqStateConfig, mifReqStateHeaders),
+ "MIF-REQ", "MIF_REQ:");
+ cfgs.emplace_back(generateGenericStateResidencyConfigs(downStateConfig, powerStateHeaders),
+ "SLC", "SLC:");
+ cfgs.emplace_back(generateGenericStateResidencyConfigs(reqStateConfig, slcReqStateHeaders),
+ "SLC-REQ", "SLC_REQ:");
- socSdp->addEntity(service->addPowerEntity("LPM", PowerEntityType::SUBSYSTEM),
- PowerEntityConfig("LPM:", generateGenericStateResidencyConfigs(
- lpmStateConfig, powerStateHeaders)));
- socSdp->addEntity(service->addPowerEntity("MIF", PowerEntityType::SUBSYSTEM),
- PowerEntityConfig("MIF:", generateGenericStateResidencyConfigs(
- downStateConfig, powerStateHeaders)));
- socSdp->addEntity(service->addPowerEntity("MIF-REQ", PowerEntityType::SUBSYSTEM),
- PowerEntityConfig("MIF_REQ:", generateGenericStateResidencyConfigs(
- reqStateConfig, mifReqStateHeaders)));
- socSdp->addEntity(service->addPowerEntity("SLC", PowerEntityType::SUBSYSTEM),
- PowerEntityConfig("SLC:", generateGenericStateResidencyConfigs(
- downStateConfig, powerStateHeaders)));
- socSdp->addEntity(service->addPowerEntity("SLC-REQ", PowerEntityType::SUBSYSTEM),
- PowerEntityConfig("SLC_REQ:", generateGenericStateResidencyConfigs(
- reqStateConfig, slcReqStateHeaders)));
+ auto socSdp = std::make_shared<GenericStateResidencyDataProvider>(
+ "/sys/devices/platform/1742048c.acpm_stats/soc_stats", cfgs);
- service->addStateResidencyDataProvider(socSdp);
+ p->addStateResidencyDataProvider(socSdp);
}
-void addUfsStats(PowerStats *const service) {
- sp<UfsStateResidencyDataProvider> ufsSdp = new UfsStateResidencyDataProvider(
- service->addPowerEntity("UFS", PowerEntityType::SUBSYSTEM));
- service->addStateResidencyDataProvider(ufsSdp);
+void setEnergyMeter(std::shared_ptr<PowerStats> p) {
+ std::vector<const std::string> deviceNames { "s2mpg10-odpm", "s2mpg11-odpm" };
+ p->setEnergyMeterDataProvider(std::make_unique<IioEnergyMeterDataProvider>(deviceNames, true));
}
-void addWifiStats(PowerStats *const service) {
- sp<GenericStateResidencyDataProvider> wifiSdp =
- new GenericStateResidencyDataProvider("/sys/wifi/power_stats");
+void addDisplay(std::shared_ptr<PowerStats> p) {
+ // Add display residency stats
- // The transform function converts microseconds to milliseconds.
- std::function<uint64_t(uint64_t)> usecToMs = [](uint64_t a) { return a / 1000; };
- StateResidencyConfig stateConfig = {
+ /*
+ * TODO(b/167216667): Add complete set of display states here. Must account
+ * for ALL devices built using this source
+ */
+ std::vector<std::string> states = {
+ "Off",
+ "LP: 1440x3040@30",
+ "On: 1440x3040@60",
+ "On: 1440x3040@90",
+ "HBM: 1440x3040@60",
+ "HBM: 1440x3040@90"};
+
+ auto displaySdp =
+ std::make_shared<DisplayStateResidencyDataProvider>("Display",
+ "/sys/class/backlight/panel0-backlight/state",
+ states);
+ p->addStateResidencyDataProvider(displaySdp);
+
+ // Add display energy consumer
+ /*
+ * TODO(b/167216667): Add correct display power model here. Must read from display rail
+ * and include proper coefficients for display states. Must account for ALL devices built
+ * using this source.
+ */
+ auto displayConsumer = PowerStatsEnergyConsumer::createMeterAndEntityConsumer(p,
+ EnergyConsumerType::DISPLAY, "display", {"PPVAR_VSYS_PWR_DISP"}, "Display",
+ {{"LP: 1440x3040@30", 1},
+ {"On: 1440x3040@60", 2},
+ {"On: 1440x3040@90", 3}});
+
+ p->addEnergyConsumer(displayConsumer);
+}
+
+void addCPUclusters(std::shared_ptr<PowerStats> p) {
+ p->addEnergyConsumer(PowerStatsEnergyConsumer::createMeterConsumer(p,
+ EnergyConsumerType::CPU_CLUSTER, "CPUCL0", {"S4M_VDD_CPUCL0"}));
+ p->addEnergyConsumer(PowerStatsEnergyConsumer::createMeterConsumer(p,
+ EnergyConsumerType::CPU_CLUSTER, "CPUCL1", {"S3M_VDD_CPUCL1"}));
+ p->addEnergyConsumer(PowerStatsEnergyConsumer::createMeterConsumer(p,
+ EnergyConsumerType::CPU_CLUSTER, "CPUCL2", {"S2M_VDD_CPUCL2"}));
+}
+
+void addGPU(std::shared_ptr<PowerStats> p) {
+ // Add gpu energy consumer
+ std::map<std::string, int32_t> stateCoeffs;
+ const int socRev = android::base::GetIntProperty(kBootHwSoCRev, 0);
+
+ // B0/B1 chips have different GPU DVFS operating points than A0/A1 SoC
+ if (socRev >= 2) {
+ stateCoeffs = {
+ {"151000", 10},
+ {"202000", 20},
+ {"251000", 30},
+ {"302000", 40},
+ {"351000", 50},
+ {"400000", 60},
+ {"471000", 70},
+ {"510000", 80},
+ {"572000", 90},
+ {"701000", 100},
+ {"762000", 110},
+ {"848000", 120}};
+ } else {
+ stateCoeffs = {
+ {"151000", 10},
+ {"302000", 20},
+ {"455000", 30},
+ {"572000", 40},
+ {"670000", 50}};
+ }
+
+ auto gpuConsumer = PowerStatsEnergyConsumer::createMeterAndAttrConsumer(p,
+ EnergyConsumerType::OTHER, "GPU", {"S2S_VDD_G3D"},
+ {{UID_TIME_IN_STATE, "/sys/devices/platform/1c500000.mali/uid_time_in_state"}},
+ stateCoeffs);
+
+ p->addEnergyConsumer(gpuConsumer);
+}
+
+void addMobileRadio(std::shared_ptr<PowerStats> p)
+{
+ // A constant to represent the number of microseconds in one millisecond.
+ const int US_TO_MS = 1000;
+
+ // modem power_stats are reported in microseconds. The transform function
+ // converts microseconds to milliseconds.
+ std::function<uint64_t(uint64_t)> modemUsToMs = [](uint64_t a) { return a / US_TO_MS; };
+ const GenericStateResidencyDataProvider::StateResidencyConfig powerStateConfig = {
.entryCountSupported = true,
.entryCountPrefix = "count:",
.totalTimeSupported = true,
.totalTimePrefix = "duration_usec:",
- .totalTimeTransform = usecToMs,
+ .totalTimeTransform = modemUsToMs,
.lastEntrySupported = true,
.lastEntryPrefix = "last_entry_timestamp_usec:",
- .lastEntryTransform = usecToMs,
+ .lastEntryTransform = modemUsToMs,
};
- StateResidencyConfig pcieStateConfig = {
- .entryCountSupported = true,
- .entryCountPrefix = "count:",
- .totalTimeSupported = true,
- .totalTimePrefix = "duration_usec:",
- .totalTimeTransform = usecToMs,
+ const std::vector<std::pair<std::string, std::string>> powerStateHeaders = {
+ std::make_pair("SLEEP", "SLEEP:"),
};
- std::vector<std::pair<std::string, std::string>> stateHeaders = {
- std::make_pair("AWAKE", "AWAKE:"),
- std::make_pair("ASLEEP", "ASLEEP:"),
- };
- std::vector<std::pair<std::string, std::string>> pcieStateHeaders = {
- std::make_pair("L0", "L0:"), std::make_pair("L1", "L1:"),
- std::make_pair("L1_1", "L1_1:"), std::make_pair("L1_2", "L1_2:"),
- std::make_pair("L2", "L2:"),
- };
+ std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> cfgs;
+ cfgs.emplace_back(generateGenericStateResidencyConfigs(powerStateConfig, powerStateHeaders),
+ "MODEM", "");
- wifiSdp->addEntity(
- service->addPowerEntity("WIFI", PowerEntityType::SUBSYSTEM),
- PowerEntityConfig(generateGenericStateResidencyConfigs(stateConfig, stateHeaders)));
- wifiSdp->addEntity(service->addPowerEntity("WIFI-PCIE", PowerEntityType::SUBSYSTEM),
- PowerEntityConfig(generateGenericStateResidencyConfigs(pcieStateConfig,
- pcieStateHeaders)));
+ p->addStateResidencyDataProvider(std::make_shared<GenericStateResidencyDataProvider>(
+ "/sys/devices/platform/cpif/modem/power_stats", cfgs));
- service->addStateResidencyDataProvider(wifiSdp);
+ p->addEnergyConsumer(PowerStatsEnergyConsumer::createMeterConsumer(p,
+ EnergyConsumerType::MOBILE_RADIO, "MODEM", {"VSYS_PWR_MODEM", "VSYS_PWR_RFFE"}));
}
-int main(int /* argc */, char ** /* argv */) {
- ALOGI("power.stats service 1.0 is starting.");
+void addGNSS(std::shared_ptr<PowerStats> p)
+{
+ p->addEnergyConsumer(PowerStatsEnergyConsumer::createMeterConsumer(p,
+ EnergyConsumerType::GNSS, "GPS", {"L9S_GNSS_CORE"}));
+}
- PowerStats *service = new PowerStats();
+void addNFC(std::shared_ptr<PowerStats> p) {
+ const GenericStateResidencyDataProvider::StateResidencyConfig nfcStateConfig = {
+ .entryCountSupported = true,
+ .entryCountPrefix = "Cumulative count:",
+ .totalTimeSupported = true,
+ .totalTimePrefix = "Cumulative duration msec:",
+ .lastEntrySupported = true,
+ .lastEntryPrefix = "Last entry timestamp msec:",
+ };
+ const std::vector<std::pair<std::string, std::string>> nfcStateHeaders = {
+ std::make_pair("IDLE", "Idle mode:"),
+ std::make_pair("ACTIVE", "Active mode:"),
+ std::make_pair("ACTIVE-RW", "Active Reader/Writer mode:"),
+ };
- // Add rail data provider
- service->setRailDataProvider(std::make_unique<RailDataProvider>());
+ std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> cfgs;
+ cfgs.emplace_back(generateGenericStateResidencyConfigs(nfcStateConfig, nfcStateHeaders),
+ "NFC", "NFC subsystem");
- addAoCStats(service);
- addCpuCStateStats(service);
- addDvfsStats(service);
- addGPUStats(service);
- addNFCStats(service);
- addPCIeStats(service);
- addSocStats(service);
- addUfsStats(service);
- addWifiStats(service);
+ auto nfcSdp = std::make_shared<GenericStateResidencyDataProvider>(
+ "/sys/devices/platform/10960000.hsi2c/i2c-3/3-0008/power_stats", cfgs);
- // Add Power Entities that require the Aidl data provider
- sp<AidlStateResidencyDataProvider> aidlSdp = new AidlStateResidencyDataProvider();
- uint32_t bluetoothId = service->addPowerEntity("Bluetooth", PowerEntityType::SUBSYSTEM);
- aidlSdp->addEntity(bluetoothId, "Bluetooth", {"Idle", "Active", "Tx", "Rx"});
- uint32_t citadelId = service->addPowerEntity("Citadel", PowerEntityType::SUBSYSTEM);
- aidlSdp->addEntity(citadelId, "Citadel", {"Last-Reset", "Active", "Deep-Sleep"});
- service->addStateResidencyDataProvider(aidlSdp);
+ p->addStateResidencyDataProvider(nfcSdp);
+}
- auto serviceStatus = android::defaultServiceManager()->addService(
- android::String16("power.stats-vendor"), aidlSdp);
- if (serviceStatus != android::OK) {
- ALOGE("Unable to register power.stats-vendor service %d", serviceStatus);
- return 1;
- }
+void addPCIe(std::shared_ptr<PowerStats> p) {
+ // Add PCIe power entities for Modem and WiFi
+ const GenericStateResidencyDataProvider::StateResidencyConfig pcieStateConfig = {
+ .entryCountSupported = true,
+ .entryCountPrefix = "Cumulative count:",
+ .totalTimeSupported = true,
+ .totalTimePrefix = "Cumulative duration msec:",
+ .lastEntrySupported = true,
+ .lastEntryPrefix = "Last entry timestamp msec:",
+ };
+ const std::vector<std::pair<std::string, std::string>> pcieStateHeaders = {
+ std::make_pair("UP", "Link up:"),
+ std::make_pair("DOWN", "Link down:"),
+ };
- sp<android::ProcessState> ps{android::ProcessState::self()}; // Create non-HW binder threadpool
- ps->startThreadPool();
+ // Add PCIe - Modem
+ const std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> pcieModemCfgs = {
+ {generateGenericStateResidencyConfigs(pcieStateConfig, pcieStateHeaders), "PCIe-Modem",
+ "Version: 1"}
+ };
+ auto pcieModemSdp = std::make_shared<GenericStateResidencyDataProvider>(
+ "/sys/devices/platform/11920000.pcie/power_stats", pcieModemCfgs);
+ p->addStateResidencyDataProvider(pcieModemSdp);
- // Configure the threadpool
- configureRpcThreadpool(1, true /*callerWillJoin*/);
+ // Add PCIe - WiFi
+ const std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> pcieWifiCfgs = {
+ {generateGenericStateResidencyConfigs(pcieStateConfig, pcieStateHeaders),
+ "PCIe-WiFi", "Version: 1"}
+ };
+ auto pcieWifiSdp = std::make_shared<GenericStateResidencyDataProvider>(
+ "/sys/devices/platform/14520000.pcie/power_stats", pcieWifiCfgs);
+ p->addStateResidencyDataProvider(pcieWifiSdp);
+}
- status_t status = service->registerAsService();
- if (status != OK) {
- ALOGE("Could not register service for power.stats HAL Iface (%d), exiting.", status);
- return 1;
- }
+void addWifi(std::shared_ptr<PowerStats> p) {
+ // The transform function converts microseconds to milliseconds.
+ std::function<uint64_t(uint64_t)> usecToMs = [](uint64_t a) { return a / 1000; };
+ const GenericStateResidencyDataProvider::StateResidencyConfig stateConfig = {
+ .entryCountSupported = true,
+ .entryCountPrefix = "count:",
+ .totalTimeSupported = true,
+ .totalTimePrefix = "duration_usec:",
+ .totalTimeTransform = usecToMs,
+ .lastEntrySupported = true,
+ .lastEntryPrefix = "last_entry_timestamp_usec:",
+ .lastEntryTransform = usecToMs,
+ };
+ const GenericStateResidencyDataProvider::StateResidencyConfig pcieStateConfig = {
+ .entryCountSupported = true,
+ .entryCountPrefix = "count:",
+ .totalTimeSupported = true,
+ .totalTimePrefix = "duration_usec:",
+ .totalTimeTransform = usecToMs,
+ .lastEntrySupported = false,
+ };
- ALOGI("power.stats service is ready");
- joinRpcThreadpool();
+ const std::vector<std::pair<std::string, std::string>> stateHeaders = {
+ std::make_pair("AWAKE", "AWAKE:"),
+ std::make_pair("ASLEEP", "ASLEEP:"),
- // In normal operation, we don't expect the thread pool to exit
- ALOGE("power.stats service is shutting down");
- return 1;
+ };
+ const std::vector<std::pair<std::string, std::string>> pcieStateHeaders = {
+ std::make_pair("L0", "L0:"),
+ std::make_pair("L1", "L1:"),
+ std::make_pair("L1_1", "L1_1:"),
+ std::make_pair("L1_2", "L1_2:"),
+ std::make_pair("L2", "L2:"),
+ };
+
+ const std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> cfgs = {
+ {generateGenericStateResidencyConfigs(stateConfig, stateHeaders), "WIFI", "WIFI"},
+ {generateGenericStateResidencyConfigs(pcieStateConfig, pcieStateHeaders), "WIFI-PCIE",
+ "WIFI-PCIE"}
+ };
+
+ auto wifiSdp = std::make_shared<GenericStateResidencyDataProvider>("/sys/wifi/power_stats",
+ cfgs);
+ p->addStateResidencyDataProvider(wifiSdp);
+}
+
+/**
+ * Unlike other data providers, which source power entity state residency data from the kernel,
+ * this data provider acts as a general-purpose channel for state residency data providers
+ * that live in user space. Entities are defined here and user space clients of this provider's
+ * vendor service register callbacks to provide state residency data for their given pwoer entity.
+ */
+void addPixelStateResidencyDataProvider(std::shared_ptr<PowerStats> p) {
+ std::shared_ptr<PixelStateResidencyDataProvider> pixelSdp =
+ ndk::SharedRefBase::make<PixelStateResidencyDataProvider>();
+
+ pixelSdp->addEntity("Bluetooth", {{0, "Idle"}, {1, "Active"}, {2, "Tx"}, {3, "Rx"}});
+
+ pixelSdp->start();
+ p->addStateResidencyDataProvider(pixelSdp);
+}
+
+int main() {
+ LOG(INFO) << "Pixel PowerStats HAL AIDL Service is starting.";
+
+ // single thread
+ ABinderProcess_setThreadPoolMaxThreadCount(0);
+
+ std::shared_ptr<PowerStats> p = ndk::SharedRefBase::make<PowerStats>();
+
+ setEnergyMeter(p);
+
+ addPixelStateResidencyDataProvider(p);
+ addAoC(p);
+ addDisplay(p);
+ addDvfsStats(p);
+ addSoC(p);
+ addCPUclusters(p);
+ addGPU(p);
+ addMobileRadio(p);
+ addGNSS(p);
+ addNFC(p);
+ addPCIe(p);
+ addWifi(p);
+
+ const std::string instance = std::string() + PowerStats::descriptor + "/default";
+ binder_status_t status = AServiceManager_addService(p->asBinder().get(), instance.c_str());
+ LOG_ALWAYS_FATAL_IF(status != STATUS_OK);
+
+ ABinderProcess_joinThreadPool();
+ return EXIT_FAILURE; // should not reach
}
diff --git a/powerstats/serviceaidl.cpp b/powerstats/serviceaidl.cpp
deleted file mode 100644
index 8c15775..0000000
--- a/powerstats/serviceaidl.cpp
+++ /dev/null
@@ -1,523 +0,0 @@
-/*
- * Copyright (C) 2020 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 LOG_TAG "android.hardware.power.stats-service.pixel"
-
-#include <PowerStatsAidl.h>
-#include "AocStateResidencyDataProviderAidl.h"
-#include "DvfsStateResidencyDataProviderAidl.h"
-#include <dataproviders/DisplayStateResidencyDataProvider.h>
-#include <dataproviders/GenericStateResidencyDataProvider.h>
-#include <dataproviders/IioEnergyMeterDataProvider.h>
-#include <dataproviders/PowerStatsEnergyConsumer.h>
-#include <dataproviders/PowerStatsEnergyAttribution.h>
-#include <dataproviders/PixelStateResidencyDataProvider.h>
-
-#include <android-base/logging.h>
-#include <android-base/properties.h>
-#include <android/binder_manager.h>
-#include <android/binder_process.h>
-#include <log/log.h>
-
-using aidl::android::hardware::power::stats::AocStateResidencyDataProvider;
-using aidl::android::hardware::power::stats::DisplayStateResidencyDataProvider;
-using aidl::android::hardware::power::stats::DvfsStateResidencyDataProvider;
-using aidl::android::hardware::power::stats::EnergyConsumerType;
-using aidl::android::hardware::power::stats::GenericStateResidencyDataProvider;
-using aidl::android::hardware::power::stats::IioEnergyMeterDataProvider;
-using aidl::android::hardware::power::stats::PixelStateResidencyDataProvider;
-using aidl::android::hardware::power::stats::PowerStats;
-using aidl::android::hardware::power::stats::PowerStatsEnergyConsumer;
-
-constexpr char kBootHwSoCRev[] = "ro.boot.hw.soc.rev";
-
-void addAoC(std::shared_ptr<PowerStats> p) {
- std::string prefix = "/sys/devices/platform/19000000.aoc/control/";
-
- // Add AoC cores (a32, ff1, hf0, and hf1)
- std::vector<std::pair<std::string, std::string>> coreIds = {
- {"AoC-A32", prefix + "a32_"},
- {"AoC-FF1", prefix + "ff1_"},
- {"AoC-HF1", prefix + "hf1_"},
- {"AoC-HF0", prefix + "hf0_"},
- };
- std::vector<std::pair<std::string, std::string>> coreStates = {
- {"DWN", "off"}, {"RET", "retention"}, {"WFI", "wfi"}};
- p->addStateResidencyDataProvider(std::make_shared<AocStateResidencyDataProvider>(coreIds,
- coreStates));
-
- // Add AoC voltage stats
- std::vector<std::pair<std::string, std::string>> voltageIds = {
- {"AoC-Voltage", prefix + "voltage_"},
- };
- std::vector<std::pair<std::string, std::string>> voltageStates = {{"NOM", "nominal"},
- {"SUD", "super_underdrive"},
- {"UUD", "ultra_underdrive"},
- {"UD", "underdrive"}};
- p->addStateResidencyDataProvider(
- std::make_shared<AocStateResidencyDataProvider>(voltageIds, voltageStates));
-
- // Add AoC monitor mode
- std::vector<std::pair<std::string, std::string>> monitorIds = {
- {"AoC", prefix + "monitor_"},
- };
- std::vector<std::pair<std::string, std::string>> monitorStates = {
- {"MON", "mode"},
- };
- p->addStateResidencyDataProvider(
- std::make_shared<AocStateResidencyDataProvider>(monitorIds, monitorStates));
-}
-
-void addDvfsStats(std::shared_ptr<PowerStats> p) {
- // A constant to represent the number of nanoseconds in one millisecond
- const int NS_TO_MS = 1000000;
-
- std::vector<DvfsStateResidencyDataProvider::Config> cfgs;
-
- cfgs.push_back({"MIF", {
- std::make_pair("3172KHz", "3172000"),
- std::make_pair("2730KHz", "2730000"),
- std::make_pair("2535KHz", "2535000"),
- std::make_pair("2288KHz", "2288000"),
- std::make_pair("2028KHz", "2028000"),
- std::make_pair("1716KHz", "1716000"),
- std::make_pair("1539KHz", "1539000"),
- std::make_pair("1352KHz", "1352000"),
- std::make_pair("1014KHz", "1014000"),
- std::make_pair("845KHz", "845000"),
- std::make_pair("676KHz", "676000"),
- std::make_pair("546KHz", "546000"),
- std::make_pair("421KHz", "421000"),
- std::make_pair("0KHz", "0"),
- }});
-
- cfgs.push_back({"CL0", {
- std::make_pair("2024KHz", "2024000"),
- std::make_pair("1950KHz", "1950000"),
- std::make_pair("1868KHz", "1868000"),
- std::make_pair("1803KHz", "1803000"),
- std::make_pair("1745KHz", "1745000"),
- std::make_pair("1704KHz", "1704000"),
- std::make_pair("1598KHz", "1598000"),
- std::make_pair("1459KHz", "1459000"),
- std::make_pair("1401KHz", "1401000"),
- std::make_pair("1328KHz", "1328000"),
- std::make_pair("1197KHz", "1197000"),
- std::make_pair("1098KHz", "1098000"),
- std::make_pair("930KHz", "930000"),
- std::make_pair("889KHz", "889000"),
- std::make_pair("738KHz", "738000"),
- std::make_pair("574KHz", "574000"),
- std::make_pair("300KHz", "300000"),
- std::make_pair("0KHz", "0"),
- }});
-
- cfgs.push_back({"CL1", {
- std::make_pair("2253KHz", "2253000"),
- std::make_pair("2130KHz", "2130000"),
- std::make_pair("1999KHz", "1999000"),
- std::make_pair("1836KHz", "1836000"),
- std::make_pair("1663KHz", "1663000"),
- std::make_pair("1491KHz", "1491000"),
- std::make_pair("1328KHz", "1328000"),
- std::make_pair("1197KHz", "1197000"),
- std::make_pair("1024KHz", "1024000"),
- std::make_pair("910KHz", "910000"),
- std::make_pair("799KHz", "799000"),
- std::make_pair("696KHz", "696000"),
- std::make_pair("533KHz", "533000"),
- std::make_pair("400KHz", "400000"),
- std::make_pair("0KHz", "0"),
- }});
-
- cfgs.push_back({"CL2", {
- std::make_pair("2630KHz", "2630000"),
- std::make_pair("2507KHz", "2507000"),
- std::make_pair("2401KHz", "2401000"),
- std::make_pair("2302KHz", "2302000"),
- std::make_pair("2252KHz", "2252000"),
- std::make_pair("2188KHz", "2188000"),
- std::make_pair("2048KHz", "2048000"),
- std::make_pair("1901KHz", "1901000"),
- std::make_pair("1826KHz", "1826000"),
- std::make_pair("1745KHz", "1745000"),
- std::make_pair("1582KHz", "1582000"),
- std::make_pair("1426KHz", "1426000"),
- std::make_pair("1277KHz", "1277000"),
- std::make_pair("1237KHz", "1237000"),
- std::make_pair("1106KHz", "1106000"),
- std::make_pair("984KHz", "984000"),
- std::make_pair("851KHz", "851000"),
- std::make_pair("848KHz", "848000"),
- std::make_pair("500KHz", "500000"),
- std::make_pair("0KHz", "0"),
- }});
-
- cfgs.push_back({"TPU", {
- std::make_pair("1066MHz", "1066000000"),
- }});
-
- p->addStateResidencyDataProvider(std::make_shared<DvfsStateResidencyDataProvider>(
- "/sys/devices/platform/1742048c.acpm_stats/fvp_stats", NS_TO_MS, cfgs));
-}
-
-void addSoC(std::shared_ptr<PowerStats> p) {
- // A constant to represent the number of nanoseconds in one millisecond.
- const int NS_TO_MS = 1000000;
-
- // ACPM stats are reported in nanoseconds. The transform function
- // converts nanoseconds to milliseconds.
- std::function<uint64_t(uint64_t)> acpmNsToMs = [](uint64_t a) { return a / NS_TO_MS; };
- const GenericStateResidencyDataProvider::StateResidencyConfig lpmStateConfig = {
- .entryCountSupported = true,
- .entryCountPrefix = "success_count:",
- .totalTimeSupported = true,
- .totalTimePrefix = "total_time_ns:",
- .totalTimeTransform = acpmNsToMs,
- .lastEntrySupported = true,
- .lastEntryPrefix = "last_entry_time_ns:",
- .lastEntryTransform = acpmNsToMs,
- };
- const GenericStateResidencyDataProvider::StateResidencyConfig downStateConfig = {
- .entryCountSupported = true,
- .entryCountPrefix = "down_count:",
- .totalTimeSupported = true,
- .totalTimePrefix = "total_down_time_ns:",
- .totalTimeTransform = acpmNsToMs,
- .lastEntrySupported = true,
- .lastEntryPrefix = "last_down_time_ns:",
- .lastEntryTransform = acpmNsToMs,
- };
- const GenericStateResidencyDataProvider::StateResidencyConfig reqStateConfig = {
- .entryCountSupported = true,
- .entryCountPrefix = "req_up_count:",
- .totalTimeSupported = true,
- .totalTimePrefix = "total_req_up_time_ns:",
- .totalTimeTransform = acpmNsToMs,
- .lastEntrySupported = true,
- .lastEntryPrefix = "last_req_up_time_ns:",
- .lastEntryTransform = acpmNsToMs,
-
- };
- const std::vector<std::pair<std::string, std::string>> powerStateHeaders = {
- std::make_pair("SICD", "SICD"),
- std::make_pair("SLEEP", "SLEEP"),
- std::make_pair("SLEEP_SLCMON", "SLEEP_SLCMON"),
- std::make_pair("STOP", "STOP"),
- };
- const std::vector<std::pair<std::string, std::string>> mifReqStateHeaders = {
- std::make_pair("AOC", "AOC"),
- std::make_pair("GSA", "GSA"),
- };
- const std::vector<std::pair<std::string, std::string>> slcReqStateHeaders = {
- std::make_pair("AOC", "AOC"),
- };
-
- std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> cfgs;
- cfgs.emplace_back(generateGenericStateResidencyConfigs(lpmStateConfig, powerStateHeaders),
- "LPM", "LPM:");
- cfgs.emplace_back(generateGenericStateResidencyConfigs(downStateConfig, powerStateHeaders),
- "MIF", "MIF:");
- cfgs.emplace_back(generateGenericStateResidencyConfigs(reqStateConfig, mifReqStateHeaders),
- "MIF-REQ", "MIF_REQ:");
- cfgs.emplace_back(generateGenericStateResidencyConfigs(downStateConfig, powerStateHeaders),
- "SLC", "SLC:");
- cfgs.emplace_back(generateGenericStateResidencyConfigs(reqStateConfig, slcReqStateHeaders),
- "SLC-REQ", "SLC_REQ:");
-
- auto socSdp = std::make_shared<GenericStateResidencyDataProvider>(
- "/sys/devices/platform/1742048c.acpm_stats/soc_stats", cfgs);
-
- p->addStateResidencyDataProvider(socSdp);
-}
-
-void setEnergyMeter(std::shared_ptr<PowerStats> p) {
- std::vector<const std::string> deviceNames { "s2mpg10-odpm", "s2mpg11-odpm" };
- p->setEnergyMeterDataProvider(std::make_unique<IioEnergyMeterDataProvider>(deviceNames, true));
-}
-
-void addDisplay(std::shared_ptr<PowerStats> p) {
- // Add display residency stats
-
- /*
- * TODO(b/167216667): Add complete set of display states here. Must account
- * for ALL devices built using this source
- */
- std::vector<std::string> states = {
- "Off",
- "LP: 1440x3040@30",
- "On: 1440x3040@60",
- "On: 1440x3040@90",
- "HBM: 1440x3040@60",
- "HBM: 1440x3040@90"};
-
- auto displaySdp =
- std::make_shared<DisplayStateResidencyDataProvider>("Display",
- "/sys/class/backlight/panel0-backlight/state",
- states);
- p->addStateResidencyDataProvider(displaySdp);
-
- // Add display energy consumer
- /*
- * TODO(b/167216667): Add correct display power model here. Must read from display rail
- * and include proper coefficients for display states. Must account for ALL devices built
- * using this source.
- */
- auto displayConsumer = PowerStatsEnergyConsumer::createMeterAndEntityConsumer(p,
- EnergyConsumerType::DISPLAY, "display", {"PPVAR_VSYS_PWR_DISP"}, "Display",
- {{"LP: 1440x3040@30", 1},
- {"On: 1440x3040@60", 2},
- {"On: 1440x3040@90", 3}});
-
- p->addEnergyConsumer(displayConsumer);
-}
-
-void addCPUclusters(std::shared_ptr<PowerStats> p) {
- p->addEnergyConsumer(PowerStatsEnergyConsumer::createMeterConsumer(p,
- EnergyConsumerType::CPU_CLUSTER, "CPUCL0", {"S4M_VDD_CPUCL0"}));
- p->addEnergyConsumer(PowerStatsEnergyConsumer::createMeterConsumer(p,
- EnergyConsumerType::CPU_CLUSTER, "CPUCL1", {"S3M_VDD_CPUCL1"}));
- p->addEnergyConsumer(PowerStatsEnergyConsumer::createMeterConsumer(p,
- EnergyConsumerType::CPU_CLUSTER, "CPUCL2", {"S2M_VDD_CPUCL2"}));
-}
-
-void addGPU(std::shared_ptr<PowerStats> p) {
- // Add gpu energy consumer
- std::map<std::string, int32_t> stateCoeffs;
- const int socRev = android::base::GetIntProperty(kBootHwSoCRev, 0);
-
- // B0/B1 chips have different GPU DVFS operating points than A0/A1 SoC
- if (socRev >= 2) {
- stateCoeffs = {
- {"151000", 10},
- {"202000", 20},
- {"251000", 30},
- {"302000", 40},
- {"351000", 50},
- {"400000", 60},
- {"471000", 70},
- {"510000", 80},
- {"572000", 90},
- {"701000", 100},
- {"762000", 110},
- {"848000", 120}};
- } else {
- stateCoeffs = {
- {"151000", 10},
- {"302000", 20},
- {"455000", 30},
- {"572000", 40},
- {"670000", 50}};
- }
-
- auto gpuConsumer = PowerStatsEnergyConsumer::createMeterAndAttrConsumer(p,
- EnergyConsumerType::OTHER, "GPU", {"S2S_VDD_G3D"},
- {{UID_TIME_IN_STATE, "/sys/devices/platform/1c500000.mali/uid_time_in_state"}},
- stateCoeffs);
-
- p->addEnergyConsumer(gpuConsumer);
-}
-
-void addMobileRadio(std::shared_ptr<PowerStats> p)
-{
- // A constant to represent the number of microseconds in one millisecond.
- const int US_TO_MS = 1000;
-
- // modem power_stats are reported in microseconds. The transform function
- // converts microseconds to milliseconds.
- std::function<uint64_t(uint64_t)> modemUsToMs = [](uint64_t a) { return a / US_TO_MS; };
- const GenericStateResidencyDataProvider::StateResidencyConfig powerStateConfig = {
- .entryCountSupported = true,
- .entryCountPrefix = "count:",
- .totalTimeSupported = true,
- .totalTimePrefix = "duration_usec:",
- .totalTimeTransform = modemUsToMs,
- .lastEntrySupported = true,
- .lastEntryPrefix = "last_entry_timestamp_usec:",
- .lastEntryTransform = modemUsToMs,
- };
- const std::vector<std::pair<std::string, std::string>> powerStateHeaders = {
- std::make_pair("SLEEP", "SLEEP:"),
- };
-
- std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> cfgs;
- cfgs.emplace_back(generateGenericStateResidencyConfigs(powerStateConfig, powerStateHeaders),
- "MODEM", "");
-
- p->addStateResidencyDataProvider(std::make_shared<GenericStateResidencyDataProvider>(
- "/sys/devices/platform/cpif/modem/power_stats", cfgs));
-
- p->addEnergyConsumer(PowerStatsEnergyConsumer::createMeterConsumer(p,
- EnergyConsumerType::MOBILE_RADIO, "MODEM", {"VSYS_PWR_MODEM", "VSYS_PWR_RFFE"}));
-}
-
-void addGNSS(std::shared_ptr<PowerStats> p)
-{
- p->addEnergyConsumer(PowerStatsEnergyConsumer::createMeterConsumer(p,
- EnergyConsumerType::GNSS, "GPS", {"L9S_GNSS_CORE"}));
-}
-
-void addNFC(std::shared_ptr<PowerStats> p) {
- const GenericStateResidencyDataProvider::StateResidencyConfig nfcStateConfig = {
- .entryCountSupported = true,
- .entryCountPrefix = "Cumulative count:",
- .totalTimeSupported = true,
- .totalTimePrefix = "Cumulative duration msec:",
- .lastEntrySupported = true,
- .lastEntryPrefix = "Last entry timestamp msec:",
- };
- const std::vector<std::pair<std::string, std::string>> nfcStateHeaders = {
- std::make_pair("IDLE", "Idle mode:"),
- std::make_pair("ACTIVE", "Active mode:"),
- std::make_pair("ACTIVE-RW", "Active Reader/Writer mode:"),
- };
-
- std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> cfgs;
- cfgs.emplace_back(generateGenericStateResidencyConfigs(nfcStateConfig, nfcStateHeaders),
- "NFC", "NFC subsystem");
-
- auto nfcSdp = std::make_shared<GenericStateResidencyDataProvider>(
- "/sys/devices/platform/10960000.hsi2c/i2c-3/3-0008/power_stats", cfgs);
-
- p->addStateResidencyDataProvider(nfcSdp);
-}
-
-void addPCIe(std::shared_ptr<PowerStats> p) {
- // Add PCIe power entities for Modem and WiFi
- const GenericStateResidencyDataProvider::StateResidencyConfig pcieStateConfig = {
- .entryCountSupported = true,
- .entryCountPrefix = "Cumulative count:",
- .totalTimeSupported = true,
- .totalTimePrefix = "Cumulative duration msec:",
- .lastEntrySupported = true,
- .lastEntryPrefix = "Last entry timestamp msec:",
- };
- const std::vector<std::pair<std::string, std::string>> pcieStateHeaders = {
- std::make_pair("UP", "Link up:"),
- std::make_pair("DOWN", "Link down:"),
- };
-
- // Add PCIe - Modem
- const std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> pcieModemCfgs = {
- {generateGenericStateResidencyConfigs(pcieStateConfig, pcieStateHeaders), "PCIe-Modem",
- "Version: 1"}
- };
- auto pcieModemSdp = std::make_shared<GenericStateResidencyDataProvider>(
- "/sys/devices/platform/11920000.pcie/power_stats", pcieModemCfgs);
- p->addStateResidencyDataProvider(pcieModemSdp);
-
- // Add PCIe - WiFi
- const std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> pcieWifiCfgs = {
- {generateGenericStateResidencyConfigs(pcieStateConfig, pcieStateHeaders),
- "PCIe-WiFi", "Version: 1"}
- };
- auto pcieWifiSdp = std::make_shared<GenericStateResidencyDataProvider>(
- "/sys/devices/platform/14520000.pcie/power_stats", pcieWifiCfgs);
- p->addStateResidencyDataProvider(pcieWifiSdp);
-}
-
-void addWifi(std::shared_ptr<PowerStats> p) {
- // The transform function converts microseconds to milliseconds.
- std::function<uint64_t(uint64_t)> usecToMs = [](uint64_t a) { return a / 1000; };
- const GenericStateResidencyDataProvider::StateResidencyConfig stateConfig = {
- .entryCountSupported = true,
- .entryCountPrefix = "count:",
- .totalTimeSupported = true,
- .totalTimePrefix = "duration_usec:",
- .totalTimeTransform = usecToMs,
- .lastEntrySupported = true,
- .lastEntryPrefix = "last_entry_timestamp_usec:",
- .lastEntryTransform = usecToMs,
- };
- const GenericStateResidencyDataProvider::StateResidencyConfig pcieStateConfig = {
- .entryCountSupported = true,
- .entryCountPrefix = "count:",
- .totalTimeSupported = true,
- .totalTimePrefix = "duration_usec:",
- .totalTimeTransform = usecToMs,
- .lastEntrySupported = false,
- };
-
- const std::vector<std::pair<std::string, std::string>> stateHeaders = {
- std::make_pair("AWAKE", "AWAKE:"),
- std::make_pair("ASLEEP", "ASLEEP:"),
-
- };
- const std::vector<std::pair<std::string, std::string>> pcieStateHeaders = {
- std::make_pair("L0", "L0:"),
- std::make_pair("L1", "L1:"),
- std::make_pair("L1_1", "L1_1:"),
- std::make_pair("L1_2", "L1_2:"),
- std::make_pair("L2", "L2:"),
- };
-
- const std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> cfgs = {
- {generateGenericStateResidencyConfigs(stateConfig, stateHeaders), "WIFI", "WIFI"},
- {generateGenericStateResidencyConfigs(pcieStateConfig, pcieStateHeaders), "WIFI-PCIE",
- "WIFI-PCIE"}
- };
-
- auto wifiSdp = std::make_shared<GenericStateResidencyDataProvider>("/sys/wifi/power_stats",
- cfgs);
- p->addStateResidencyDataProvider(wifiSdp);
-}
-
-/**
- * Unlike other data providers, which source power entity state residency data from the kernel,
- * this data provider acts as a general-purpose channel for state residency data providers
- * that live in user space. Entities are defined here and user space clients of this provider's
- * vendor service register callbacks to provide state residency data for their given pwoer entity.
- */
-void addPixelStateResidencyDataProvider(std::shared_ptr<PowerStats> p) {
- std::shared_ptr<PixelStateResidencyDataProvider> pixelSdp =
- ndk::SharedRefBase::make<PixelStateResidencyDataProvider>();
-
- pixelSdp->addEntity("Bluetooth", {{0, "Idle"}, {1, "Active"}, {2, "Tx"}, {3, "Rx"}});
-
- pixelSdp->start();
- p->addStateResidencyDataProvider(pixelSdp);
-}
-
-int main() {
- LOG(INFO) << "Pixel PowerStats HAL AIDL Service is starting.";
-
- // single thread
- ABinderProcess_setThreadPoolMaxThreadCount(0);
-
- std::shared_ptr<PowerStats> p = ndk::SharedRefBase::make<PowerStats>();
-
- setEnergyMeter(p);
-
- addPixelStateResidencyDataProvider(p);
- addAoC(p);
- addDisplay(p);
- addDvfsStats(p);
- addSoC(p);
- addCPUclusters(p);
- addGPU(p);
- addMobileRadio(p);
- addGNSS(p);
- addNFC(p);
- addPCIe(p);
- addWifi(p);
-
- const std::string instance = std::string() + PowerStats::descriptor + "/default";
- binder_status_t status = AServiceManager_addService(p->asBinder().get(), instance.c_str());
- LOG_ALWAYS_FATAL_IF(status != STATUS_OK);
-
- ABinderProcess_joinThreadPool();
- return EXIT_FAILURE; // should not reach
-}