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