• 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/bluetooth_entity.h"
17 
18 #include <cinttypes>
19 #include <ipc_skeleton.h>
20 #include "bundle_constants.h"
21 #include "bundle_mgr_interface.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 
BluetoothEntity()34 BluetoothEntity::BluetoothEntity()
35 {
36     consumptionType_ = BatteryStatsInfo::CONSUMPTION_TYPE_BLUETOOTH;
37 }
38 
Calculate(int32_t uid)39 void BluetoothEntity::Calculate(int32_t uid)
40 {
41     if (uid > StatsUtils::INVALID_VALUE) {
42         // Calculate Bluetooth scan caused by app
43         CalculateBtPowerForApp(uid);
44     } else {
45         // Calculate Bluetooth on and Bluetooth app power consumption caused by Bluetooth hardware
46         CalculateBtPower();
47     }
48 }
49 
CalculateBtPower()50 void BluetoothEntity::CalculateBtPower()
51 {
52     // Calculate Bluetooth BR on power
53     auto bluetoothBrOnAverageMa =
54         g_statsService->GetBatteryStatsParser()->GetAveragePowerMa(StatsUtils::CURRENT_BLUETOOTH_BR_ON);
55     auto bluetoothBrOnTimeMs = GetActiveTimeMs(StatsUtils::STATS_TYPE_BLUETOOTH_BR_ON);
56     auto bluetoothBrOnPowerMah = bluetoothBrOnAverageMa * bluetoothBrOnTimeMs / StatsUtils::MS_IN_HOUR;
57     bluetoothBrPowerMah_ += bluetoothBrOnPowerMah;
58 
59     // Calculate Bluetooth BLE on power
60     auto bluetoothBleOnAverageMa =
61         g_statsService->GetBatteryStatsParser()->GetAveragePowerMa(StatsUtils::CURRENT_BLUETOOTH_BLE_ON);
62     auto bluetoothBleOnTimeMs = GetActiveTimeMs(StatsUtils::STATS_TYPE_BLUETOOTH_BLE_ON);
63     auto bluetoothBleOnPowerMah = bluetoothBleOnAverageMa * bluetoothBleOnTimeMs / StatsUtils::MS_IN_HOUR;
64     bluetoothBlePowerMah_ += bluetoothBleOnPowerMah;
65 
66     auto bluetoothUidPowerMah = GetBluetoothUidPower();
67 
68     bluetoothPowerMah_ = bluetoothBrOnPowerMah + bluetoothBleOnPowerMah + bluetoothUidPowerMah;
69     totalPowerMah_ += bluetoothPowerMah_;
70 
71     std::shared_ptr<BatteryStatsInfo> statsInfo = std::make_shared<BatteryStatsInfo>();
72     statsInfo->SetConsumptioType(BatteryStatsInfo::CONSUMPTION_TYPE_BLUETOOTH);
73     statsInfo->SetPower(bluetoothPowerMah_);
74     statsInfoList_.push_back(statsInfo);
75 
76     STATS_HILOGD(COMP_SVC, "Calculate bluetooth Br time: %{public}" PRId64 "ms, Br power average: %{public}lfma,"    \
77         "Br power consumption: %{public}lfmAh, bluetooth Ble time: %{public}" PRId64 "ms, "                          \
78         "Ble power average: %{public}lfma, Ble power consumption: %{public}lfmAh, "                                  \
79         "uid power consumption: %{public}lfmAh, total power consumption: %{public}lfmAh",
80         bluetoothBrOnTimeMs,
81         bluetoothBrOnAverageMa,
82         bluetoothBrOnPowerMah,
83         bluetoothBleOnTimeMs,
84         bluetoothBleOnAverageMa,
85         bluetoothBleOnPowerMah,
86         bluetoothUidPowerMah,
87         bluetoothPowerMah_);
88 }
89 
CalculateBtPowerForApp(int32_t uid)90 void BluetoothEntity::CalculateBtPowerForApp(int32_t uid)
91 {
92     // Calculate Bluetooth Br scan power consumption
93     auto bluetoothBrScanAverageMa =
94         g_statsService->GetBatteryStatsParser()->GetAveragePowerMa(StatsUtils::CURRENT_BLUETOOTH_BR_SCAN);
95     auto bluetoothBrScanTimeMs = GetActiveTimeMs(uid, StatsUtils::STATS_TYPE_BLUETOOTH_BR_SCAN);
96     auto bluetoothBrScanPowerMah = bluetoothBrScanTimeMs * bluetoothBrScanAverageMa / StatsUtils::MS_IN_HOUR;
97     UpdateAppBluetoothBlePower(POWER_TYPE_BR, uid, bluetoothBrScanPowerMah);
98 
99     // Calculate Bluetooth Ble scan power consumption
100     auto bluetoothBleScanAverageMa =
101         g_statsService->GetBatteryStatsParser()->GetAveragePowerMa(StatsUtils::CURRENT_BLUETOOTH_BLE_SCAN);
102     auto bluetoothBleScanTimeMs = GetActiveTimeMs(uid, StatsUtils::STATS_TYPE_BLUETOOTH_BLE_SCAN);
103     auto bluetoothBleScanPowerMah = bluetoothBleScanTimeMs * bluetoothBleScanAverageMa / StatsUtils::MS_IN_HOUR;
104     UpdateAppBluetoothBlePower(POWER_TYPE_BLE, uid, bluetoothBleScanPowerMah);
105 
106     auto bluetoothUidPowerMah = bluetoothBrScanPowerMah + bluetoothBleScanPowerMah;
107     UpdateAppBluetoothBlePower(POWER_TYPE_ALL, uid, bluetoothUidPowerMah);
108 
109     STATS_HILOGD(COMP_SVC, "Calculate bluetooth Br scan time: %{public}" PRId64 "ms, "                         \
110         "Br scan power average: %{public}lfma, Br scan power consumption: %{public}lfmAh "                     \
111         "bluetooth Ble scan time: %{public}" PRId64 "ms, Ble scan power average: %{public}lfma, "              \
112         "Ble scan power consumption: %{public}lfmAh, total power consumption: %{public}lfmAh, uid:%{public}d",
113         bluetoothBrScanTimeMs,
114         bluetoothBrScanAverageMa,
115         bluetoothBrScanPowerMah,
116         bluetoothBleScanTimeMs,
117         bluetoothBleScanAverageMa,
118         bluetoothBleScanPowerMah,
119         bluetoothUidPowerMah,
120         uid);
121 }
122 
UpdateAppBluetoothBlePower(PowerType type,int32_t uid,double powerMah)123 void BluetoothEntity::UpdateAppBluetoothBlePower(PowerType type, int32_t uid, double powerMah)
124 {
125     switch (type) {
126         case POWER_TYPE_BR: {
127             auto iter = appBluetoothBrPowerMap_.find(uid);
128             if (iter != appBluetoothBrPowerMap_.end()) {
129                 iter->second = powerMah;
130                 STATS_HILOGD(COMP_SVC, "Update app bluetooth Br power consumption: %{public}lfmAh for uid: %{public}d",
131                     powerMah, uid);
132                 break;
133             }
134             appBluetoothBrPowerMap_.insert(std::pair<int32_t, double>(uid, powerMah));
135             STATS_HILOGD(COMP_SVC, "Create app bluetooth Br power consumption: %{public}lfmAh for uid: %{public}d",
136                 powerMah, uid);
137             break;
138         }
139         case POWER_TYPE_BLE: {
140             auto iter = appBluetoothBlePowerMap_.find(uid);
141             if (iter != appBluetoothBlePowerMap_.end()) {
142                 iter->second = powerMah;
143                 STATS_HILOGD(COMP_SVC, "Update app bluetooth Ble power consumption: %{public}lfmAh for uid: %{public}d",
144                     powerMah, uid);
145                 break;
146             }
147             appBluetoothBlePowerMap_.insert(std::pair<int32_t, double>(uid, powerMah));
148             STATS_HILOGD(COMP_SVC, "Create app bluetooth Ble power consumption: %{public}lfmAh for uid: %{public}d",
149                 powerMah, uid);
150             break;
151         }
152         case POWER_TYPE_ALL: {
153             auto iter = appBluetoothPowerMap_.find(uid);
154             if (iter != appBluetoothPowerMap_.end()) {
155                 iter->second = powerMah;
156                 STATS_HILOGD(COMP_SVC, "Update app bluetooth power consumption: %{public}lfmAh for uid: %{public}d",
157                     powerMah, uid);
158                 break;
159             }
160             appBluetoothPowerMap_.insert(std::pair<int32_t, double>(uid, powerMah));
161             STATS_HILOGD(COMP_SVC, "Create app bluetooth power consumption: %{public}lfmAh for uid: %{public}d",
162                 powerMah, uid);
163             break;
164         }
165         default:
166             break;
167     }
168 }
169 
GetActiveTimeMs(int32_t uid,StatsUtils::StatsType statsType,int16_t level)170 int64_t BluetoothEntity::GetActiveTimeMs(int32_t uid, StatsUtils::StatsType statsType, int16_t level)
171 {
172     int64_t time = StatsUtils::DEFAULT_VALUE;
173     switch (statsType) {
174         case StatsUtils::STATS_TYPE_BLUETOOTH_BR_SCAN: {
175             auto brScanIter = appBluetoothBrScanTimerMap_.find(uid);
176             if (brScanIter != appBluetoothBrScanTimerMap_.end()) {
177                 time = brScanIter->second->GetRunningTimeMs();
178                 STATS_HILOGD(COMP_SVC, "Get blueooth Br scan time: %{public}" PRId64 "ms for uid: %{public}d",
179                     time, uid);
180                 break;
181             }
182             STATS_HILOGD(COMP_SVC, "No bluetooth Br scan timer related to uid: %{public}d was found, return 0", uid);
183             break;
184         }
185         case StatsUtils::STATS_TYPE_BLUETOOTH_BLE_SCAN: {
186             auto bleScanIter = appBluetoothBleScanTimerMap_.find(uid);
187             if (bleScanIter != appBluetoothBleScanTimerMap_.end()) {
188                 time = bleScanIter->second->GetRunningTimeMs();
189                 STATS_HILOGD(COMP_SVC, "Get blueooth Ble scan time: %{public}" PRId64 "ms for uid: %{public}d",
190                     time, uid);
191                 break;
192             }
193             STATS_HILOGD(COMP_SVC, "No bluetooth Ble scan timer related to uid: %{public}d was found, return 0", uid);
194             break;
195         }
196         default:
197             break;
198     }
199     return time;
200 }
201 
GetActiveTimeMs(StatsUtils::StatsType statsType,int16_t level)202 int64_t BluetoothEntity::GetActiveTimeMs(StatsUtils::StatsType statsType, int16_t level)
203 {
204     int64_t time = StatsUtils::DEFAULT_VALUE;
205     switch (statsType) {
206         case StatsUtils::STATS_TYPE_BLUETOOTH_BR_ON: {
207             if (bluetoothBrOnTimer_) {
208                 time = bluetoothBrOnTimer_->GetRunningTimeMs();
209                 STATS_HILOGD(COMP_SVC, "Get blueooth Br on time: %{public}" PRId64 "ms", time);
210                 break;
211             }
212             STATS_HILOGD(COMP_SVC, "Bluetooth Br has not been turned on yet, return 0");
213             break;
214         }
215         case StatsUtils::STATS_TYPE_BLUETOOTH_BLE_ON: {
216             if (bluetoothBleOnTimer_) {
217                 time = bluetoothBleOnTimer_->GetRunningTimeMs();
218                 STATS_HILOGD(COMP_SVC, "Get blueooth Ble on time: %{public}" PRId64 "ms", time);
219                 break;
220             }
221             STATS_HILOGD(COMP_SVC, "Bluetooth Ble has not been turned on yet, return 0");
222             break;
223         }
224         default:
225             break;
226     }
227     return time;
228 }
229 
GetEntityPowerMah(int32_t uidOrUserId)230 double BluetoothEntity::GetEntityPowerMah(int32_t uidOrUserId)
231 {
232     double power = StatsUtils::DEFAULT_VALUE;
233     if (uidOrUserId > StatsUtils::INVALID_VALUE) {
234         auto iter = appBluetoothPowerMap_.find(uidOrUserId);
235         if (iter != appBluetoothPowerMap_.end()) {
236             power = iter->second;
237             STATS_HILOGD(COMP_SVC, "Get app blueooth power consumption: %{public}lfmAh for uid: %{public}d",
238                 power, uidOrUserId);
239         } else {
240             STATS_HILOGD(COMP_SVC,
241                 "No app blueooth power consumption related to uid: %{public}d was found, return 0", uidOrUserId);
242         }
243     } else {
244         power = bluetoothPowerMah_;
245         STATS_HILOGD(COMP_SVC, "Get blueooth power consumption: %{public}lfmAh", power);
246     }
247     return power;
248 }
249 
GetStatsPowerMah(StatsUtils::StatsType statsType,int32_t uid)250 double BluetoothEntity::GetStatsPowerMah(StatsUtils::StatsType statsType, int32_t uid)
251 {
252     double power = StatsUtils::DEFAULT_VALUE;
253     switch (statsType) {
254         case StatsUtils::STATS_TYPE_BLUETOOTH_BR_ON: {
255             power = bluetoothBrPowerMah_;
256             STATS_HILOGD(COMP_SVC, "Get blueooth Br on power consumption: %{public}lfmAh", power);
257             break;
258         }
259         case StatsUtils::STATS_TYPE_BLUETOOTH_BLE_ON: {
260             power = bluetoothBlePowerMah_;
261             STATS_HILOGD(COMP_SVC, "Get blueooth Ble on power consumption: %{public}lfmAh", power);
262             break;
263         }
264         case StatsUtils::STATS_TYPE_BLUETOOTH_BR_SCAN: {
265             auto brIter = appBluetoothBrPowerMap_.find(uid);
266             if (brIter != appBluetoothBrPowerMap_.end()) {
267                 power = brIter->second;
268                 STATS_HILOGD(COMP_SVC, "Get blueooth Br scan power consumption: %{public}lfmAh for uid: %{public}d",
269                     power, uid);
270                 break;
271             }
272             STATS_HILOGD(COMP_SVC,
273                 "No bluetooth Br scan power consumption related to uid: %{public}d was found, return 0", uid);
274             break;
275         }
276         case StatsUtils::STATS_TYPE_BLUETOOTH_BLE_SCAN: {
277             auto bleIter = appBluetoothBlePowerMap_.find(uid);
278             if (bleIter != appBluetoothBlePowerMap_.end()) {
279                 power = bleIter->second;
280                 STATS_HILOGD(COMP_SVC, "Get blueooth Ble scan power consumption: %{public}lfmAh for uid: %{public}d",
281                     power, uid);
282                 break;
283             }
284             STATS_HILOGD(COMP_SVC,
285                 "No bluetooth Ble scan power consumption related to uid: %{public}d was found, return 0", uid);
286             break;
287         }
288         default:
289             break;
290     }
291     return power;
292 }
293 
Reset()294 void BluetoothEntity::Reset()
295 {
296     // Reset Bluetooth on timer and power consumption
297     bluetoothBrPowerMah_ = StatsUtils::DEFAULT_VALUE;
298     bluetoothBlePowerMah_ = StatsUtils::DEFAULT_VALUE;
299     bluetoothPowerMah_ = StatsUtils::DEFAULT_VALUE;
300     if (bluetoothBrOnTimer_) {
301         bluetoothBrOnTimer_->Reset();
302     }
303 
304     if (bluetoothBleOnTimer_) {
305         bluetoothBleOnTimer_->Reset();
306     }
307 
308     // Reset app Bluetooth scan power consumption
309     for (auto& iter : appBluetoothBrPowerMap_) {
310         iter.second = StatsUtils::DEFAULT_VALUE;
311     }
312 
313     for (auto& iter : appBluetoothBlePowerMap_) {
314         iter.second = StatsUtils::DEFAULT_VALUE;
315     }
316 
317     for (auto& iter : appBluetoothPowerMap_) {
318         iter.second = StatsUtils::DEFAULT_VALUE;
319     }
320 
321     // Reset Bluetooth scan timer
322     for (auto& iter : appBluetoothBrScanTimerMap_) {
323         if (iter.second) {
324             iter.second->Reset();
325         }
326     }
327 
328     for (auto& iter : appBluetoothBleScanTimerMap_) {
329         if (iter.second) {
330             iter.second->Reset();
331         }
332     }
333 }
334 
GetOrCreateTimer(int32_t uid,StatsUtils::StatsType statsType,int16_t level)335 std::shared_ptr<StatsHelper::ActiveTimer> BluetoothEntity::GetOrCreateTimer(int32_t uid,
336     StatsUtils::StatsType statsType, int16_t level)
337 {
338     std::shared_ptr<StatsHelper::ActiveTimer> timer = nullptr;
339     switch (statsType) {
340         case StatsUtils::STATS_TYPE_BLUETOOTH_BR_SCAN: {
341             auto brScanIter = appBluetoothBrScanTimerMap_.find(uid);
342             if (brScanIter != appBluetoothBrScanTimerMap_.end()) {
343                 STATS_HILOGD(COMP_SVC, "Get blueooth Br scan timer for uid: %{public}d", uid);
344                 timer = brScanIter->second;
345                 break;
346             }
347             STATS_HILOGD(COMP_SVC, "Create bluetooth Br scan timer for uid: %{public}d", uid);
348             std::shared_ptr<StatsHelper::ActiveTimer> brScanTimer = std::make_shared<StatsHelper::ActiveTimer>();
349             appBluetoothBrScanTimerMap_.insert(
350                 std::pair<int32_t, std::shared_ptr<StatsHelper::ActiveTimer>>(uid, brScanTimer));
351             timer = brScanTimer;
352             break;
353         }
354         case StatsUtils::STATS_TYPE_BLUETOOTH_BLE_SCAN: {
355             auto bleScanIter = appBluetoothBleScanTimerMap_.find(uid);
356             if (bleScanIter != appBluetoothBleScanTimerMap_.end()) {
357                 STATS_HILOGD(COMP_SVC, "Get blueooth Ble scan timer for uid: %{public}d", uid);
358                 timer = bleScanIter->second;
359                 break;
360             }
361             STATS_HILOGD(COMP_SVC, "Create bluetooth Ble scan timer for uid: %{public}d", uid);
362             std::shared_ptr<StatsHelper::ActiveTimer> bleScanTimer = std::make_shared<StatsHelper::ActiveTimer>();
363             appBluetoothBleScanTimerMap_.insert(
364                 std::pair<int32_t, std::shared_ptr<StatsHelper::ActiveTimer>>(uid, bleScanTimer));
365             timer = bleScanTimer;
366             break;
367         }
368         default:
369             STATS_HILOGW(COMP_SVC, "Create active timer failed");
370             break;
371     }
372     return timer;
373 }
374 
GetOrCreateTimer(StatsUtils::StatsType statsType,int16_t level)375 std::shared_ptr<StatsHelper::ActiveTimer> BluetoothEntity::GetOrCreateTimer(StatsUtils::StatsType statsType,
376     int16_t level)
377 {
378     std::shared_ptr<StatsHelper::ActiveTimer> timer = nullptr;
379     switch (statsType) {
380         case StatsUtils::STATS_TYPE_BLUETOOTH_BR_ON: {
381             if (bluetoothBrOnTimer_ != nullptr) {
382                 STATS_HILOGD(COMP_SVC, "Get blueooth Br on timer");
383                 timer = bluetoothBrOnTimer_;
384                 break;
385             }
386             STATS_HILOGD(COMP_SVC, "Create blueooth Br on timer");
387             bluetoothBrOnTimer_ = std::make_shared<StatsHelper::ActiveTimer>();
388             timer = bluetoothBrOnTimer_;
389             break;
390         }
391         case StatsUtils::STATS_TYPE_BLUETOOTH_BLE_ON: {
392             if (bluetoothBleOnTimer_ != nullptr) {
393                 STATS_HILOGD(COMP_SVC, "Get blueooth Ble on timer");
394                 timer = bluetoothBleOnTimer_;
395                 break;
396             }
397             STATS_HILOGD(COMP_SVC, "Create blueooth Ble on timer");
398             bluetoothBleOnTimer_ = std::make_shared<StatsHelper::ActiveTimer>();
399             timer = bluetoothBleOnTimer_;
400             break;
401         }
402         default:
403             STATS_HILOGW(COMP_SVC, "Create active timer failed");
404             break;
405     }
406     return timer;
407 }
408 
GetBluetoothUidPower()409 double BluetoothEntity::GetBluetoothUidPower()
410 {
411     double bluetoothUidPower = StatsUtils::DEFAULT_VALUE;
412     auto bundleObj =
413         DelayedSingleton<AppExecFwk::SysMrgClient>::GetInstance()->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
414     if (bundleObj == nullptr) {
415         STATS_HILOGW(COMP_SVC, "Failed to get bundle manager service, return 0");
416         return bluetoothUidPower;
417     }
418 
419     sptr<AppExecFwk::IBundleMgr> bmgr = iface_cast<AppExecFwk::IBundleMgr>(bundleObj);
420     if (bmgr == nullptr) {
421         STATS_HILOGW(COMP_SVC, "Failed to get bundle manager proxy, return 0");
422         return bluetoothUidPower;
423     }
424 
425     std::string bundleName = "com.ohos.bluetooth";
426     std::string identity = IPCSkeleton::ResetCallingIdentity();
427     int32_t bluetoothUid = bmgr->GetUidByBundleName(bundleName, AppExecFwk::Constants::DEFAULT_USERID);
428     IPCSkeleton::SetCallingIdentity(identity);
429 
430     auto core = g_statsService->GetBatteryStatsCore();
431     auto uidEntity = core->GetEntity(BatteryStatsInfo::CONSUMPTION_TYPE_APP);
432     if (uidEntity != nullptr) {
433         bluetoothUidPower = uidEntity->GetEntityPowerMah(bluetoothUid);
434     }
435     STATS_HILOGD(COMP_SVC, "Get bluetooth uid power consumption: %{public}lfmAh", bluetoothUidPower);
436     return bluetoothUidPower;
437 }
438 
DumpInfo(std::string & result,int32_t uid)439 void BluetoothEntity::DumpInfo(std::string& result, int32_t uid)
440 {
441     int64_t brOntime = GetActiveTimeMs(StatsUtils::STATS_TYPE_BLUETOOTH_BR_ON);
442     int64_t bleOntime = GetActiveTimeMs(StatsUtils::STATS_TYPE_BLUETOOTH_BR_ON);
443     result.append("Bluetooth dump:\n")
444         .append("Bluetooth Br on time: ")
445         .append(ToString(brOntime))
446         .append("ms")
447         .append("\n")
448         .append("Bluetooth Ble on time: ")
449         .append(ToString(bleOntime))
450         .append("ms")
451         .append("\n");
452 }
453 } // namespace PowerMgr
454 } // namespace OHOS
455