1 /*
2  * Copyright (C) 2019 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 #define LOG_TAG "[email protected]"
18 
19 #include <android/log.h>
20 #include <binder/IPCThreadState.h>
21 #include <binder/IServiceManager.h>
22 #include <binder/ProcessState.h>
23 #include <hidl/HidlTransportSupport.h>
24 #include <pixelpowerstats/AidlStateResidencyDataProvider.h>
25 #include <pixelpowerstats/GenericStateResidencyDataProvider.h>
26 #include <pixelpowerstats/PowerStats.h>
27 #include <pixelpowerstats/WlanStateResidencyDataProvider.h>
28 
29 #include "IaxxxStateResidencyDataProvider.h"
30 #include "GpuStateResidencyDataProvider.h"
31 #include "OsloStateResidencyDataProvider.h"
32 #include "RailDataProvider.h"
33 
34 using android::OK;
35 using android::sp;
36 using android::status_t;
37 
38 // libhwbinder:
39 using android::hardware::configureRpcThreadpool;
40 using android::hardware::joinRpcThreadpool;
41 
42 // Generated HIDL files
43 using android::hardware::power::stats::V1_0::IPowerStats;
44 using android::hardware::power::stats::V1_0::PowerEntityType;
45 using android::hardware::power::stats::V1_0::implementation::PowerStats;
46 
47 // Pixel specific
48 using android::hardware::google::pixel::powerstats::AidlStateResidencyDataProvider;
49 using android::hardware::google::pixel::powerstats::IaxxxStateResidencyDataProvider;
50 using android::hardware::google::pixel::powerstats::generateGenericStateResidencyConfigs;
51 using android::hardware::google::pixel::powerstats::GenericStateResidencyDataProvider;
52 using android::hardware::google::pixel::powerstats::GpuStateResidencyDataProvider;
53 using android::hardware::google::pixel::powerstats::OsloStateResidencyDataProvider;
54 using android::hardware::google::pixel::powerstats::PowerEntityConfig;
55 using android::hardware::google::pixel::powerstats::RailDataProvider;
56 using android::hardware::google::pixel::powerstats::StateResidencyConfig;
57 using android::hardware::google::pixel::powerstats::WlanStateResidencyDataProvider;
58 
main(int,char **)59 int main(int /* argc */, char** /* argv */) {
60     ALOGI("power.stats service 1.0 is starting.");
61 
62 
63     PowerStats* service = new PowerStats();
64 
65     // Add rail data provider
66     service->setRailDataProvider(std::make_unique<RailDataProvider>());
67 
68     // Add power entities related to rpmh
69     const uint64_t RPM_CLK = 19200;  // RPM runs at 19.2Mhz. Divide by 19200 for msec
70     std::function<uint64_t(uint64_t)> rpmConvertToMs = [](uint64_t a) { return a / RPM_CLK; };
71     std::vector<StateResidencyConfig> rpmStateResidencyConfigs = {
72         {.name = "Sleep",
73          .entryCountSupported = true,
74          .entryCountPrefix = "Sleep Count:",
75          .totalTimeSupported = true,
76          .totalTimePrefix = "Sleep Accumulated Duration:",
77          .totalTimeTransform = rpmConvertToMs,
78          .lastEntrySupported = true,
79          .lastEntryPrefix = "Sleep Last Entered At:",
80          .lastEntryTransform = rpmConvertToMs}};
81 
82     sp<GenericStateResidencyDataProvider> rpmSdp =
83             new GenericStateResidencyDataProvider("/sys/power/rpmh_stats/master_stats");
84 
85     uint32_t apssId = service->addPowerEntity("APSS", PowerEntityType::SUBSYSTEM);
86     rpmSdp->addEntity(apssId, PowerEntityConfig("APSS", rpmStateResidencyConfigs));
87 
88     uint32_t mpssId = service->addPowerEntity("MPSS", PowerEntityType::SUBSYSTEM);
89     rpmSdp->addEntity(mpssId, PowerEntityConfig("MPSS", rpmStateResidencyConfigs));
90 
91     uint32_t adspId = service->addPowerEntity("ADSP", PowerEntityType::SUBSYSTEM);
92     rpmSdp->addEntity(adspId, PowerEntityConfig("ADSP", rpmStateResidencyConfigs));
93 
94     uint32_t cdspId = service->addPowerEntity("CDSP", PowerEntityType::SUBSYSTEM);
95     rpmSdp->addEntity(cdspId, PowerEntityConfig("CDSP", rpmStateResidencyConfigs));
96 
97     uint32_t slpiId = service->addPowerEntity("SLPI", PowerEntityType::SUBSYSTEM);
98     rpmSdp->addEntity(slpiId, PowerEntityConfig("SLPI", rpmStateResidencyConfigs));
99 
100     uint32_t slpiIslandId = service->addPowerEntity("SLPI_ISLAND", PowerEntityType::SUBSYSTEM);
101     rpmSdp->addEntity(slpiIslandId, PowerEntityConfig("SLPI_ISLAND", {
102         {.name = "uImage",
103          .entryCountSupported = true,
104          .entryCountPrefix = "Sleep Count:",
105          .totalTimeSupported = true,
106          .totalTimePrefix = "Sleep Accumulated Duration:",
107          .totalTimeTransform = rpmConvertToMs,
108          .lastEntrySupported = true,
109          .lastEntryPrefix = "Sleep Last Entered At:",
110          .lastEntryTransform = rpmConvertToMs}}));
111 
112     service->addStateResidencyDataProvider(rpmSdp);
113 
114     // Add SoC power entity
115     StateResidencyConfig socStateConfig = {
116         .entryCountSupported = true,
117         .entryCountPrefix = "count:",
118         .totalTimeSupported = true,
119         .totalTimePrefix = "actual last sleep(msec):",
120         .lastEntrySupported = false
121     };
122     std::vector<std::pair<std::string, std::string>> socStateHeaders = {
123         std::make_pair("AOSD", "RPM Mode:aosd"),
124         std::make_pair("CXSD", "RPM Mode:cxsd"),
125         std::make_pair("DDR", "RPM Mode:ddr"),
126     };
127 
128     sp<GenericStateResidencyDataProvider> socSdp =
129             new GenericStateResidencyDataProvider("/sys/power/system_sleep/stats");
130 
131     uint32_t socId = service->addPowerEntity("SoC", PowerEntityType::POWER_DOMAIN);
132     socSdp->addEntity(socId,
133         PowerEntityConfig(generateGenericStateResidencyConfigs(socStateConfig, socStateHeaders)));
134 
135     service->addStateResidencyDataProvider(socSdp);
136 
137     // Add WLAN power entity
138     uint32_t wlanId = service->addPowerEntity("WLAN", PowerEntityType::SUBSYSTEM);
139     sp<WlanStateResidencyDataProvider> wlanSdp =
140             new WlanStateResidencyDataProvider(wlanId, "/sys/kernel/wlan/power_stats");
141     service->addStateResidencyDataProvider(wlanSdp);
142 
143     // Add Airbrush power entity
144     StateResidencyConfig airStateConfig = {
145         .entryCountSupported = true,
146         .entryCountPrefix = "Cumulative count:",
147         .totalTimeSupported = true,
148         .totalTimePrefix = "Cumulative duration msec:",
149         .lastEntrySupported = true,
150         .lastEntryPrefix = "Last entry timestamp msec:",
151     };
152     std::vector<std::pair<std::string, std::string>> airStateHeaders = {
153         std::make_pair("Active", "ACTIVE"),
154         std::make_pair("Sleep", "SLEEP"),
155         std::make_pair("Deep-Sleep", "DEEP SLEEP"),
156         std::make_pair("Suspend", "SUSPEND"),
157         std::make_pair("Off", "OFF"),
158         std::make_pair("Unknown", "UNKNOWN"),
159     };
160 
161     sp<GenericStateResidencyDataProvider> airSdp =
162             new GenericStateResidencyDataProvider(
163                     "/sys/devices/platform/soc/soc:abc-sm/state_stats");
164 
165     uint32_t airId = service->addPowerEntity("Visual-Core", PowerEntityType::SUBSYSTEM);
166     airSdp->addEntity(airId, PowerEntityConfig("Pixel Visual Core Subsystem Power Stats",
167             generateGenericStateResidencyConfigs(airStateConfig, airStateHeaders)));
168 
169     service->addStateResidencyDataProvider(airSdp);
170 
171     // Add NFC power entity
172     StateResidencyConfig nfcStateConfig = {
173         .entryCountSupported = true,
174         .entryCountPrefix = "Cumulative count:",
175         .totalTimeSupported = true,
176         .totalTimePrefix = "Cumulative duration msec:",
177         .lastEntrySupported = true,
178         .lastEntryPrefix = "Last entry timestamp msec:"
179     };
180     std::vector<std::pair<std::string, std::string>> nfcStateHeaders = {
181         std::make_pair("Idle", "Idle mode:"),
182         std::make_pair("Active", "Active mode:"),
183         std::make_pair("Active-RW", "Active Reader/Writer mode:"),
184     };
185 
186     sp<GenericStateResidencyDataProvider> nfcSdp =
187             new GenericStateResidencyDataProvider("/sys/class/misc/st21nfc/device/power_stats");
188 
189     uint32_t nfcId = service->addPowerEntity("NFC", PowerEntityType::SUBSYSTEM);
190     nfcSdp->addEntity(nfcId,
191         PowerEntityConfig(generateGenericStateResidencyConfigs(nfcStateConfig, nfcStateHeaders)));
192 
193     service->addStateResidencyDataProvider(nfcSdp);
194 
195     // Add GPU power entity
196     uint32_t gpuId = service->addPowerEntity("GPU", PowerEntityType::SUBSYSTEM);
197     sp<GpuStateResidencyDataProvider> gpuSdp = new GpuStateResidencyDataProvider(gpuId);
198     service->addStateResidencyDataProvider(gpuSdp);
199 
200     // Add Oslo power entity
201     uint32_t osloId = service->addPowerEntity("Oslo", PowerEntityType::SUBSYSTEM);
202     sp<OsloStateResidencyDataProvider> osloSdp = new OsloStateResidencyDataProvider(osloId);
203     service->addStateResidencyDataProvider(osloSdp);
204 
205     // Add IAXXX power entity
206     uint32_t iaxxxId = service->addPowerEntity("IAXXX", PowerEntityType::SUBSYSTEM);
207     sp<IaxxxStateResidencyDataProvider> iaxxxSdp = new IaxxxStateResidencyDataProvider(iaxxxId);
208     service->addStateResidencyDataProvider(iaxxxSdp);
209 
210     // Add Power Entities that require the Aidl data provider
211     sp<AidlStateResidencyDataProvider> aidlSdp = new AidlStateResidencyDataProvider();
212     uint32_t citadelId = service->addPowerEntity("Citadel", PowerEntityType::SUBSYSTEM);
213     aidlSdp->addEntity(citadelId, "Citadel", {"Last-Reset", "Active", "Deep-Sleep"});
214 
215     auto serviceStatus = android::defaultServiceManager()->addService(
216             android::String16("power.stats-vendor"), aidlSdp);
217     if (serviceStatus != android::OK) {
218         ALOGE("Unable to register power.stats-vendor service %d", serviceStatus);
219         return 1;
220     }
221     sp<android::ProcessState> ps{android::ProcessState::self()};  // Create non-HW binder threadpool
222     ps->startThreadPool();
223 
224     service->addStateResidencyDataProvider(aidlSdp);
225 
226     // Configure the threadpool
227     configureRpcThreadpool(1, true /*callerWillJoin*/);
228 
229     status_t status = service->registerAsService();
230     if (status != OK) {
231         ALOGE("Could not register service for power.stats HAL Iface (%d), exiting.", status);
232         return 1;
233     }
234 
235     ALOGI("power.stats service is ready");
236     joinRpcThreadpool();
237 
238     // In normal operation, we don't expect the thread pool to exit
239     ALOGE("power.stats service is shutting down");
240     return 1;
241 }
242