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