1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <PowerStats.h> 20 21 #include <android-base/chrono_utils.h> 22 23 #include <chrono> 24 #include <random> 25 26 namespace aidl { 27 namespace android { 28 namespace hardware { 29 namespace power { 30 namespace stats { 31 32 class FakeEnergyMeter : public PowerStats::IEnergyMeter { 33 public: FakeEnergyMeter(std::vector<std::pair<std::string,std::string>> channelNames)34 FakeEnergyMeter(std::vector<std::pair<std::string, std::string>> channelNames) { 35 int32_t channelId = 0; 36 for (const auto& [name, subsystem] : channelNames) { 37 Channel c; 38 c.id = channelId++; 39 c.name = name; 40 c.subsystem = subsystem; 41 42 EnergyMeasurement m; 43 m.id = c.id; 44 m.timestampMs = 0; 45 m.durationMs = 0; 46 m.energyUWs = 0; 47 48 mChannels.push_back(c); 49 mEnergyMeasurements.push_back(m); 50 } 51 } 52 ~FakeEnergyMeter() = default; readEnergyMeter(const std::vector<int32_t> & in_channelIds,std::vector<EnergyMeasurement> * _aidl_return)53 ndk::ScopedAStatus readEnergyMeter(const std::vector<int32_t>& in_channelIds, 54 std::vector<EnergyMeasurement>* _aidl_return) override { 55 for (auto& measurement : mEnergyMeasurements) { 56 mFakeEnergyMeasurement.update(&measurement); 57 } 58 59 if (in_channelIds.empty()) { 60 *_aidl_return = mEnergyMeasurements; 61 } else { 62 for (int32_t id : in_channelIds) { 63 // check for invalid ids 64 if (id < 0 || id >= mEnergyMeasurements.size()) { 65 return ndk::ScopedAStatus(AStatus_fromExceptionCode(EX_ILLEGAL_ARGUMENT)); 66 } 67 68 _aidl_return->push_back(mEnergyMeasurements[id]); 69 } 70 } 71 72 return ndk::ScopedAStatus::ok(); 73 } 74 getEnergyMeterInfo(std::vector<Channel> * _aidl_return)75 ndk::ScopedAStatus getEnergyMeterInfo(std::vector<Channel>* _aidl_return) override { 76 *_aidl_return = mChannels; 77 return ndk::ScopedAStatus::ok(); 78 } 79 80 private: 81 class FakeEnergyMeasurement { 82 public: FakeEnergyMeasurement()83 FakeEnergyMeasurement() : mDistribution(1, 100) {} update(EnergyMeasurement * measurement)84 void update(EnergyMeasurement* measurement) { 85 // generates number in the range 1..100 86 auto randNum = std::bind(mDistribution, mGenerator); 87 88 // Get current time since boot in milliseconds 89 uint64_t now = std::chrono::time_point_cast<std::chrono::milliseconds>( 90 ::android::base::boot_clock::now()) 91 .time_since_epoch() 92 .count(); 93 measurement->timestampMs = now; 94 measurement->durationMs = now; 95 measurement->energyUWs += randNum() * 100; 96 } 97 98 private: 99 std::default_random_engine mGenerator; 100 std::uniform_int_distribution<int> mDistribution; 101 }; 102 103 std::vector<Channel> mChannels; 104 FakeEnergyMeasurement mFakeEnergyMeasurement; 105 std::vector<EnergyMeasurement> mEnergyMeasurements; 106 }; 107 108 } // namespace stats 109 } // namespace power 110 } // namespace hardware 111 } // namespace android 112 } // namespace aidl