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