• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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