• 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 #include "battery_stats_core.h"
16 
17 #include <cinttypes>
18 #include <fstream>
19 #include <map>
20 #include <functional>
21 #include <list>
22 #include <utility>
23 #include <vector>
24 
25 #include "ios"
26 #include "json/reader.h"
27 #include "json/writer.h"
28 #include "ohos_account_kits.h"
29 
30 #include "battery_info.h"
31 #include "battery_srv_client.h"
32 #include "entities/audio_entity.h"
33 #include "entities/bluetooth_entity.h"
34 #include "entities/camera_entity.h"
35 #include "entities/cpu_entity.h"
36 #include "entities/flashlight_entity.h"
37 #include "entities/gnss_entity.h"
38 #include "entities/idle_entity.h"
39 #include "entities/phone_entity.h"
40 #include "entities/screen_entity.h"
41 #include "entities/sensor_entity.h"
42 #include "entities/uid_entity.h"
43 #include "entities/user_entity.h"
44 #include "entities/wifi_entity.h"
45 #include "entities/wakelock_entity.h"
46 #include "entities/alarm_entity.h"
47 #include "stats_helper.h"
48 
49 #include "xcollie/xcollie.h"
50 #include "xcollie/xcollie_define.h"
51 
52 namespace OHOS {
53 namespace PowerMgr {
54 namespace {
55 static const std::string BATTERY_STATS_JSON = "/data/service/el0/stats/battery_stats.json";
56 } // namespace
CreatePartEntity()57 void BatteryStatsCore::CreatePartEntity()
58 {
59     if (bluetoothEntity_ == nullptr) {
60         STATS_HILOGD(COMP_SVC, "Create bluetooth entity");
61         bluetoothEntity_ = std::make_shared<BluetoothEntity>();
62     }
63     if (idleEntity_ == nullptr) {
64         STATS_HILOGD(COMP_SVC, "Create idle entity");
65         idleEntity_ = std::make_shared<IdleEntity>();
66     }
67     if (phoneEntity_ == nullptr) {
68         STATS_HILOGD(COMP_SVC, "Create phone entity");
69         phoneEntity_ = std::make_shared<PhoneEntity>();
70     }
71     if (screenEntity_ == nullptr) {
72         STATS_HILOGD(COMP_SVC, "Create screen entity");
73         screenEntity_ = std::make_shared<ScreenEntity>();
74     }
75     if (wifiEntity_ == nullptr) {
76         STATS_HILOGD(COMP_SVC, "Create wifi entity");
77         wifiEntity_ = std::make_shared<WifiEntity>();
78     }
79 }
80 
CreateAppEntity()81 void BatteryStatsCore::CreateAppEntity()
82 {
83     if (audioEntity_ == nullptr) {
84         STATS_HILOGD(COMP_SVC, "Create audio entity");
85         audioEntity_ = std::make_shared<AudioEntity>();
86     }
87     if (cameraEntity_ == nullptr) {
88         STATS_HILOGD(COMP_SVC, "Create camera entity");
89         cameraEntity_ = std::make_shared<CameraEntity>();
90     }
91     if (flashlightEntity_ == nullptr) {
92         STATS_HILOGD(COMP_SVC, "Create flashlight entity");
93         flashlightEntity_ = std::make_shared<FlashlightEntity>();
94     }
95     if (gnssEntity_ == nullptr) {
96         STATS_HILOGD(COMP_SVC, "Create gnss entity");
97         gnssEntity_ = std::make_shared<GnssEntity>();
98     }
99     if (sensorEntity_ == nullptr) {
100         STATS_HILOGD(COMP_SVC, "Create sensor entity");
101         sensorEntity_ = std::make_shared<SensorEntity>();
102     }
103     if (uidEntity_ == nullptr) {
104         STATS_HILOGD(COMP_SVC, "Create uid entity");
105         uidEntity_ = std::make_shared<UidEntity>();
106     }
107     if (userEntity_ == nullptr) {
108         STATS_HILOGD(COMP_SVC, "Create user entity");
109         userEntity_ = std::make_shared<UserEntity>();
110     }
111     if (wakelockEntity_ == nullptr) {
112         STATS_HILOGD(COMP_SVC, "Create wakelock entity");
113         wakelockEntity_ = std::make_shared<WakelockEntity>();
114     }
115     if (cpuEntity_ == nullptr) {
116         STATS_HILOGD(COMP_SVC, "Create cpu entity");
117         cpuEntity_ = std::make_shared<CpuEntity>();
118     }
119     if (alarmEntity_ == nullptr) {
120         STATS_HILOGD(COMP_SVC, "Create alarm entity");
121         alarmEntity_ = std::make_shared<AlarmEntity>();
122     }
123 }
124 
Init()125 bool BatteryStatsCore::Init()
126 {
127     STATS_HILOGI(COMP_SVC, "Battery stats core init");
128     CreateAppEntity();
129     CreatePartEntity();
130     auto& batterySrvClient = BatterySrvClient::GetInstance();
131     BatteryPluggedType plugType = batterySrvClient.GetPluggedType();
132     if (plugType == BatteryPluggedType::PLUGGED_TYPE_NONE || plugType == BatteryPluggedType::PLUGGED_TYPE_BUTT) {
133         StatsHelper::SetOnBattery(true);
134     } else {
135         StatsHelper::SetOnBattery(false);
136     }
137 
138     if (!LoadBatteryStatsData()) {
139         STATS_HILOGW(COMP_SVC, "Load battery stats data failed");
140     }
141     return true;
142 }
143 
ComputePower()144 void BatteryStatsCore::ComputePower()
145 {
146     std::lock_guard lock(mutex_);
147     STATS_HILOGD(COMP_SVC, "Calculate battery stats");
148     const uint32_t DFX_DELAY_MS = 10000;
149     int id = HiviewDFX::XCollie::GetInstance().SetTimer("BatteryStatsCoreComputePower", DFX_DELAY_MS, nullptr, nullptr,
150         HiviewDFX::XCOLLIE_FLAG_NOOP);
151 
152     BatteryStatsEntity::ResetStatsEntity();
153     uidEntity_->Calculate();
154     bluetoothEntity_->Calculate();
155     idleEntity_->Calculate();
156     phoneEntity_->Calculate();
157     screenEntity_->Calculate();
158     wifiEntity_->Calculate();
159     userEntity_->Calculate();
160 
161     HiviewDFX::XCollie::GetInstance().CancelTimer(id);
162 }
163 
GetBatteryStats()164 BatteryStatsInfoList BatteryStatsCore::GetBatteryStats()
165 {
166     return BatteryStatsEntity::GetStatsInfoList();
167 }
168 
GetEntity(const BatteryStatsInfo::ConsumptionType & type)169 std::shared_ptr<BatteryStatsEntity> BatteryStatsCore::GetEntity(const BatteryStatsInfo::ConsumptionType& type)
170 {
171     STATS_HILOGD(COMP_SVC, "Get %{public}s entity", BatteryStatsInfo::ConvertConsumptionType(type).c_str());
172     switch (type) {
173         case BatteryStatsInfo::CONSUMPTION_TYPE_APP:
174             return uidEntity_;
175         case BatteryStatsInfo::CONSUMPTION_TYPE_BLUETOOTH:
176             return bluetoothEntity_;
177         case BatteryStatsInfo::CONSUMPTION_TYPE_IDLE:
178             return idleEntity_;
179         case BatteryStatsInfo::CONSUMPTION_TYPE_PHONE:
180             return phoneEntity_;
181         case BatteryStatsInfo::CONSUMPTION_TYPE_SCREEN:
182             return screenEntity_;
183         case BatteryStatsInfo::CONSUMPTION_TYPE_USER:
184             return userEntity_;
185         case BatteryStatsInfo::CONSUMPTION_TYPE_WIFI:
186             return wifiEntity_;
187         case BatteryStatsInfo::CONSUMPTION_TYPE_CAMERA:
188             return cameraEntity_;
189         case BatteryStatsInfo::CONSUMPTION_TYPE_FLASHLIGHT:
190             return flashlightEntity_;
191         case BatteryStatsInfo::CONSUMPTION_TYPE_AUDIO:
192             return audioEntity_;
193         case BatteryStatsInfo::CONSUMPTION_TYPE_SENSOR:
194             return sensorEntity_;
195         case BatteryStatsInfo::CONSUMPTION_TYPE_GNSS:
196             return gnssEntity_;
197         case BatteryStatsInfo::CONSUMPTION_TYPE_CPU:
198             return cpuEntity_;
199         case BatteryStatsInfo::CONSUMPTION_TYPE_WAKELOCK:
200             return wakelockEntity_;
201         case BatteryStatsInfo::CONSUMPTION_TYPE_ALARM:
202             return alarmEntity_;
203         case BatteryStatsInfo::CONSUMPTION_TYPE_INVALID:
204         default:
205             return nullptr;
206     }
207 }
208 
UpdateStats(StatsUtils::StatsType statsType,int64_t time,int64_t data,int32_t uid)209 void BatteryStatsCore::UpdateStats(StatsUtils::StatsType statsType, int64_t time, int64_t data, int32_t uid)
210 {
211     STATS_HILOGD(COMP_SVC,
212         "Update for duration, statsType: %{public}s, uid: %{public}d, time: %{public}" PRId64 ", "  \
213         "data: %{public}" PRId64 "",
214         StatsUtils::ConvertStatsType(statsType).c_str(), uid, time, data);
215     if (uid > StatsUtils::INVALID_VALUE) {
216         uidEntity_->UpdateUidMap(uid);
217     }
218 
219     switch (statsType) {
220         case StatsUtils::STATS_TYPE_WIFI_SCAN:
221             UpdateCounter(wifiEntity_, statsType, data, uid);
222             break;
223         case StatsUtils::STATS_TYPE_ALARM:
224             UpdateCounter(alarmEntity_, statsType, data, uid);
225             break;
226         default:
227             break;
228     }
229 }
230 
UpdateConnectivityStats(StatsUtils::StatsType statsType,StatsUtils::StatsState state,int32_t uid)231 void BatteryStatsCore::UpdateConnectivityStats(StatsUtils::StatsType statsType, StatsUtils::StatsState state,
232     int32_t uid)
233 {
234     switch (statsType) {
235         case StatsUtils::STATS_TYPE_BLUETOOTH_BR_ON:
236         case StatsUtils::STATS_TYPE_BLUETOOTH_BLE_ON:
237             UpdateTimer(bluetoothEntity_, statsType, state);
238             break;
239         case StatsUtils::STATS_TYPE_WIFI_ON:
240             UpdateTimer(wifiEntity_, statsType, state);
241             break;
242         case StatsUtils::STATS_TYPE_BLUETOOTH_BR_SCAN:
243         case StatsUtils::STATS_TYPE_BLUETOOTH_BLE_SCAN:
244             UpdateTimer(bluetoothEntity_, statsType, state, uid);
245             break;
246         default:
247             break;
248     }
249 }
250 
UpdateCommonStats(StatsUtils::StatsType statsType,StatsUtils::StatsState state,int32_t uid)251 void BatteryStatsCore::UpdateCommonStats(StatsUtils::StatsType statsType, StatsUtils::StatsState state, int32_t uid)
252 {
253     switch (statsType) {
254         case StatsUtils::STATS_TYPE_FLASHLIGHT_ON:
255             UpdateTimer(flashlightEntity_, statsType, state, uid);
256             break;
257         case StatsUtils::STATS_TYPE_GNSS_ON:
258             UpdateTimer(gnssEntity_, statsType, state, uid);
259             break;
260         case StatsUtils::STATS_TYPE_SENSOR_GRAVITY_ON:
261             UpdateTimer(sensorEntity_, statsType, state, uid);
262             break;
263         case StatsUtils::STATS_TYPE_SENSOR_PROXIMITY_ON:
264             UpdateTimer(sensorEntity_, statsType, state, uid);
265             break;
266         case StatsUtils::STATS_TYPE_AUDIO_ON:
267             UpdateTimer(audioEntity_, statsType, state, uid);
268             break;
269         case StatsUtils::STATS_TYPE_WAKELOCK_HOLD:
270             UpdateTimer(wakelockEntity_, statsType, state, uid);
271             break;
272         default:
273             break;
274     }
275 }
276 
UpdateStats(StatsUtils::StatsType statsType,StatsUtils::StatsState state,int16_t level,int32_t uid,const std::string & deviceId)277 void BatteryStatsCore::UpdateStats(StatsUtils::StatsType statsType, StatsUtils::StatsState state, int16_t level,
278     int32_t uid, const std::string& deviceId)
279 {
280     STATS_HILOGD(COMP_SVC,
281         "Update for state, statsType: %{public}s, uid: %{public}d, state: %{public}d, level: %{public}d,"   \
282         "deviceId: %{private}s",
283         StatsUtils::ConvertStatsType(statsType).c_str(), uid, state, level, deviceId.c_str());
284     if (uid > StatsUtils::INVALID_VALUE) {
285         uidEntity_->UpdateUidMap(uid);
286     }
287 
288     switch (statsType) {
289         case StatsUtils::STATS_TYPE_SCREEN_ON:
290         case StatsUtils::STATS_TYPE_SCREEN_BRIGHTNESS:
291             UpdateScreenStats(statsType, state, level);
292             break;
293         case StatsUtils::STATS_TYPE_CAMERA_ON:
294         case StatsUtils::STATS_TYPE_CAMERA_FLASHLIGHT_ON:
295             UpdateCameraStats(statsType, state, uid, deviceId);
296             break;
297         case StatsUtils::STATS_TYPE_PHONE_ACTIVE:
298         case StatsUtils::STATS_TYPE_PHONE_DATA:
299             UpdatePhoneStats(statsType, state, level);
300             break;
301         case StatsUtils::STATS_TYPE_BLUETOOTH_BR_ON:
302         case StatsUtils::STATS_TYPE_BLUETOOTH_BLE_ON:
303         case StatsUtils::STATS_TYPE_WIFI_ON:
304         case StatsUtils::STATS_TYPE_BLUETOOTH_BR_SCAN:
305         case StatsUtils::STATS_TYPE_BLUETOOTH_BLE_SCAN:
306             UpdateConnectivityStats(statsType, state, uid);
307             break;
308         case StatsUtils::STATS_TYPE_FLASHLIGHT_ON:
309         case StatsUtils::STATS_TYPE_GNSS_ON:
310         case StatsUtils::STATS_TYPE_SENSOR_GRAVITY_ON:
311         case StatsUtils::STATS_TYPE_SENSOR_PROXIMITY_ON:
312         case StatsUtils::STATS_TYPE_AUDIO_ON:
313         case StatsUtils::STATS_TYPE_WAKELOCK_HOLD:
314             UpdateCommonStats(statsType, state, uid);
315             break;
316         default:
317             break;
318     }
319 }
320 
UpdateScreenStats(StatsUtils::StatsType statsType,StatsUtils::StatsState state,int16_t level)321 void BatteryStatsCore::UpdateScreenStats(StatsUtils::StatsType statsType, StatsUtils::StatsState state, int16_t level)
322 {
323     STATS_HILOGD(COMP_SVC,
324         "statsType: %{public}s, state: %{public}d, level: %{public}d, last brightness level: %{public}d",
325         StatsUtils::ConvertStatsType(statsType).c_str(), state, level, lastBrightnessLevel_);
326     if (statsType == StatsUtils::STATS_TYPE_SCREEN_ON) {
327         UpdateScreenTimer(state);
328     } else if (statsType == StatsUtils::STATS_TYPE_SCREEN_BRIGHTNESS) {
329         if (!isScreenOn_) {
330             STATS_HILOGW(COMP_SVC, "Screen is off, return");
331             return;
332         }
333         UpdateBrightnessTimer(state, level);
334     }
335 }
336 
UpdateCameraStats(StatsUtils::StatsType statsType,StatsUtils::StatsState state,int32_t uid,const std::string & deviceId)337 void BatteryStatsCore::UpdateCameraStats(StatsUtils::StatsType statsType, StatsUtils::StatsState state,
338     int32_t uid, const std::string& deviceId)
339 {
340     STATS_HILOGD(COMP_SVC, "Camera status: %{public}d, Last camera uid: %{public}d", isCameraOn_, lastCameraUid_);
341     if (statsType == StatsUtils::STATS_TYPE_CAMERA_ON) {
342         if (state == StatsUtils::STATS_STATE_ACTIVATED) {
343             if (isCameraOn_) {
344                 STATS_HILOGW(COMP_SVC, "Camera is already opened, return");
345                 return;
346             }
347             UpdateCameraTimer(state, uid, deviceId);
348         } else if (state == StatsUtils::STATS_STATE_DEACTIVATED) {
349             if (!isCameraOn_) {
350                 STATS_HILOGW(COMP_SVC, "Camera is off, return");
351                 return;
352             }
353             UpdateCameraTimer(state, lastCameraUid_, deviceId);
354         }
355     } else if (statsType == StatsUtils::STATS_TYPE_CAMERA_FLASHLIGHT_ON) {
356         if (!isCameraOn_) {
357             STATS_HILOGW(COMP_SVC, "Camera is off, return");
358             return;
359         }
360         UpdateTimer(flashlightEntity_, StatsUtils::STATS_TYPE_FLASHLIGHT_ON, state, lastCameraUid_);
361     }
362 }
363 
UpdatePhoneStats(StatsUtils::StatsType statsType,StatsUtils::StatsState state,int16_t level)364 void BatteryStatsCore::UpdatePhoneStats(StatsUtils::StatsType statsType, StatsUtils::StatsState state, int16_t level)
365 {
366     STATS_HILOGD(COMP_SVC, "statsType: %{public}s, state: %{public}d, level: %{public}d",
367         StatsUtils::ConvertStatsType(statsType).c_str(), state, level);
368     std::shared_ptr<StatsHelper::ActiveTimer> timer;
369     timer = phoneEntity_->GetOrCreateTimer(statsType, level);
370     if (timer == nullptr) {
371         STATS_HILOGW(COMP_SVC, "Timer is null, return");
372         return;
373     }
374 
375     switch (state) {
376         case StatsUtils::STATS_STATE_ACTIVATED:
377             timer->StartRunning();
378             break;
379         case StatsUtils::STATS_STATE_DEACTIVATED:
380             timer->StopRunning();
381             break;
382         default:
383             break;
384     }
385 }
386 
UpdateTimer(std::shared_ptr<BatteryStatsEntity> entity,StatsUtils::StatsType statsType,StatsUtils::StatsState state,int32_t uid)387 void BatteryStatsCore::UpdateTimer(std::shared_ptr<BatteryStatsEntity> entity, StatsUtils::StatsType statsType,
388     StatsUtils::StatsState state, int32_t uid)
389 {
390     STATS_HILOGD(COMP_SVC,
391         "entity: %{public}s, statsType: %{public}s, state: %{public}d, uid: %{public}d",
392         BatteryStatsInfo::ConvertConsumptionType(entity->GetConsumptionType()).c_str(),
393         StatsUtils::ConvertStatsType(statsType).c_str(),
394         state,
395         uid);
396     std::shared_ptr<StatsHelper::ActiveTimer> timer;
397     if (uid > StatsUtils::INVALID_VALUE) {
398         timer = entity->GetOrCreateTimer(uid, statsType);
399     } else {
400         timer = entity->GetOrCreateTimer(statsType);
401     }
402 
403     if (timer == nullptr) {
404         STATS_HILOGW(COMP_SVC, "Timer is null, return");
405         return;
406     }
407 
408     switch (state) {
409         case StatsUtils::STATS_STATE_ACTIVATED:
410             timer->StartRunning();
411             break;
412         case StatsUtils::STATS_STATE_DEACTIVATED:
413             timer->StopRunning();
414             break;
415         default:
416             break;
417     }
418 }
419 
UpdateTimer(std::shared_ptr<BatteryStatsEntity> entity,StatsUtils::StatsType statsType,int64_t time,int32_t uid)420 void BatteryStatsCore::UpdateTimer(std::shared_ptr<BatteryStatsEntity> entity, StatsUtils::StatsType statsType,
421     int64_t time, int32_t uid)
422 {
423     STATS_HILOGD(COMP_SVC,
424         "entity: %{public}s, statsType: %{public}s, time: %{public}" PRId64 ", uid: %{public}d",
425         BatteryStatsInfo::ConvertConsumptionType(entity->GetConsumptionType()).c_str(),
426         StatsUtils::ConvertStatsType(statsType).c_str(),
427         time,
428         uid);
429     std::shared_ptr<StatsHelper::ActiveTimer> timer;
430     if (uid > StatsUtils::INVALID_VALUE) {
431         timer = entity->GetOrCreateTimer(uid, statsType);
432     } else {
433         timer = entity->GetOrCreateTimer(statsType);
434     }
435 
436     if (timer == nullptr) {
437         STATS_HILOGW(COMP_SVC, "Timer is null, return");
438         return;
439     }
440     timer->AddRunningTimeMs(time);
441 }
442 
UpdateCameraTimer(StatsUtils::StatsState state,int32_t uid,const std::string & deviceId)443 void BatteryStatsCore::UpdateCameraTimer(StatsUtils::StatsState state, int32_t uid, const std::string& deviceId)
444 {
445     STATS_HILOGD(COMP_SVC, "Camera status: %{public}d, uid: %{public}d, deviceId: %{private}s",
446         state, uid, deviceId.c_str());
447     std::shared_ptr<StatsHelper::ActiveTimer> timer;
448     if (uid > StatsUtils::INVALID_VALUE && deviceId != "") {
449         timer = cameraEntity_->GetOrCreateTimer(deviceId, uid, StatsUtils::STATS_TYPE_CAMERA_ON);
450     } else {
451         timer = cameraEntity_->GetOrCreateTimer(StatsUtils::STATS_TYPE_CAMERA_ON);
452     }
453 
454     if (timer == nullptr) {
455         STATS_HILOGW(COMP_SVC, "Timer is null, return");
456         return;
457     }
458 
459     switch (state) {
460         case StatsUtils::STATS_STATE_ACTIVATED: {
461             if (timer->StartRunning()) {
462                 isCameraOn_ = true;
463                 lastCameraUid_ = uid;
464             }
465             break;
466         }
467         case StatsUtils::STATS_STATE_DEACTIVATED: {
468             if (timer->StopRunning()) {
469                 UpdateTimer(flashlightEntity_,
470                             StatsUtils::STATS_TYPE_FLASHLIGHT_ON,
471                             StatsUtils::STATS_STATE_DEACTIVATED,
472                             lastCameraUid_);
473                 isCameraOn_ = false;
474                 lastCameraUid_ = StatsUtils::INVALID_VALUE;
475             }
476             break;
477         }
478         default:
479             break;
480     }
481 }
482 
UpdateScreenTimer(StatsUtils::StatsState state)483 void BatteryStatsCore::UpdateScreenTimer(StatsUtils::StatsState state)
484 {
485     std::shared_ptr<StatsHelper::ActiveTimer> screenOnTimer = nullptr;
486     std::shared_ptr<StatsHelper::ActiveTimer> brightnessTimer = nullptr;
487     screenOnTimer = screenEntity_->GetOrCreateTimer(StatsUtils::STATS_TYPE_SCREEN_ON);
488     if (lastBrightnessLevel_ > StatsUtils::INVALID_VALUE) {
489         brightnessTimer = screenEntity_->GetOrCreateTimer(StatsUtils::STATS_TYPE_SCREEN_BRIGHTNESS,
490             lastBrightnessLevel_);
491     }
492     if (state == StatsUtils::STATS_STATE_ACTIVATED) {
493         screenOnTimer->StartRunning();
494         if (brightnessTimer != nullptr) {
495             brightnessTimer->StartRunning();
496         }
497         isScreenOn_ = true;
498     } else if (state == StatsUtils::STATS_STATE_DEACTIVATED) {
499         screenOnTimer->StopRunning();
500         if (brightnessTimer != nullptr) {
501             brightnessTimer->StopRunning();
502         }
503         isScreenOn_ = false;
504     }
505 }
506 
UpdateBrightnessTimer(StatsUtils::StatsState state,int16_t level)507 void BatteryStatsCore::UpdateBrightnessTimer(StatsUtils::StatsState state, int16_t level)
508 {
509     if (level <= StatsUtils::INVALID_VALUE || level > StatsUtils::SCREEN_BRIGHTNESS_BIN) {
510         STATS_HILOGW(COMP_SVC, "Screen brightness level is out of range");
511         return;
512     }
513 
514     if (lastBrightnessLevel_ <= StatsUtils::INVALID_VALUE ||
515         (level > StatsUtils::INVALID_VALUE && level == lastBrightnessLevel_)) {
516         auto brightnessTimer = screenEntity_->GetOrCreateTimer(StatsUtils::STATS_TYPE_SCREEN_BRIGHTNESS,
517             level);
518         brightnessTimer->StartRunning();
519     } else if (level != lastBrightnessLevel_) {
520         auto oldBrightnessTimer = screenEntity_->GetOrCreateTimer(StatsUtils::STATS_TYPE_SCREEN_BRIGHTNESS,
521             lastBrightnessLevel_);
522         auto newBrightnessTimer = screenEntity_->GetOrCreateTimer(StatsUtils::STATS_TYPE_SCREEN_BRIGHTNESS, level);
523         if (oldBrightnessTimer != nullptr) {
524             STATS_HILOGI(COMP_SVC, "Stop screen brightness timer for last level: %{public}d",
525                 lastBrightnessLevel_);
526             oldBrightnessTimer->StopRunning();
527         }
528         if (newBrightnessTimer != nullptr) {
529             STATS_HILOGI(COMP_SVC, "Start screen brightness timer for latest level: %{public}d", level);
530             newBrightnessTimer->StartRunning();
531         }
532     }
533     lastBrightnessLevel_ = level;
534 }
535 
UpdateCounter(std::shared_ptr<BatteryStatsEntity> entity,StatsUtils::StatsType statsType,int64_t data,int32_t uid)536 void BatteryStatsCore::UpdateCounter(std::shared_ptr<BatteryStatsEntity> entity, StatsUtils::StatsType statsType,
537     int64_t data, int32_t uid)
538 {
539     STATS_HILOGD(COMP_SVC,
540         "entity: %{public}s, statsType: %{public}s, data: %{public}" PRId64 ", uid: %{public}d",
541         BatteryStatsInfo::ConvertConsumptionType(entity->GetConsumptionType()).c_str(),
542         StatsUtils::ConvertStatsType(statsType).c_str(),
543         data,
544         uid);
545     std::shared_ptr<StatsHelper::Counter> counter;
546     if (uid > StatsUtils::INVALID_VALUE) {
547         counter = entity->GetOrCreateCounter(statsType, uid);
548     } else {
549         counter = entity->GetOrCreateCounter(statsType);
550     }
551 
552     if (counter == nullptr) {
553         STATS_HILOGW(COMP_SVC, "Counter is null, return");
554         return;
555     }
556     counter->AddCount(data);
557 }
558 
GetTotalTimeMs(StatsUtils::StatsType statsType,int16_t level)559 int64_t BatteryStatsCore::GetTotalTimeMs(StatsUtils::StatsType statsType, int16_t level)
560 {
561     STATS_HILOGD(COMP_SVC, "Handle statsType: %{public}s, level: %{public}d",
562         StatsUtils::ConvertStatsType(statsType).c_str(), level);
563     int64_t time = StatsUtils::DEFAULT_VALUE;
564     switch (statsType) {
565         case StatsUtils::STATS_TYPE_SCREEN_BRIGHTNESS:
566             time = screenEntity_->GetActiveTimeMs(statsType, level);
567             break;
568         case StatsUtils::STATS_TYPE_SCREEN_ON:
569             time = screenEntity_->GetActiveTimeMs(statsType);
570             break;
571         case StatsUtils::STATS_TYPE_BLUETOOTH_BR_ON:
572         case StatsUtils::STATS_TYPE_BLUETOOTH_BLE_ON:
573             time = bluetoothEntity_->GetActiveTimeMs(statsType);
574             break;
575         case StatsUtils::STATS_TYPE_WIFI_ON:
576             time = wifiEntity_->GetActiveTimeMs(statsType);
577             break;
578         case StatsUtils::STATS_TYPE_PHONE_ACTIVE:
579         case StatsUtils::STATS_TYPE_PHONE_DATA:
580             time = phoneEntity_->GetActiveTimeMs(statsType, level);
581             break;
582         case StatsUtils::STATS_TYPE_PHONE_IDLE:
583         case StatsUtils::STATS_TYPE_CPU_SUSPEND:
584             time = idleEntity_->GetActiveTimeMs(statsType);
585             break;
586         default:
587             break;
588     }
589     STATS_HILOGD(COMP_SVC, "Get active time: %{public}sms for %{public}s", std::to_string(time).c_str(),
590         StatsUtils::ConvertStatsType(statsType).c_str());
591     return time;
592 }
593 
DumpInfo(std::string & result)594 void BatteryStatsCore::DumpInfo(std::string& result)
595 {
596     result.append("BATTERY STATS DUMP:\n");
597     result.append("\n");
598     if (bluetoothEntity_) {
599         bluetoothEntity_->DumpInfo(result);
600         result.append("\n");
601     }
602     if (idleEntity_) {
603         idleEntity_->DumpInfo(result);
604         result.append("\n");
605     }
606     if (phoneEntity_) {
607         phoneEntity_->DumpInfo(result);
608         result.append("\n");
609     }
610     if (screenEntity_) {
611         screenEntity_->DumpInfo(result);
612         result.append("\n");
613     }
614     if (wifiEntity_) {
615         wifiEntity_->DumpInfo(result);
616         result.append("\n");
617     }
618     if (uidEntity_) {
619         uidEntity_->DumpInfo(result);
620         result.append("\n");
621     }
622     GetDebugInfo(result);
623 }
624 
UpdateDebugInfo(const std::string & info)625 void BatteryStatsCore::UpdateDebugInfo(const std::string& info)
626 {
627     debugInfo_.append(info);
628 }
629 
GetDebugInfo(std::string & result)630 void BatteryStatsCore::GetDebugInfo(std::string& result)
631 {
632     if (debugInfo_.size() > 0) {
633         result.append("Misc stats info dump:\n");
634         result.append(debugInfo_);
635     }
636 }
637 
GetTotalTimeMs(int32_t uid,StatsUtils::StatsType statsType,int16_t level)638 int64_t BatteryStatsCore::GetTotalTimeMs(int32_t uid, StatsUtils::StatsType statsType, int16_t level)
639 {
640     STATS_HILOGD(COMP_SVC, "Handle statsType: %{public}s, uid: %{public}d, level: %{public}d",
641         StatsUtils::ConvertStatsType(statsType).c_str(), uid, level);
642     int64_t time = StatsUtils::DEFAULT_VALUE;
643     switch (statsType) {
644         case StatsUtils::STATS_TYPE_BLUETOOTH_BR_SCAN:
645         case StatsUtils::STATS_TYPE_BLUETOOTH_BLE_SCAN:
646             time = bluetoothEntity_->GetActiveTimeMs(uid, statsType);
647             break;
648         case StatsUtils::STATS_TYPE_CAMERA_ON:
649             time = cameraEntity_->GetActiveTimeMs(uid, statsType);
650             break;
651         case StatsUtils::STATS_TYPE_FLASHLIGHT_ON:
652             time = flashlightEntity_->GetActiveTimeMs(uid, statsType);
653             break;
654         case StatsUtils::STATS_TYPE_GNSS_ON:
655             time = gnssEntity_->GetActiveTimeMs(uid, statsType);
656             break;
657         case StatsUtils::STATS_TYPE_SENSOR_GRAVITY_ON:
658             time = sensorEntity_->GetActiveTimeMs(uid, statsType);
659             break;
660         case StatsUtils::STATS_TYPE_SENSOR_PROXIMITY_ON:
661             time = sensorEntity_->GetActiveTimeMs(uid, statsType);
662             break;
663         case StatsUtils::STATS_TYPE_AUDIO_ON:
664             time = audioEntity_->GetActiveTimeMs(uid, statsType);
665             break;
666         case StatsUtils::STATS_TYPE_WAKELOCK_HOLD:
667             time = wakelockEntity_->GetActiveTimeMs(uid, statsType);
668             break;
669         case StatsUtils::STATS_TYPE_CPU_CLUSTER:
670         case StatsUtils::STATS_TYPE_CPU_SPEED:
671         case StatsUtils::STATS_TYPE_CPU_ACTIVE:
672             time = cpuEntity_->GetCpuTimeMs(uid);
673             break;
674         default:
675             break;
676     }
677     STATS_HILOGD(COMP_SVC, "Get active time: %{public}sms for %{public}s of uid: %{public}d",
678         std::to_string(time).c_str(), StatsUtils::ConvertStatsType(statsType).c_str(), uid);
679     return time;
680 }
681 
GetTotalDataCount(StatsUtils::StatsType statsType,int32_t uid)682 int64_t BatteryStatsCore::GetTotalDataCount(StatsUtils::StatsType statsType, int32_t uid)
683 {
684     STATS_HILOGD(COMP_SVC, "no traffic data bytes of %{public}s for uid: %{public}d",
685         StatsUtils::ConvertStatsType(statsType).c_str(), uid);
686     return StatsUtils::DEFAULT_VALUE;
687 }
688 
GetTotalConsumptionCount(StatsUtils::StatsType statsType,int32_t uid)689 int64_t BatteryStatsCore::GetTotalConsumptionCount(StatsUtils::StatsType statsType, int32_t uid)
690 {
691     int64_t data = StatsUtils::DEFAULT_VALUE;
692     switch (statsType) {
693         case StatsUtils::STATS_TYPE_WIFI_SCAN:
694             data = wifiEntity_->GetConsumptionCount(statsType, uid);
695             break;
696         case StatsUtils::STATS_TYPE_ALARM:
697             data = alarmEntity_->GetConsumptionCount(statsType, uid);
698             break;
699         default:
700             break;
701     }
702     STATS_HILOGD(COMP_SVC, "Get consumption count: %{public}" PRId64 " of %{public}s for uid: %{public}d",
703         data, StatsUtils::ConvertStatsType(statsType).c_str(), uid);
704     return data;
705 }
706 
GetAppStatsMah(const int32_t & uid)707 double BatteryStatsCore::GetAppStatsMah(const int32_t& uid)
708 {
709     std::lock_guard lock(mutex_);
710     double appStatsMah = StatsUtils::DEFAULT_VALUE;
711     auto statsInfoList = GetBatteryStats();
712     for (auto iter = statsInfoList.begin(); iter != statsInfoList.end(); iter++) {
713         if ((*iter)->GetConsumptionType() == BatteryStatsInfo::CONSUMPTION_TYPE_APP) {
714             if ((*iter)->GetUid() == uid) {
715                 appStatsMah = (*iter)->GetPower();
716                 break;
717             }
718         }
719     }
720     STATS_HILOGD(COMP_SVC, "Get stats mah: %{public}lf for uid: %{public}d", appStatsMah, uid);
721     return appStatsMah;
722 }
723 
GetAppStatsPercent(const int32_t & uid)724 double BatteryStatsCore::GetAppStatsPercent(const int32_t& uid)
725 {
726     double appStatsPercent = StatsUtils::DEFAULT_VALUE;
727     auto statsInfoList = GetBatteryStats();
728     auto totalConsumption = BatteryStatsEntity::GetTotalPowerMah();
729     if (totalConsumption <= StatsUtils::DEFAULT_VALUE) {
730         STATS_HILOGW(COMP_SVC, "No consumption got, return 0");
731         return appStatsPercent;
732     }
733     for (auto iter = statsInfoList.begin(); iter != statsInfoList.end(); iter++) {
734         if ((*iter)->GetConsumptionType() == BatteryStatsInfo::CONSUMPTION_TYPE_APP) {
735             if ((*iter)->GetUid() == uid && totalConsumption != StatsUtils::DEFAULT_VALUE) {
736                 appStatsPercent = (*iter)->GetPower() / totalConsumption;
737                 break;
738             }
739         }
740     }
741     STATS_HILOGD(COMP_SVC, "Get stats percent: %{public}lf for uid: %{public}d", appStatsPercent, uid);
742     return appStatsPercent;
743 }
744 
GetPartStatsMah(const BatteryStatsInfo::ConsumptionType & type)745 double BatteryStatsCore::GetPartStatsMah(const BatteryStatsInfo::ConsumptionType& type)
746 {
747     double partStatsMah = StatsUtils::DEFAULT_VALUE;
748     auto statsInfoList = GetBatteryStats();
749     for (auto iter = statsInfoList.begin(); iter != statsInfoList.end(); iter++) {
750         if ((*iter)->GetConsumptionType() == type) {
751             partStatsMah = (*iter)->GetPower();
752             break;
753         }
754     }
755     STATS_HILOGD(COMP_SVC, "Get stats mah: %{public}lf for type: %{public}d", partStatsMah, type);
756     return partStatsMah;
757 }
758 
GetPartStatsPercent(const BatteryStatsInfo::ConsumptionType & type)759 double BatteryStatsCore::GetPartStatsPercent(const BatteryStatsInfo::ConsumptionType& type)
760 {
761     double partStatsPercent = StatsUtils::DEFAULT_VALUE;
762     auto statsInfoList = GetBatteryStats();
763     auto totalConsumption = BatteryStatsEntity::GetTotalPowerMah();
764     for (auto iter = statsInfoList.begin(); iter != statsInfoList.end(); iter++) {
765         if ((*iter)->GetConsumptionType() == type && totalConsumption != StatsUtils::DEFAULT_VALUE) {
766             partStatsPercent = (*iter)->GetPower() / totalConsumption;
767             break;
768         }
769     }
770     STATS_HILOGD(COMP_SVC, "Get stats percent: %{public}lf for type: %{public}d", partStatsPercent, type);
771     return partStatsPercent;
772 }
773 
SaveForHardware(Json::Value & root)774 void BatteryStatsCore::SaveForHardware(Json::Value& root)
775 {
776     STATS_HILOGD(COMP_SVC, "Save hardware battery stats");
777     // Save for Bluetooth
778     root["Hardware"]["bluetooth_br_on"] =
779         Json::Value(GetTotalTimeMs(StatsUtils::STATS_TYPE_BLUETOOTH_BR_ON));
780     root["Hardware"]["bluetooth_ble_on"] =
781         Json::Value(GetTotalTimeMs(StatsUtils::STATS_TYPE_BLUETOOTH_BLE_ON));
782 
783     // Save for Screen
784     root["Hardware"]["screen_on"] =
785         Json::Value(GetTotalTimeMs(StatsUtils::STATS_TYPE_SCREEN_ON));
786     for (uint16_t brightNess = 0; brightNess <= StatsUtils::SCREEN_BRIGHTNESS_BIN; brightNess++) {
787         root["Hardware"]["screen_brightness"][brightNess] =
788             Json::Value(GetTotalTimeMs(StatsUtils::STATS_TYPE_SCREEN_BRIGHTNESS, brightNess));
789     }
790 
791     // Save for Wifi
792     root["Hardware"]["wifi_on"] =
793         Json::Value(GetTotalTimeMs(StatsUtils::STATS_TYPE_WIFI_ON));
794     root["Hardware"]["wifi_scan"] =
795         Json::Value(GetTotalConsumptionCount(StatsUtils::STATS_TYPE_WIFI_SCAN));
796 
797     // Save for CPU idle
798     root["Hardware"]["cpu_idle"] =
799         Json::Value(GetTotalTimeMs(StatsUtils::STATS_TYPE_PHONE_IDLE));
800 
801     // Save for Phone
802     for (uint16_t signalOn = 0; signalOn < StatsUtils::RADIO_SIGNAL_BIN; signalOn++) {
803         root["Hardware"]["radio_on"][signalOn] =
804             Json::Value(GetTotalTimeMs(StatsUtils::STATS_TYPE_PHONE_ACTIVE, signalOn));
805     }
806     for (uint16_t signalData = 0; signalData < StatsUtils::RADIO_SIGNAL_BIN; signalData++) {
807         root["Hardware"]["radio_data"][signalData] =
808             Json::Value(GetTotalTimeMs(StatsUtils::STATS_TYPE_PHONE_DATA, signalData));
809     }
810 }
811 
SaveForSoftware(Json::Value & root)812 void BatteryStatsCore::SaveForSoftware(Json::Value& root)
813 {
814     for (auto it : uidEntity_->GetUids()) {
815         SaveForSoftwareCommon(root, it);
816         SaveForSoftwareConnectivity(root, it);
817     }
818 }
819 
SaveForSoftwareCommon(Json::Value & root,int32_t uid)820 void BatteryStatsCore::SaveForSoftwareCommon(Json::Value& root, int32_t uid)
821 {
822     STATS_HILOGD(COMP_SVC, "Save software common battery stats, uid: %{public}d", uid);
823     std::string strUid = std::to_string(uid);
824     // Save for camera related
825     root["Software"][strUid]["camera_on"] =
826         Json::Value(GetTotalTimeMs(uid, StatsUtils::STATS_TYPE_CAMERA_ON));
827 
828     // Save for flashlight related
829     root["Software"][strUid]["flashlight_on"] =
830         Json::Value(GetTotalTimeMs(uid, StatsUtils::STATS_TYPE_FLASHLIGHT_ON));
831 
832     // Save for gnss related
833     root["Software"][strUid]["gnss_on"] =
834         Json::Value(GetTotalTimeMs(uid, StatsUtils::STATS_TYPE_GNSS_ON));
835 
836     // Save for audio related
837     root["Software"][strUid]["audio_on"] =
838         Json::Value(GetTotalTimeMs(uid, StatsUtils::STATS_TYPE_AUDIO_ON));
839 
840     // Save for wakelock related
841     root["Software"][strUid]["cpu_awake"] =
842         Json::Value(GetTotalTimeMs(uid, StatsUtils::STATS_TYPE_WAKELOCK_HOLD));
843 
844     // Save for sensor related
845     root["Software"][strUid]["sensor_gravity"] =
846         Json::Value(GetTotalTimeMs(uid, StatsUtils::STATS_TYPE_SENSOR_GRAVITY_ON));
847     root["Software"][strUid]["sensor_proximity"] =
848         Json::Value(GetTotalTimeMs(uid, StatsUtils::STATS_TYPE_SENSOR_PROXIMITY_ON));
849 
850     // Save for alarm related
851     root["Software"][strUid]["alarm"] =
852         Json::Value(GetTotalConsumptionCount(StatsUtils::STATS_TYPE_ALARM, uid));
853 
854     // Save for cpu related
855     root["Software"][strUid]["cpu_time"] = Json::Value(cpuEntity_->GetCpuTimeMs(uid));
856 }
857 
SaveForSoftwareConnectivity(Json::Value & root,int32_t uid)858 void BatteryStatsCore::SaveForSoftwareConnectivity(Json::Value& root, int32_t uid)
859 {
860     STATS_HILOGD(COMP_SVC, "Save software connectivity battery stats, uid: %{public}d", uid);
861     std::string strUid = std::to_string(uid);
862     // Save for Bluetooth related
863     root["Software"][strUid]["bluetooth_br_scan"] =
864         Json::Value(GetTotalTimeMs(uid, StatsUtils::STATS_TYPE_BLUETOOTH_BR_SCAN));
865     root["Software"][strUid]["bluetooth_ble_scan"] =
866         Json::Value(GetTotalTimeMs(uid, StatsUtils::STATS_TYPE_BLUETOOTH_BLE_SCAN));
867 }
868 
SaveForPower(Json::Value & root)869 void BatteryStatsCore::SaveForPower(Json::Value& root)
870 {
871     STATS_HILOGD(COMP_SVC, "Save power battery stats");
872     auto statsInfoList = BatteryStatsEntity::GetStatsInfoList();
873     for (auto iter = statsInfoList.begin(); iter != statsInfoList.end(); iter++) {
874         if ((*iter)->GetConsumptionType() == BatteryStatsInfo::CONSUMPTION_TYPE_APP) {
875             std::string name = std::to_string((*iter)->GetUid());
876             root["Power"][name] = Json::Value((*iter)->GetPower());
877             STATS_HILOGD(COMP_SVC, "Saved power: %{public}lf for uid: %{public}s", (*iter)->GetPower(),
878                 name.c_str());
879         } else if ((*iter)->GetConsumptionType() != BatteryStatsInfo::CONSUMPTION_TYPE_USER) {
880             std::string name = std::to_string((*iter)->GetConsumptionType());
881             root["Power"][name] = Json::Value((*iter)->GetPower());
882             STATS_HILOGD(COMP_SVC, "Saved power: %{public}lf for type: %{public}s", (*iter)->GetPower(),
883                 name.c_str());
884         }
885     }
886 }
887 
SaveBatteryStatsData()888 bool BatteryStatsCore::SaveBatteryStatsData()
889 {
890     ComputePower();
891     Json::Value root;
892 
893     // Save for power
894     SaveForPower(root);
895 
896     // Save for hardware
897     SaveForHardware(root);
898 
899     // Save for software
900     SaveForSoftware(root);
901 
902     Json::StreamWriterBuilder swb;
903     std::ofstream ofs;
904     ofs.open(BATTERY_STATS_JSON);
905     if (!ofs.is_open()) {
906         STATS_HILOGE(COMP_SVC, "Opening json file failed");
907         return false;
908     }
909     swb.newStreamWriter()->write(root, &ofs);
910     ofs.close();
911     return true;
912 }
913 
LoadBatteryStatsData()914 bool BatteryStatsCore::LoadBatteryStatsData()
915 {
916     Json::CharReaderBuilder reader;
917     Json::Value root;
918     std::string errors;
919     std::ifstream ifs(BATTERY_STATS_JSON, std::ios::binary);
920     if (!ifs.is_open()) {
921         STATS_HILOGE(COMP_SVC, "Json file doesn't exist");
922         return false;
923     }
924     if (!parseFromStream(reader, ifs, &root, &errors)) {
925         STATS_HILOGE(COMP_SVC, "Failed to parse the JSON file");
926         ifs.close();
927         return false;
928     }
929     ifs.close();
930     BatteryStatsEntity::ResetStatsEntity();
931     Json::Value::Members member = root["Power"].getMemberNames();
932     std::map<int32_t, double> tmpUserPowerMap;
933     for (auto iter = member.begin(); iter != member.end(); iter++) {
934         auto id = std::stoi(*iter);
935         int32_t usr = StatsUtils::INVALID_VALUE;
936         std::shared_ptr<BatteryStatsInfo> info = std::make_shared<BatteryStatsInfo>();
937         if (id > StatsUtils::INVALID_VALUE) {
938             info->SetUid(id);
939             info->SetConsumptioType(BatteryStatsInfo::CONSUMPTION_TYPE_APP);
940             info->SetPower(root["Power"][*iter].asDouble());
941             usr = AccountSA::OhosAccountKits::GetInstance().GetDeviceAccountIdByUID(id);
942             const auto& userPower = tmpUserPowerMap.find(usr);
943             if (userPower != tmpUserPowerMap.end()) {
944                 userPower->second += info->GetPower();
945             } else {
946                 tmpUserPowerMap.insert(std::pair<int32_t, double>(usr, info->GetPower()));
947             }
948         } else if (id < StatsUtils::INVALID_VALUE && id > BatteryStatsInfo::CONSUMPTION_TYPE_INVALID) {
949             info->SetUid(StatsUtils::INVALID_VALUE);
950             info->SetConsumptioType(static_cast<BatteryStatsInfo::ConsumptionType>(id));
951             info->SetPower(root["Power"][*iter].asDouble());
952         }
953         STATS_HILOGD(COMP_SVC, "Load power:%{public}lfmAh,id:%{public}d,user:%{public}d", info->GetPower(), id, usr);
954         BatteryStatsEntity::UpdateStatsInfoList(info);
955     }
956     for (auto& iter : tmpUserPowerMap) {
957         std::shared_ptr<BatteryStatsInfo> statsInfo = std::make_shared<BatteryStatsInfo>();
958         statsInfo->SetConsumptioType(BatteryStatsInfo::CONSUMPTION_TYPE_USER);
959         statsInfo->SetUserId(iter.first);
960         statsInfo->SetPower(iter.second);
961         BatteryStatsEntity::UpdateStatsInfoList(statsInfo);
962     }
963     return true;
964 }
965 
Reset()966 void BatteryStatsCore::Reset()
967 {
968     std::lock_guard lock(mutex_);
969     audioEntity_->Reset();
970     bluetoothEntity_->Reset();
971     cameraEntity_->Reset();
972     cpuEntity_->Reset();
973     flashlightEntity_->Reset();
974     gnssEntity_->Reset();
975     idleEntity_->Reset();
976     phoneEntity_->Reset();
977     screenEntity_->Reset();
978     sensorEntity_->Reset();
979     uidEntity_->Reset();
980     userEntity_->Reset();
981     wifiEntity_->Reset();
982     wakelockEntity_->Reset();
983     alarmEntity_->Reset();
984     BatteryStatsEntity::ResetStatsEntity();
985     debugInfo_.clear();
986 }
987 } // namespace PowerMgr
988 } // namespace OHOS
989