1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "entities/uid_entity.h"
17
18 #include <bundle_constants.h>
19 #include <bundle_mgr_interface.h>
20 #include <ipc_skeleton.h>
21 #include <ohos_account_kits_impl.h>
22 #include <system_ability_definition.h>
23 #include <sys_mgr_client.h>
24
25 #include "battery_stats_service.h"
26 #include "stats_log.h"
27
28 namespace OHOS {
29 namespace PowerMgr {
30 namespace {
31 auto g_statsService = DelayedStatsSpSingleton<BatteryStatsService>::GetInstance();
32 }
33
UidEntity()34 UidEntity::UidEntity()
35 {
36 consumptionType_ = BatteryStatsInfo::CONSUMPTION_TYPE_APP;
37 }
38
UpdateUidMap(int32_t uid)39 void UidEntity::UpdateUidMap(int32_t uid)
40 {
41 if (uid > StatsUtils::INVALID_VALUE) {
42 auto iter = uidPowerMap_.find(uid);
43 if (iter != uidPowerMap_.end()) {
44 STATS_HILOGD(COMP_SVC, "Uid has already been added, ignore");
45 } else {
46 STATS_HILOGD(COMP_SVC, "Update %{public}d to uid power map", uid);
47 uidPowerMap_.insert(std::pair<int32_t, double>(uid, StatsUtils::DEFAULT_VALUE));
48 }
49 }
50 }
51
GetUids()52 std::vector<int32_t> UidEntity::GetUids()
53 {
54 std::vector<int32_t> uids;
55 std::transform(uidPowerMap_.begin(), uidPowerMap_.end(), std::back_inserter(uids), [](const auto& item) {
56 return item.first;
57 });
58 return uids;
59 }
60
CalculateForConnectivity(int32_t uid)61 double UidEntity::CalculateForConnectivity(int32_t uid)
62 {
63 double power = StatsUtils::DEFAULT_VALUE;
64 auto core = g_statsService->GetBatteryStatsCore();
65 auto bluetoothEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_BLUETOOTH);
66
67 // Calculate bluetooth power consumption
68 bluetoothEntity->Calculate(uid);
69 power += bluetoothEntity->GetEntityPowerMah(uid);
70 STATS_HILOGD(COMP_SVC, "Connectivity power consumption: %{public}lfmAh for uid: %{public}d", power, uid);
71 return power;
72 }
73
CalculateForCommon(int32_t uid)74 double UidEntity::CalculateForCommon(int32_t uid)
75 {
76 double power = StatsUtils::DEFAULT_VALUE;
77 auto core = g_statsService->GetBatteryStatsCore();
78 auto cameraEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_CAMERA);
79 auto flashlightEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_FLASHLIGHT);
80 auto audioEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_AUDIO);
81 auto sensorEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_SENSOR);
82 auto gnssEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_GNSS);
83 auto cpuEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_CPU);
84 auto wakelockEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_WAKELOCK);
85 auto alarmEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_ALARM);
86
87 // Calculate camera power consumption
88 cameraEntity->Calculate(uid);
89 power += cameraEntity->GetEntityPowerMah(uid);
90 // Calculate flashlight power consumption
91 flashlightEntity->Calculate(uid);
92 power += flashlightEntity->GetEntityPowerMah(uid);
93 // Calculate audio power consumption
94 audioEntity->Calculate(uid);
95 power += audioEntity->GetEntityPowerMah(uid);
96 // Calculate sensor power consumption
97 sensorEntity->Calculate(uid);
98 power += sensorEntity->GetEntityPowerMah(uid);
99 // Calculate gnss power consumption
100 gnssEntity->Calculate(uid);
101 power += gnssEntity->GetEntityPowerMah(uid);
102 // Calculate cpu power consumption
103 cpuEntity->Calculate(uid);
104 power += cpuEntity->GetEntityPowerMah(uid);
105 // Calculate cpu power consumption
106 wakelockEntity->Calculate(uid);
107 power += wakelockEntity->GetEntityPowerMah(uid);
108 // Calculate alarm power consumption
109 alarmEntity->Calculate(uid);
110 power += alarmEntity->GetEntityPowerMah(uid);
111
112 STATS_HILOGD(COMP_SVC, "Common power consumption: %{public}lfmAh for uid: %{public}d", power, uid);
113 return power;
114 }
115
Calculate(int32_t uid)116 void UidEntity::Calculate(int32_t uid)
117 {
118 auto core = g_statsService->GetBatteryStatsCore();
119 auto userEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_USER);
120 for (auto& iter : uidPowerMap_) {
121 double power = StatsUtils::DEFAULT_VALUE;
122 power += CalculateForConnectivity(iter.first);
123 power += CalculateForCommon(iter.first);
124 iter.second = power;
125 totalPowerMah_ += power;
126 AddtoStatsList(iter.first, power);
127 int32_t uid = iter.first;
128 int32_t userId = AccountSA::OhosAccountKits::GetInstance().GetDeviceAccountIdByUID(uid);
129 if (userEntity != nullptr) {
130 userEntity->AggregateUserPowerMah(userId, power);
131 }
132 }
133 }
134
AddtoStatsList(int32_t uid,double power)135 void UidEntity::AddtoStatsList(int32_t uid, double power)
136 {
137 std::shared_ptr<BatteryStatsInfo> statsInfo = std::make_shared<BatteryStatsInfo>();
138 statsInfo->SetConsumptioType(BatteryStatsInfo::CONSUMPTION_TYPE_APP);
139 statsInfo->SetUid(uid);
140 statsInfo->SetPower(power);
141 statsInfoList_.push_back(statsInfo);
142 }
143
GetEntityPowerMah(int32_t uidOrUserId)144 double UidEntity::GetEntityPowerMah(int32_t uidOrUserId)
145 {
146 double power = StatsUtils::DEFAULT_VALUE;
147 auto iter = uidPowerMap_.find(uidOrUserId);
148 if (iter != uidPowerMap_.end()) {
149 power = iter->second;
150 STATS_HILOGD(COMP_SVC, "Get app uid power consumption: %{public}lfmAh for uid: %{public}d",
151 power, uidOrUserId);
152 } else {
153 STATS_HILOGD(COMP_SVC,
154 "No app uid power consumption related to uid: %{public}d was found, return 0", uidOrUserId);
155 }
156 return power;
157 }
158
GetPowerForConnectivity(StatsUtils::StatsType statsType,int32_t uid)159 double UidEntity::GetPowerForConnectivity(StatsUtils::StatsType statsType, int32_t uid)
160 {
161 double power = StatsUtils::DEFAULT_VALUE;
162 auto core = g_statsService->GetBatteryStatsCore();
163 auto bluetoothEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_BLUETOOTH);
164
165 if (statsType == StatsUtils::STATS_TYPE_BLUETOOTH_BR_SCAN) {
166 power = bluetoothEntity->GetStatsPowerMah(StatsUtils::STATS_TYPE_BLUETOOTH_BR_SCAN, uid);
167 } else if (statsType == StatsUtils::STATS_TYPE_BLUETOOTH_BLE_SCAN) {
168 power = bluetoothEntity->GetStatsPowerMah(StatsUtils::STATS_TYPE_BLUETOOTH_BLE_SCAN, uid);
169 }
170 return power;
171 }
172
GetPowerForCommon(StatsUtils::StatsType statsType,int32_t uid)173 double UidEntity::GetPowerForCommon(StatsUtils::StatsType statsType, int32_t uid)
174 {
175 double power = StatsUtils::DEFAULT_VALUE;
176 auto core = g_statsService->GetBatteryStatsCore();
177 auto cameraEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_CAMERA);
178 auto flashlightEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_FLASHLIGHT);
179 auto audioEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_AUDIO);
180 auto sensorEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_SENSOR);
181 auto gnssEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_GNSS);
182 auto cpuEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_CPU);
183 auto wakelockEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_WAKELOCK);
184 auto alarmEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_ALARM);
185
186 if (statsType == StatsUtils::STATS_TYPE_CAMERA_ON) {
187 power = cameraEntity->GetStatsPowerMah(StatsUtils::STATS_TYPE_CAMERA_ON, uid);
188 } else if (statsType == StatsUtils::STATS_TYPE_FLASHLIGHT_ON) {
189 power = flashlightEntity->GetStatsPowerMah(StatsUtils::STATS_TYPE_FLASHLIGHT_ON, uid);
190 } else if (statsType == StatsUtils::STATS_TYPE_GNSS_ON) {
191 power = gnssEntity->GetStatsPowerMah(StatsUtils::STATS_TYPE_GNSS_ON, uid);
192 } else if (statsType == StatsUtils::STATS_TYPE_SENSOR_GRAVITY_ON) {
193 power = sensorEntity->GetStatsPowerMah(StatsUtils::STATS_TYPE_SENSOR_GRAVITY_ON, uid);
194 } else if (statsType == StatsUtils::STATS_TYPE_SENSOR_PROXIMITY_ON) {
195 power = sensorEntity->GetStatsPowerMah(StatsUtils::STATS_TYPE_SENSOR_PROXIMITY_ON, uid);
196 } else if (statsType == StatsUtils::STATS_TYPE_AUDIO_ON) {
197 power = audioEntity->GetStatsPowerMah(StatsUtils::STATS_TYPE_AUDIO_ON, uid);
198 } else if (statsType == StatsUtils::STATS_TYPE_WAKELOCK_HOLD) {
199 power = wakelockEntity->GetStatsPowerMah(StatsUtils::STATS_TYPE_WAKELOCK_HOLD, uid);
200 } else if (statsType == StatsUtils::STATS_TYPE_CPU_CLUSTER) {
201 power = cpuEntity->GetStatsPowerMah(StatsUtils::STATS_TYPE_CPU_CLUSTER, uid);
202 } else if (statsType == StatsUtils::STATS_TYPE_CPU_SPEED) {
203 power = cpuEntity->GetStatsPowerMah(StatsUtils::STATS_TYPE_CPU_SPEED, uid);
204 } else if (statsType == StatsUtils::STATS_TYPE_CPU_ACTIVE) {
205 power = cpuEntity->GetStatsPowerMah(StatsUtils::STATS_TYPE_CPU_ACTIVE, uid);
206 } else if (statsType == StatsUtils::STATS_TYPE_ALARM) {
207 power = alarmEntity->GetStatsPowerMah(StatsUtils::STATS_TYPE_ALARM, uid);
208 }
209 return power;
210 }
211
GetStatsPowerMah(StatsUtils::StatsType statsType,int32_t uid)212 double UidEntity::GetStatsPowerMah(StatsUtils::StatsType statsType, int32_t uid)
213 {
214 double power = StatsUtils::DEFAULT_VALUE;
215
216 switch (statsType) {
217 case StatsUtils::STATS_TYPE_BLUETOOTH_BR_SCAN:
218 case StatsUtils::STATS_TYPE_BLUETOOTH_BLE_SCAN:
219 power = GetPowerForConnectivity(statsType, uid);
220 break;
221 case StatsUtils::STATS_TYPE_CAMERA_ON:
222 case StatsUtils::STATS_TYPE_FLASHLIGHT_ON:
223 case StatsUtils::STATS_TYPE_GNSS_ON:
224 case StatsUtils::STATS_TYPE_SENSOR_GRAVITY_ON:
225 case StatsUtils::STATS_TYPE_SENSOR_PROXIMITY_ON:
226 case StatsUtils::STATS_TYPE_AUDIO_ON:
227 case StatsUtils::STATS_TYPE_WAKELOCK_HOLD:
228 case StatsUtils::STATS_TYPE_CPU_CLUSTER:
229 case StatsUtils::STATS_TYPE_CPU_SPEED:
230 case StatsUtils::STATS_TYPE_CPU_ACTIVE:
231 case StatsUtils::STATS_TYPE_ALARM:
232 power = GetPowerForCommon(statsType, uid);
233 break;
234 default:
235 STATS_HILOGW(COMP_SVC, "Invalid or illegal type got, return 0");
236 break;
237 }
238
239 STATS_HILOGD(COMP_SVC, "Get %{public}s power: %{public}lfmAh for uid: %{public}d",
240 StatsUtils::ConvertStatsType(statsType).c_str(), power, uid);
241 return power;
242 }
243
Reset()244 void UidEntity::Reset()
245 {
246 // Reset app Uid total power consumption
247 for (auto& iter : uidPowerMap_) {
248 iter.second = StatsUtils::DEFAULT_VALUE;
249 }
250 }
251
DumpForBluetooth(int32_t uid,std::string & result)252 void UidEntity::DumpForBluetooth(int32_t uid, std::string& result)
253 {
254 // Dump for bluetooth realted info
255 auto core = g_statsService->GetBatteryStatsCore();
256 int64_t bluetoothBrScanTime = core->GetTotalTimeMs(uid, StatsUtils::STATS_TYPE_BLUETOOTH_BR_SCAN);
257 int64_t bluetoothBleScanTime = core->GetTotalTimeMs(uid, StatsUtils::STATS_TYPE_BLUETOOTH_BLE_SCAN);
258
259 result.append("Bluetooth Br scan time: ")
260 .append(ToString(bluetoothBrScanTime))
261 .append("ms\n")
262 .append("Bluetooth Ble scan time: ")
263 .append(ToString(bluetoothBleScanTime))
264 .append("ms\n");
265 }
266
DumpForCommon(int32_t uid,std::string & result)267 void UidEntity::DumpForCommon(int32_t uid, std::string& result)
268 {
269 auto core = g_statsService->GetBatteryStatsCore();
270 // Dump for camera related info
271 int64_t cameraTime = core->GetTotalTimeMs(uid, StatsUtils::STATS_TYPE_CAMERA_ON);
272
273 // Dump for flashlight related info
274 int64_t flashlightTime = core->GetTotalTimeMs(uid, StatsUtils::STATS_TYPE_FLASHLIGHT_ON);
275
276 // Dump for gnss related info
277 int64_t gnssTime = core->GetTotalTimeMs(uid, StatsUtils::STATS_TYPE_GNSS_ON);
278
279 // Dump for gravity sensor related info
280 int64_t gravityTime = core->GetTotalTimeMs(uid, StatsUtils::STATS_TYPE_SENSOR_GRAVITY_ON);
281
282 // Dump for proximity sensor related info
283 int64_t proximityTime = core->GetTotalTimeMs(uid, StatsUtils::STATS_TYPE_SENSOR_PROXIMITY_ON);
284
285 // Dump for audio related info
286 int64_t audioTime = core->GetTotalTimeMs(uid, StatsUtils::STATS_TYPE_AUDIO_ON);
287
288 // Dump for wakelock related info
289 int64_t wakelockTime = core->GetTotalTimeMs(uid, StatsUtils::STATS_TYPE_WAKELOCK_HOLD);
290
291 // Dump for alarm related info
292 int64_t alarmCount = core->GetTotalConsumptionCount(StatsUtils::STATS_TYPE_ALARM, uid);
293
294 result.append("Camera on time: ")
295 .append(ToString(cameraTime))
296 .append("ms\n")
297 .append("Flashlight scan time: ")
298 .append(ToString(flashlightTime))
299 .append("ms\n")
300 .append("GNSS scan time: ")
301 .append(ToString(gnssTime))
302 .append("ms\n")
303 .append("Gravity sensor on time: ")
304 .append(ToString(gravityTime))
305 .append("ms\n")
306 .append("Proximity sensor on time: ")
307 .append(ToString(proximityTime))
308 .append("ms\n")
309 .append("Audio on time: ")
310 .append(ToString(audioTime))
311 .append("ms\n")
312 .append("Wakelock hold time: ")
313 .append(ToString(wakelockTime))
314 .append("ms\n")
315 .append("Alarm trigger count: ")
316 .append(ToString(alarmCount))
317 .append("times\n");
318 }
319
DumpInfo(std::string & result,int32_t uid)320 void UidEntity::DumpInfo(std::string& result, int32_t uid)
321 {
322 auto core = g_statsService->GetBatteryStatsCore();
323 for (auto& iter : uidPowerMap_) {
324 std::string bundleName = "NULL";
325 auto bundleObj =
326 DelayedSingleton<AppExecFwk::SysMrgClient>::GetInstance()
327 ->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
328 if (bundleObj == nullptr) {
329 STATS_HILOGE(COMP_SVC, "Failed to get bundle manager service");
330 } else {
331 sptr<AppExecFwk::IBundleMgr> bmgr = iface_cast<AppExecFwk::IBundleMgr>(bundleObj);
332 if (bmgr == nullptr) {
333 STATS_HILOGE(COMP_SVC, "Failed to get bundle manager proxy");
334 } else {
335 std::string identity = IPCSkeleton::ResetCallingIdentity();
336 ErrCode res = bmgr->GetNameForUid(iter.first, bundleName);
337 IPCSkeleton::SetCallingIdentity(identity);
338 if (res != ERR_OK) {
339 STATS_HILOGE(COMP_SVC, "Failed to get bundle name for uid=%{public}d, ErrCode=%{public}d",
340 iter.first, static_cast<int32_t>(res));
341 }
342 }
343 }
344 result.append("\n")
345 .append(ToString(iter.first))
346 .append("(Bundle name: ")
347 .append(bundleName)
348 .append(")")
349 .append(":")
350 .append("\n");
351 DumpForBluetooth(iter.first, result);
352 DumpForCommon(iter.first, result);
353 auto cpuEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_CPU);
354 if (cpuEntity) {
355 cpuEntity->DumpInfo(result, iter.first);
356 }
357 }
358 }
359 } // namespace PowerMgr
360 } // namespace OHOS