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