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