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