1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
/*
* 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 "AocStateResidencyDataProvider.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
|