Loading power/stats/aidl/default/FakeEnergyConsumer.h 0 → 100644 +83 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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 <PowerStats.h> #include <android-base/chrono_utils.h> #include <chrono> #include <random> namespace aidl { namespace android { namespace hardware { namespace power { namespace stats { class FakeEnergyConsumer : public PowerStats::IEnergyConsumer { public: FakeEnergyConsumer(EnergyConsumerType type, std::string name) : mType(type), mName(name) { mResult.timestampMs = 0; mResult.energyUWs = 0; mResult.attribution = {}; } ~FakeEnergyConsumer() = default; std::string getName() override { return mName; } EnergyConsumerType getType() override { return mType; } std::optional<EnergyConsumerResult> getEnergyConsumed() override { mFakeEnergyConsumerResult.update(&mResult); return mResult; } private: class FakeEnergyConsumerResult { public: FakeEnergyConsumerResult() : mDistribution(1, 100) {} void update(EnergyConsumerResult* result) { // generates number in the range 1..100 auto randNum = std::bind(mDistribution, mGenerator); // Get current time since boot in milliseconds uint64_t now = std::chrono::time_point_cast<std::chrono::milliseconds>( ::android::base::boot_clock::now()) .time_since_epoch() .count(); result->timestampMs = now; result->energyUWs += randNum() * 100; } private: std::default_random_engine mGenerator; std::uniform_int_distribution<int> mDistribution; }; EnergyConsumerType mType; std::string mName; FakeEnergyConsumerResult mFakeEnergyConsumerResult; EnergyConsumerResult mResult; }; } // namespace stats } // namespace power } // namespace hardware } // namespace android } // namespace aidl No newline at end of file power/stats/aidl/default/FakeEnergyMeter.h 0 → 100644 +109 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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 <PowerStats.h> #include <android-base/chrono_utils.h> #include <chrono> #include <random> namespace aidl { namespace android { namespace hardware { namespace power { namespace stats { class FakeEnergyMeter : public PowerStats::IEnergyMeter { public: FakeEnergyMeter(std::vector<std::pair<std::string, std::string>> channelNames) { int32_t channelId = 0; for (const auto& [name, subsystem] : channelNames) { Channel c; c.id = channelId++; c.name = name; c.subsystem = subsystem; EnergyMeasurement m; m.id = c.id; m.timestampMs = 0; m.durationMs = 0; m.energyUWs = 0; mChannels.push_back(c); mEnergyMeasurements.push_back(m); } } ~FakeEnergyMeter() = default; ndk::ScopedAStatus readEnergyMeter(const std::vector<int32_t>& in_channelIds, std::vector<EnergyMeasurement>* _aidl_return) override { for (auto& measurement : mEnergyMeasurements) { mFakeEnergyMeasurement.update(&measurement); } if (in_channelIds.empty()) { *_aidl_return = mEnergyMeasurements; } else { for (int32_t id : in_channelIds) { if (id >= 0 && id < mEnergyMeasurements.size()) { _aidl_return->push_back(mEnergyMeasurements[id]); } } } return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus getEnergyMeterInfo(std::vector<Channel>* _aidl_return) override { *_aidl_return = mChannels; return ndk::ScopedAStatus::ok(); } private: class FakeEnergyMeasurement { public: FakeEnergyMeasurement() : mDistribution(1, 100) {} void update(EnergyMeasurement* measurement) { // generates number in the range 1..100 auto randNum = std::bind(mDistribution, mGenerator); // Get current time since boot in milliseconds uint64_t now = std::chrono::time_point_cast<std::chrono::milliseconds>( ::android::base::boot_clock::now()) .time_since_epoch() .count(); measurement->timestampMs = now; measurement->durationMs = now; measurement->energyUWs += randNum() * 100; } private: std::default_random_engine mGenerator; std::uniform_int_distribution<int> mDistribution; }; std::vector<Channel> mChannels; FakeEnergyMeasurement mFakeEnergyMeasurement; std::vector<EnergyMeasurement> mEnergyMeasurements; }; } // namespace stats } // namespace power } // namespace hardware } // namespace android } // namespace aidl No newline at end of file power/stats/aidl/default/FakeStateResidencyDataProvider.h 0 → 100644 +87 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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 <PowerStats.h> #include <random> namespace aidl { namespace android { namespace hardware { namespace power { namespace stats { class FakeStateResidencyDataProvider : public PowerStats::IStateResidencyDataProvider { public: FakeStateResidencyDataProvider(const std::string& name, std::vector<State> states) : mName(name), mStates(states) { for (const auto& state : mStates) { StateResidency r; r.id = state.id; r.totalTimeInStateMs = 0; r.totalStateEntryCount = 0; r.lastEntryTimestampMs = 0; mResidencies.push_back(r); } } ~FakeStateResidencyDataProvider() = default; // Methods from PowerStats::IStateResidencyDataProvider bool getStateResidencies( std::unordered_map<std::string, std::vector<StateResidency>>* residencies) override { for (auto& residency : mResidencies) { mFakeStateResidency.update(&residency); } residencies->emplace(mName, mResidencies); return true; } std::unordered_map<std::string, std::vector<State>> getInfo() override { return {{mName, mStates}}; } private: class FakeStateResidency { public: FakeStateResidency() : mDistribution(1, 100) {} void update(StateResidency* residency) { // generates number in the range 1..100 auto randNum = std::bind(mDistribution, mGenerator); residency->totalTimeInStateMs += randNum() * 100; residency->totalStateEntryCount += randNum(); residency->lastEntryTimestampMs += randNum() * 100; } private: std::default_random_engine mGenerator; std::uniform_int_distribution<int> mDistribution; }; const std::string mName; const std::vector<State> mStates; FakeStateResidency mFakeStateResidency; std::vector<StateResidency> mResidencies; }; } // namespace stats } // namespace power } // namespace hardware } // namespace android } // namespace aidl No newline at end of file power/stats/aidl/default/PowerStats.cpp +124 −13 Original line number Diff line number Diff line Loading @@ -18,48 +18,159 @@ #include <android-base/logging.h> #include <numeric> namespace aidl { namespace android { namespace hardware { namespace power { namespace stats { void PowerStats::addStateResidencyDataProvider(std::unique_ptr<IStateResidencyDataProvider> p) { if (!p) { return; } int32_t id = mPowerEntityInfos.size(); for (const auto& [entityName, states] : p->getInfo()) { PowerEntity i = { .id = id++, .name = entityName, .states = states, }; mPowerEntityInfos.emplace_back(i); mStateResidencyDataProviders.emplace_back(std::move(p)); } } void PowerStats::addEnergyConsumer(std::unique_ptr<IEnergyConsumer> p) { if (!p) { return; } EnergyConsumerType type = p->getType(); std::string name = p->getName(); int32_t count = count_if(mEnergyConsumerInfos.begin(), mEnergyConsumerInfos.end(), [&type](const EnergyConsumer& c) { return type == c.type; }); int32_t id = mEnergyConsumers.size(); mEnergyConsumerInfos.emplace_back( EnergyConsumer{.id = id, .ordinal = count, .type = type, .name = name}); mEnergyConsumers.emplace_back(std::move(p)); } void PowerStats::setEnergyMeter(std::unique_ptr<IEnergyMeter> p) { mEnergyMeter = std::move(p); } ndk::ScopedAStatus PowerStats::getPowerEntityInfo(std::vector<PowerEntity>* _aidl_return) { (void)_aidl_return; *_aidl_return = mPowerEntityInfos; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus PowerStats::getStateResidency(const std::vector<int32_t>& in_powerEntityIds, std::vector<StateResidencyResult>* _aidl_return) { (void)in_powerEntityIds; (void)_aidl_return; if (mPowerEntityInfos.empty()) { return ndk::ScopedAStatus::ok(); } // If in_powerEntityIds is empty then return data for all supported entities if (in_powerEntityIds.empty()) { std::vector<int32_t> v(mPowerEntityInfos.size()); std::iota(std::begin(v), std::end(v), 0); return getStateResidency(v, _aidl_return); } binder_status_t err = STATUS_OK; std::unordered_map<std::string, std::vector<StateResidency>> stateResidencies; for (const int32_t id : in_powerEntityIds) { // skip any invalid ids if (id < 0 || id >= mPowerEntityInfos.size()) { continue; } // Check to see if we already have data for the given id std::string powerEntityName = mPowerEntityInfos[id].name; if (stateResidencies.find(powerEntityName) == stateResidencies.end()) { mStateResidencyDataProviders[id]->getStateResidencies(&stateResidencies); } // Append results if we have them auto stateResidency = stateResidencies.find(powerEntityName); if (stateResidency != stateResidencies.end()) { StateResidencyResult res = { .id = id, .stateResidencyData = stateResidency->second, }; _aidl_return->emplace_back(res); } else { // Failed to retrieve results for the given id. err = STATUS_FAILED_TRANSACTION; } } return ndk::ScopedAStatus::fromStatus(err); } ndk::ScopedAStatus PowerStats::getEnergyConsumerInfo(std::vector<EnergyConsumer>* _aidl_return) { (void)_aidl_return; *_aidl_return = mEnergyConsumerInfos; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus PowerStats::getEnergyConsumed(const std::vector<int32_t>& in_energyConsumerIds, std::vector<EnergyConsumerResult>* _aidl_return) { (void)in_energyConsumerIds; (void)_aidl_return; if (mEnergyConsumers.empty()) { return ndk::ScopedAStatus::ok(); } // If in_powerEntityIds is empty then return data for all supported energy consumers if (in_energyConsumerIds.empty()) { std::vector<int32_t> v(mEnergyConsumerInfos.size()); std::iota(std::begin(v), std::end(v), 0); return getEnergyConsumed(v, _aidl_return); } binder_status_t err = STATUS_OK; for (const auto id : in_energyConsumerIds) { // skip any invalid ids if (id < 0 || id >= mEnergyConsumers.size()) { continue; } auto optionalResult = mEnergyConsumers[id]->getEnergyConsumed(); if (optionalResult) { EnergyConsumerResult result = optionalResult.value(); result.id = id; _aidl_return->emplace_back(result); } else { // Failed to retrieve results for the given id. err = STATUS_FAILED_TRANSACTION; } } return ndk::ScopedAStatus::fromStatus(err); } ndk::ScopedAStatus PowerStats::getEnergyMeterInfo(std::vector<Channel>* _aidl_return) { (void)_aidl_return; if (!mEnergyMeter) { return ndk::ScopedAStatus::ok(); } return mEnergyMeter->getEnergyMeterInfo(_aidl_return); } ndk::ScopedAStatus PowerStats::readEnergyMeter(const std::vector<int32_t>& in_channelIds, std::vector<EnergyMeasurement>* _aidl_return) { (void)in_channelIds; (void)_aidl_return; if (!mEnergyMeter) { return ndk::ScopedAStatus::ok(); } return mEnergyMeter->readEnergyMeter(in_channelIds, _aidl_return); } } // namespace stats } // namespace power } // namespace hardware Loading power/stats/aidl/default/PowerStats.h +41 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ #include <aidl/android/hardware/power/stats/BnPowerStats.h> #include <unordered_map> namespace aidl { namespace android { namespace hardware { Loading @@ -26,7 +28,37 @@ namespace stats { class PowerStats : public BnPowerStats { public: class IStateResidencyDataProvider { public: virtual ~IStateResidencyDataProvider() = default; virtual bool getStateResidencies( std::unordered_map<std::string, std::vector<StateResidency>>* residencies) = 0; virtual std::unordered_map<std::string, std::vector<State>> getInfo() = 0; }; class IEnergyConsumer { public: virtual ~IEnergyConsumer() = default; virtual std::string getName() = 0; virtual EnergyConsumerType getType() = 0; virtual std::optional<EnergyConsumerResult> getEnergyConsumed() = 0; }; class IEnergyMeter { public: virtual ~IEnergyMeter() = default; virtual ndk::ScopedAStatus readEnergyMeter( const std::vector<int32_t>& in_channelIds, std::vector<EnergyMeasurement>* _aidl_return) = 0; virtual ndk::ScopedAStatus getEnergyMeterInfo(std::vector<Channel>* _aidl_return) = 0; }; PowerStats() = default; void addStateResidencyDataProvider(std::unique_ptr<IStateResidencyDataProvider> p); void addEnergyConsumer(std::unique_ptr<IEnergyConsumer> p); void setEnergyMeter(std::unique_ptr<IEnergyMeter> p); // Methods from aidl::android::hardware::power::stats::IPowerStats ndk::ScopedAStatus getPowerEntityInfo(std::vector<PowerEntity>* _aidl_return) override; ndk::ScopedAStatus getStateResidency(const std::vector<int32_t>& in_powerEntityIds, Loading @@ -37,6 +69,15 @@ class PowerStats : public BnPowerStats { ndk::ScopedAStatus getEnergyMeterInfo(std::vector<Channel>* _aidl_return) override; ndk::ScopedAStatus readEnergyMeter(const std::vector<int32_t>& in_channelIds, std::vector<EnergyMeasurement>* _aidl_return) override; private: std::vector<std::unique_ptr<IStateResidencyDataProvider>> mStateResidencyDataProviders; std::vector<PowerEntity> mPowerEntityInfos; std::vector<std::unique_ptr<IEnergyConsumer>> mEnergyConsumers; std::vector<EnergyConsumer> mEnergyConsumerInfos; std::unique_ptr<IEnergyMeter> mEnergyMeter; }; } // namespace stats Loading Loading
power/stats/aidl/default/FakeEnergyConsumer.h 0 → 100644 +83 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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 <PowerStats.h> #include <android-base/chrono_utils.h> #include <chrono> #include <random> namespace aidl { namespace android { namespace hardware { namespace power { namespace stats { class FakeEnergyConsumer : public PowerStats::IEnergyConsumer { public: FakeEnergyConsumer(EnergyConsumerType type, std::string name) : mType(type), mName(name) { mResult.timestampMs = 0; mResult.energyUWs = 0; mResult.attribution = {}; } ~FakeEnergyConsumer() = default; std::string getName() override { return mName; } EnergyConsumerType getType() override { return mType; } std::optional<EnergyConsumerResult> getEnergyConsumed() override { mFakeEnergyConsumerResult.update(&mResult); return mResult; } private: class FakeEnergyConsumerResult { public: FakeEnergyConsumerResult() : mDistribution(1, 100) {} void update(EnergyConsumerResult* result) { // generates number in the range 1..100 auto randNum = std::bind(mDistribution, mGenerator); // Get current time since boot in milliseconds uint64_t now = std::chrono::time_point_cast<std::chrono::milliseconds>( ::android::base::boot_clock::now()) .time_since_epoch() .count(); result->timestampMs = now; result->energyUWs += randNum() * 100; } private: std::default_random_engine mGenerator; std::uniform_int_distribution<int> mDistribution; }; EnergyConsumerType mType; std::string mName; FakeEnergyConsumerResult mFakeEnergyConsumerResult; EnergyConsumerResult mResult; }; } // namespace stats } // namespace power } // namespace hardware } // namespace android } // namespace aidl No newline at end of file
power/stats/aidl/default/FakeEnergyMeter.h 0 → 100644 +109 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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 <PowerStats.h> #include <android-base/chrono_utils.h> #include <chrono> #include <random> namespace aidl { namespace android { namespace hardware { namespace power { namespace stats { class FakeEnergyMeter : public PowerStats::IEnergyMeter { public: FakeEnergyMeter(std::vector<std::pair<std::string, std::string>> channelNames) { int32_t channelId = 0; for (const auto& [name, subsystem] : channelNames) { Channel c; c.id = channelId++; c.name = name; c.subsystem = subsystem; EnergyMeasurement m; m.id = c.id; m.timestampMs = 0; m.durationMs = 0; m.energyUWs = 0; mChannels.push_back(c); mEnergyMeasurements.push_back(m); } } ~FakeEnergyMeter() = default; ndk::ScopedAStatus readEnergyMeter(const std::vector<int32_t>& in_channelIds, std::vector<EnergyMeasurement>* _aidl_return) override { for (auto& measurement : mEnergyMeasurements) { mFakeEnergyMeasurement.update(&measurement); } if (in_channelIds.empty()) { *_aidl_return = mEnergyMeasurements; } else { for (int32_t id : in_channelIds) { if (id >= 0 && id < mEnergyMeasurements.size()) { _aidl_return->push_back(mEnergyMeasurements[id]); } } } return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus getEnergyMeterInfo(std::vector<Channel>* _aidl_return) override { *_aidl_return = mChannels; return ndk::ScopedAStatus::ok(); } private: class FakeEnergyMeasurement { public: FakeEnergyMeasurement() : mDistribution(1, 100) {} void update(EnergyMeasurement* measurement) { // generates number in the range 1..100 auto randNum = std::bind(mDistribution, mGenerator); // Get current time since boot in milliseconds uint64_t now = std::chrono::time_point_cast<std::chrono::milliseconds>( ::android::base::boot_clock::now()) .time_since_epoch() .count(); measurement->timestampMs = now; measurement->durationMs = now; measurement->energyUWs += randNum() * 100; } private: std::default_random_engine mGenerator; std::uniform_int_distribution<int> mDistribution; }; std::vector<Channel> mChannels; FakeEnergyMeasurement mFakeEnergyMeasurement; std::vector<EnergyMeasurement> mEnergyMeasurements; }; } // namespace stats } // namespace power } // namespace hardware } // namespace android } // namespace aidl No newline at end of file
power/stats/aidl/default/FakeStateResidencyDataProvider.h 0 → 100644 +87 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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 <PowerStats.h> #include <random> namespace aidl { namespace android { namespace hardware { namespace power { namespace stats { class FakeStateResidencyDataProvider : public PowerStats::IStateResidencyDataProvider { public: FakeStateResidencyDataProvider(const std::string& name, std::vector<State> states) : mName(name), mStates(states) { for (const auto& state : mStates) { StateResidency r; r.id = state.id; r.totalTimeInStateMs = 0; r.totalStateEntryCount = 0; r.lastEntryTimestampMs = 0; mResidencies.push_back(r); } } ~FakeStateResidencyDataProvider() = default; // Methods from PowerStats::IStateResidencyDataProvider bool getStateResidencies( std::unordered_map<std::string, std::vector<StateResidency>>* residencies) override { for (auto& residency : mResidencies) { mFakeStateResidency.update(&residency); } residencies->emplace(mName, mResidencies); return true; } std::unordered_map<std::string, std::vector<State>> getInfo() override { return {{mName, mStates}}; } private: class FakeStateResidency { public: FakeStateResidency() : mDistribution(1, 100) {} void update(StateResidency* residency) { // generates number in the range 1..100 auto randNum = std::bind(mDistribution, mGenerator); residency->totalTimeInStateMs += randNum() * 100; residency->totalStateEntryCount += randNum(); residency->lastEntryTimestampMs += randNum() * 100; } private: std::default_random_engine mGenerator; std::uniform_int_distribution<int> mDistribution; }; const std::string mName; const std::vector<State> mStates; FakeStateResidency mFakeStateResidency; std::vector<StateResidency> mResidencies; }; } // namespace stats } // namespace power } // namespace hardware } // namespace android } // namespace aidl No newline at end of file
power/stats/aidl/default/PowerStats.cpp +124 −13 Original line number Diff line number Diff line Loading @@ -18,48 +18,159 @@ #include <android-base/logging.h> #include <numeric> namespace aidl { namespace android { namespace hardware { namespace power { namespace stats { void PowerStats::addStateResidencyDataProvider(std::unique_ptr<IStateResidencyDataProvider> p) { if (!p) { return; } int32_t id = mPowerEntityInfos.size(); for (const auto& [entityName, states] : p->getInfo()) { PowerEntity i = { .id = id++, .name = entityName, .states = states, }; mPowerEntityInfos.emplace_back(i); mStateResidencyDataProviders.emplace_back(std::move(p)); } } void PowerStats::addEnergyConsumer(std::unique_ptr<IEnergyConsumer> p) { if (!p) { return; } EnergyConsumerType type = p->getType(); std::string name = p->getName(); int32_t count = count_if(mEnergyConsumerInfos.begin(), mEnergyConsumerInfos.end(), [&type](const EnergyConsumer& c) { return type == c.type; }); int32_t id = mEnergyConsumers.size(); mEnergyConsumerInfos.emplace_back( EnergyConsumer{.id = id, .ordinal = count, .type = type, .name = name}); mEnergyConsumers.emplace_back(std::move(p)); } void PowerStats::setEnergyMeter(std::unique_ptr<IEnergyMeter> p) { mEnergyMeter = std::move(p); } ndk::ScopedAStatus PowerStats::getPowerEntityInfo(std::vector<PowerEntity>* _aidl_return) { (void)_aidl_return; *_aidl_return = mPowerEntityInfos; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus PowerStats::getStateResidency(const std::vector<int32_t>& in_powerEntityIds, std::vector<StateResidencyResult>* _aidl_return) { (void)in_powerEntityIds; (void)_aidl_return; if (mPowerEntityInfos.empty()) { return ndk::ScopedAStatus::ok(); } // If in_powerEntityIds is empty then return data for all supported entities if (in_powerEntityIds.empty()) { std::vector<int32_t> v(mPowerEntityInfos.size()); std::iota(std::begin(v), std::end(v), 0); return getStateResidency(v, _aidl_return); } binder_status_t err = STATUS_OK; std::unordered_map<std::string, std::vector<StateResidency>> stateResidencies; for (const int32_t id : in_powerEntityIds) { // skip any invalid ids if (id < 0 || id >= mPowerEntityInfos.size()) { continue; } // Check to see if we already have data for the given id std::string powerEntityName = mPowerEntityInfos[id].name; if (stateResidencies.find(powerEntityName) == stateResidencies.end()) { mStateResidencyDataProviders[id]->getStateResidencies(&stateResidencies); } // Append results if we have them auto stateResidency = stateResidencies.find(powerEntityName); if (stateResidency != stateResidencies.end()) { StateResidencyResult res = { .id = id, .stateResidencyData = stateResidency->second, }; _aidl_return->emplace_back(res); } else { // Failed to retrieve results for the given id. err = STATUS_FAILED_TRANSACTION; } } return ndk::ScopedAStatus::fromStatus(err); } ndk::ScopedAStatus PowerStats::getEnergyConsumerInfo(std::vector<EnergyConsumer>* _aidl_return) { (void)_aidl_return; *_aidl_return = mEnergyConsumerInfos; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus PowerStats::getEnergyConsumed(const std::vector<int32_t>& in_energyConsumerIds, std::vector<EnergyConsumerResult>* _aidl_return) { (void)in_energyConsumerIds; (void)_aidl_return; if (mEnergyConsumers.empty()) { return ndk::ScopedAStatus::ok(); } // If in_powerEntityIds is empty then return data for all supported energy consumers if (in_energyConsumerIds.empty()) { std::vector<int32_t> v(mEnergyConsumerInfos.size()); std::iota(std::begin(v), std::end(v), 0); return getEnergyConsumed(v, _aidl_return); } binder_status_t err = STATUS_OK; for (const auto id : in_energyConsumerIds) { // skip any invalid ids if (id < 0 || id >= mEnergyConsumers.size()) { continue; } auto optionalResult = mEnergyConsumers[id]->getEnergyConsumed(); if (optionalResult) { EnergyConsumerResult result = optionalResult.value(); result.id = id; _aidl_return->emplace_back(result); } else { // Failed to retrieve results for the given id. err = STATUS_FAILED_TRANSACTION; } } return ndk::ScopedAStatus::fromStatus(err); } ndk::ScopedAStatus PowerStats::getEnergyMeterInfo(std::vector<Channel>* _aidl_return) { (void)_aidl_return; if (!mEnergyMeter) { return ndk::ScopedAStatus::ok(); } return mEnergyMeter->getEnergyMeterInfo(_aidl_return); } ndk::ScopedAStatus PowerStats::readEnergyMeter(const std::vector<int32_t>& in_channelIds, std::vector<EnergyMeasurement>* _aidl_return) { (void)in_channelIds; (void)_aidl_return; if (!mEnergyMeter) { return ndk::ScopedAStatus::ok(); } return mEnergyMeter->readEnergyMeter(in_channelIds, _aidl_return); } } // namespace stats } // namespace power } // namespace hardware Loading
power/stats/aidl/default/PowerStats.h +41 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ #include <aidl/android/hardware/power/stats/BnPowerStats.h> #include <unordered_map> namespace aidl { namespace android { namespace hardware { Loading @@ -26,7 +28,37 @@ namespace stats { class PowerStats : public BnPowerStats { public: class IStateResidencyDataProvider { public: virtual ~IStateResidencyDataProvider() = default; virtual bool getStateResidencies( std::unordered_map<std::string, std::vector<StateResidency>>* residencies) = 0; virtual std::unordered_map<std::string, std::vector<State>> getInfo() = 0; }; class IEnergyConsumer { public: virtual ~IEnergyConsumer() = default; virtual std::string getName() = 0; virtual EnergyConsumerType getType() = 0; virtual std::optional<EnergyConsumerResult> getEnergyConsumed() = 0; }; class IEnergyMeter { public: virtual ~IEnergyMeter() = default; virtual ndk::ScopedAStatus readEnergyMeter( const std::vector<int32_t>& in_channelIds, std::vector<EnergyMeasurement>* _aidl_return) = 0; virtual ndk::ScopedAStatus getEnergyMeterInfo(std::vector<Channel>* _aidl_return) = 0; }; PowerStats() = default; void addStateResidencyDataProvider(std::unique_ptr<IStateResidencyDataProvider> p); void addEnergyConsumer(std::unique_ptr<IEnergyConsumer> p); void setEnergyMeter(std::unique_ptr<IEnergyMeter> p); // Methods from aidl::android::hardware::power::stats::IPowerStats ndk::ScopedAStatus getPowerEntityInfo(std::vector<PowerEntity>* _aidl_return) override; ndk::ScopedAStatus getStateResidency(const std::vector<int32_t>& in_powerEntityIds, Loading @@ -37,6 +69,15 @@ class PowerStats : public BnPowerStats { ndk::ScopedAStatus getEnergyMeterInfo(std::vector<Channel>* _aidl_return) override; ndk::ScopedAStatus readEnergyMeter(const std::vector<int32_t>& in_channelIds, std::vector<EnergyMeasurement>* _aidl_return) override; private: std::vector<std::unique_ptr<IStateResidencyDataProvider>> mStateResidencyDataProviders; std::vector<PowerEntity> mPowerEntityInfos; std::vector<std::unique_ptr<IEnergyConsumer>> mEnergyConsumers; std::vector<EnergyConsumer> mEnergyConsumerInfos; std::unique_ptr<IEnergyMeter> mEnergyMeter; }; } // namespace stats Loading