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