1 /*
2 * Copyright (c) 2021-2023 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
16 #include "battery_stats_service.h"
17
18 #include <file_ex.h>
19 #include <cmath>
20 #include <ipc_skeleton.h>
21
22 #include "common_event_data.h"
23 #include "common_event_manager.h"
24 #include "common_event_subscribe_info.h"
25 #include "common_event_support.h"
26 #include "hisysevent.h"
27 #include "hisysevent_manager.h"
28 #include "if_system_ability_manager.h"
29 #include "iservice_registry.h"
30 #include "permission.h"
31 #include "sysparam.h"
32 #include "system_ability_definition.h"
33 #include "xcollie/watchdog.h"
34
35 #include "battery_stats_dumper.h"
36 #include "battery_stats_listener.h"
37 #include "battery_stats_subscriber.h"
38 #include "stats_common.h"
39 #include "stats_hisysevent.h"
40 #include "stats_xcollie.h"
41
42 namespace OHOS {
43 namespace PowerMgr {
44 sptr<BatteryStatsService> BatteryStatsService::instance_ = nullptr;
45 std::mutex BatteryStatsService::singletonMutex_;
46 namespace {
47 auto g_statsService = BatteryStatsService::GetInstance();
48 const bool G_REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(g_statsService.GetRefPtr());
49 SysParam::BootCompletedCallback g_bootCompletedCallback;
50 }
51 std::atomic_bool BatteryStatsService::isBootCompleted_ = false;
52
BatteryStatsService()53 BatteryStatsService::BatteryStatsService() : SystemAbility(POWER_MANAGER_BATT_STATS_SERVICE_ID, true) {}
54
~BatteryStatsService()55 BatteryStatsService::~BatteryStatsService() {}
56
GetInstance()57 sptr<BatteryStatsService> BatteryStatsService::GetInstance()
58 {
59 if (instance_ == nullptr) {
60 std::lock_guard<std::mutex> lock(singletonMutex_);
61 if (instance_ == nullptr) {
62 instance_ = new BatteryStatsService();
63 }
64 }
65 return instance_;
66 }
67
OnStart()68 void BatteryStatsService::OnStart()
69 {
70 if (ready_) {
71 STATS_HILOGI(COMP_SVC, "OnStart is ready, nothing to do");
72 return;
73 }
74 if (!(Init())) {
75 STATS_HILOGE(COMP_SVC, "Call init failed");
76 return;
77 }
78 AddSystemAbilityListener(DFX_SYS_EVENT_SERVICE_ABILITY_ID);
79 AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
80 if (!Publish(BatteryStatsService::GetInstance())) {
81 STATS_HILOGE(COMP_SVC, "OnStart register to system ability manager failed");
82 return;
83 }
84 RegisterBootCompletedCallback();
85 ready_ = true;
86 }
87
OnStop()88 void BatteryStatsService::OnStop()
89 {
90 if (!ready_) {
91 STATS_HILOGI(COMP_SVC, "OnStop is not ready, nothing to do");
92 return;
93 }
94 ready_ = false;
95 isBootCompleted_ = false;
96 RemoveSystemAbilityListener(DFX_SYS_EVENT_SERVICE_ABILITY_ID);
97 RemoveSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
98 HiviewDFX::HiSysEventManager::RemoveListener(listenerPtr_);
99 if (!OHOS::EventFwk::CommonEventManager::UnSubscribeCommonEvent(subscriberPtr_)) {
100 STATS_HILOGE(COMP_SVC, "OnStart unregister to commonevent manager failed");
101 }
102 }
103
RegisterBootCompletedCallback()104 void BatteryStatsService::RegisterBootCompletedCallback()
105 {
106 g_bootCompletedCallback = []() {
107 isBootCompleted_ = true;
108 };
109 SysParam::RegisterBootCompletedCallback(g_bootCompletedCallback);
110 }
111
112
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)113 void BatteryStatsService::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
114 {
115 STATS_HILOGI(COMP_SVC, "systemAbilityId=%{public}d, deviceId=%{private}s", systemAbilityId, deviceId.c_str());
116 if (systemAbilityId == DFX_SYS_EVENT_SERVICE_ABILITY_ID) {
117 AddHiSysEventListener();
118 }
119 if (systemAbilityId == COMMON_EVENT_SERVICE_ID) {
120 SubscribeCommonEvent();
121 }
122 }
123
Init()124 bool BatteryStatsService::Init()
125 {
126 if (parser_ == nullptr) {
127 parser_ = std::make_shared<BatteryStatsParser>();
128 if (!parser_->Init()) {
129 STATS_HILOGE(COMP_SVC, "Battery stats parser initialization failed");
130 return false;
131 }
132 }
133
134 if (core_ == nullptr) {
135 core_ = std::make_shared<BatteryStatsCore>();
136 if (!core_->Init()) {
137 STATS_HILOGE(COMP_SVC, "Battery stats core initialization failed");
138 return false;
139 }
140 }
141
142 if (detector_ == nullptr) {
143 detector_ = std::make_shared<BatteryStatsDetector>();
144 }
145
146 return true;
147 }
148
SubscribeCommonEvent()149 bool BatteryStatsService::SubscribeCommonEvent()
150 {
151 using namespace OHOS::EventFwk;
152 bool result = false;
153 MatchingSkills matchingSkills;
154 matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_SHUTDOWN);
155 matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_BATTERY_CHANGED);
156 CommonEventSubscribeInfo subscribeInfo(matchingSkills);
157 subscribeInfo.SetThreadMode(CommonEventSubscribeInfo::ThreadMode::COMMON);
158 if (!subscriberPtr_) {
159 subscriberPtr_ = std::make_shared<BatteryStatsSubscriber>(subscribeInfo);
160 }
161 result = CommonEventManager::SubscribeCommonEvent(subscriberPtr_);
162 if (!result) {
163 STATS_HILOGE(COMP_SVC, "Subscribe CommonEvent failed");
164 }
165 return result;
166 }
167
AddHiSysEventListener()168 bool BatteryStatsService::AddHiSysEventListener()
169 {
170 if (!listenerPtr_) {
171 OHOS::EventFwk::CommonEventSubscribeInfo info;
172 listenerPtr_ = std::make_shared<BatteryStatsListener>();
173 }
174 OHOS::HiviewDFX::ListenerRule statsRule("PowerStats");
175 OHOS::HiviewDFX::ListenerRule distSchedRule("DISTSCHEDULE", StatsHiSysEvent::START_REMOTE_ABILITY);
176 std::vector<OHOS::HiviewDFX::ListenerRule> sysRules;
177 sysRules.push_back(statsRule);
178 sysRules.push_back(distSchedRule);
179 auto res = HiviewDFX::HiSysEventManager::AddListener(listenerPtr_, sysRules);
180 if (res != 0) {
181 STATS_HILOGE(COMP_SVC, "Listener added failed");
182 }
183 return res;
184 }
185
IsServiceReady() const186 bool BatteryStatsService::IsServiceReady() const
187 {
188 return ready_;
189 }
190
GetBatteryStats()191 BatteryStatsInfoList BatteryStatsService::GetBatteryStats()
192 {
193 std::lock_guard lock(mutex_);
194 BatteryStatsInfoList statsInfoList = {};
195 if (!Permission::IsSystem()) {
196 lastError_ = StatsError::ERR_SYSTEM_API_DENIED;
197 return statsInfoList;
198 }
199 core_->ComputePower();
200 statsInfoList = core_->GetBatteryStats();
201 return statsInfoList;
202 }
203
Dump(int32_t fd,const std::vector<std::u16string> & args)204 int32_t BatteryStatsService::Dump(int32_t fd, const std::vector<std::u16string>& args)
205 {
206 if (!isBootCompleted_) {
207 return ERR_NO_INIT;
208 }
209 if (!Permission::IsSystem()) {
210 return ERR_PERMISSION_DENIED;
211 }
212 std::lock_guard lock(mutex_);
213 std::vector<std::string> argsInStr;
214 std::transform(args.begin(), args.end(), std::back_inserter(argsInStr),
215 [](const std::u16string &arg) {
216 std::string ret = Str16ToStr8(arg);
217 STATS_HILOGD(COMP_SVC, "arg: %{public}s", ret.c_str());
218 return ret;
219 });
220 std::string result;
221 BatteryStatsDumper::Dump(argsInStr, result);
222 if (!SaveStringToFd(fd, result)) {
223 STATS_HILOGE(COMP_SVC, "Dump save to fd failed, %{public}s", result.c_str());
224 return ERR_OK;
225 }
226 return ERR_OK;
227 }
228
GetAppStatsMah(const int32_t & uid)229 double BatteryStatsService::GetAppStatsMah(const int32_t& uid)
230 {
231 std::lock_guard lock(mutex_);
232 if (!Permission::IsSystem()) {
233 lastError_ = StatsError::ERR_SYSTEM_API_DENIED;
234 return StatsUtils::DEFAULT_VALUE;
235 }
236 core_->ComputePower();
237 return core_->GetAppStatsMah(uid);
238 }
239
GetAppStatsPercent(const int32_t & uid)240 double BatteryStatsService::GetAppStatsPercent(const int32_t& uid)
241 {
242 std::lock_guard lock(mutex_);
243 if (!Permission::IsSystem()) {
244 lastError_ = StatsError::ERR_SYSTEM_API_DENIED;
245 return StatsUtils::DEFAULT_VALUE;
246 }
247 core_->ComputePower();
248 return core_->GetAppStatsPercent(uid);
249 }
250
GetPartStatsMah(const BatteryStatsInfo::ConsumptionType & type)251 double BatteryStatsService::GetPartStatsMah(const BatteryStatsInfo::ConsumptionType& type)
252 {
253 std::lock_guard lock(mutex_);
254 if (!Permission::IsSystem()) {
255 lastError_ = StatsError::ERR_SYSTEM_API_DENIED;
256 return StatsUtils::DEFAULT_VALUE;
257 }
258 core_->ComputePower();
259 return core_->GetPartStatsMah(type);
260 }
261
GetPartStatsPercent(const BatteryStatsInfo::ConsumptionType & type)262 double BatteryStatsService::GetPartStatsPercent(const BatteryStatsInfo::ConsumptionType& type)
263 {
264 std::lock_guard lock(mutex_);
265 if (!Permission::IsSystem()) {
266 lastError_ = StatsError::ERR_SYSTEM_API_DENIED;
267 return StatsUtils::DEFAULT_VALUE;
268 }
269 core_->ComputePower();
270 return core_->GetPartStatsPercent(type);
271 }
272
GetTotalTimeSecond(const StatsUtils::StatsType & statsType,const int32_t & uid)273 uint64_t BatteryStatsService::GetTotalTimeSecond(const StatsUtils::StatsType& statsType, const int32_t& uid)
274 {
275 if (!Permission::IsSystem()) {
276 lastError_ = StatsError::ERR_SYSTEM_API_DENIED;
277 return ERR_OK;
278 }
279 STATS_HILOGD(COMP_SVC, "statsType: %{public}d, uid: %{public}d", statsType, uid);
280 uint64_t timeSecond;
281 if (uid > StatsUtils::INVALID_VALUE) {
282 double timeMs = static_cast<double>(core_->GetTotalTimeMs(uid, statsType));
283 timeSecond = round(timeMs / StatsUtils::MS_IN_SECOND);
284 } else {
285 double timeMs = static_cast<double>(core_->GetTotalTimeMs(statsType));
286 timeSecond = round(timeMs / StatsUtils::MS_IN_SECOND);
287 }
288 return timeSecond;
289 }
290
GetTotalDataBytes(const StatsUtils::StatsType & statsType,const int32_t & uid)291 uint64_t BatteryStatsService::GetTotalDataBytes(const StatsUtils::StatsType& statsType, const int32_t& uid)
292 {
293 if (!Permission::IsSystem()) {
294 lastError_ = StatsError::ERR_SYSTEM_API_DENIED;
295 return ERR_OK;
296 }
297 return core_->GetTotalDataCount(statsType, uid);
298 }
299
Reset()300 void BatteryStatsService::Reset()
301 {
302 if (!Permission::IsSystem()) {
303 return;
304 }
305 core_->Reset();
306 }
307
GetBatteryStatsCore() const308 std::shared_ptr<BatteryStatsCore> BatteryStatsService::GetBatteryStatsCore() const
309 {
310 return core_;
311 }
312
GetBatteryStatsParser() const313 std::shared_ptr<BatteryStatsParser> BatteryStatsService::GetBatteryStatsParser() const
314 {
315 return parser_;
316 }
317
GetBatteryStatsDetector() const318 std::shared_ptr<BatteryStatsDetector> BatteryStatsService::GetBatteryStatsDetector() const
319 {
320 return detector_;
321 }
322
SetOnBattery(bool isOnBattery)323 void BatteryStatsService::SetOnBattery(bool isOnBattery)
324 {
325 if (!Permission::IsSystem()) {
326 return;
327 }
328 StatsHelper::SetOnBattery(isOnBattery);
329 }
330
ShellDump(const std::vector<std::string> & args,uint32_t argc)331 std::string BatteryStatsService::ShellDump(const std::vector<std::string>& args, uint32_t argc)
332 {
333 if (!Permission::IsSystem()|| !isBootCompleted_) {
334 return "";
335 }
336 std::lock_guard lock(mutex_);
337 pid_t pid = IPCSkeleton::GetCallingPid();
338 std::string result;
339 bool ret = BatteryStatsDumper::Dump(args, result);
340 STATS_HILOGI(COMP_SVC, "PID: %{public}d, Dump result :%{public}d", pid, ret);
341 return result;
342 }
343
GetBatteryStatsIpc(ParcelableBatteryStatsList & batteryStats,int32_t & tempError)344 int32_t BatteryStatsService::GetBatteryStatsIpc(ParcelableBatteryStatsList& batteryStats, int32_t& tempError)
345 {
346 StatsXCollie statsXCollie("BatteryStatsService::GetBatteryStatsIpc", false);
347 batteryStats.statsList_ = GetBatteryStats();
348 tempError = static_cast<int32_t>(lastError_);
349 lastError_ = StatsError::ERR_OK;
350 return ERR_OK;
351 }
352
GetAppStatsMahIpc(int32_t uid,double & appStatsMah,int32_t & tempError)353 int32_t BatteryStatsService::GetAppStatsMahIpc(int32_t uid, double& appStatsMah, int32_t& tempError)
354 {
355 StatsXCollie statsXCollie("BatteryStatsService::GetAppStatsMahIpc", false);
356 appStatsMah = GetAppStatsMah(uid);
357 tempError = static_cast<int32_t>(lastError_);
358 lastError_ = StatsError::ERR_OK;
359 return ERR_OK;
360 }
361
GetAppStatsPercentIpc(int32_t uid,double & appStatsPercent,int32_t & tempError)362 int32_t BatteryStatsService::GetAppStatsPercentIpc(int32_t uid, double& appStatsPercent, int32_t& tempError)
363 {
364 StatsXCollie statsXCollie("BatteryStatsService::GetAppStatsPercentIpc", false);
365 appStatsPercent = GetAppStatsPercent(uid);
366 tempError = static_cast<int32_t>(lastError_);
367 lastError_ = StatsError::ERR_OK;
368 return ERR_OK;
369 }
370
GetPartStatsMahIpc(int32_t type,double & partStatsMah,int32_t & tempError)371 int32_t BatteryStatsService::GetPartStatsMahIpc(int32_t type, double& partStatsMah, int32_t& tempError)
372 {
373 StatsXCollie statsXCollie("BatteryStatsService::GetPartStatsMahIpc", false);
374 partStatsMah = GetPartStatsMah(static_cast<BatteryStatsInfo::ConsumptionType>(type));
375 tempError = static_cast<int32_t>(lastError_);
376 lastError_ = StatsError::ERR_OK;
377 return ERR_OK;
378 }
379
GetPartStatsPercentIpc(int32_t type,double & partStatsPercent,int32_t & tempError)380 int32_t BatteryStatsService::GetPartStatsPercentIpc(int32_t type, double& partStatsPercent, int32_t& tempError)
381 {
382 StatsXCollie statsXCollie("BatteryStatsService::GetPartStatsPercentIpc", false);
383 partStatsPercent = GetPartStatsPercent(static_cast<BatteryStatsInfo::ConsumptionType>(type));
384 tempError = static_cast<int32_t>(lastError_);
385 lastError_ = StatsError::ERR_OK;
386 return ERR_OK;
387 }
388
GetTotalTimeSecondIpc(int32_t statsType,int32_t uid,uint64_t & totalTimeSecond)389 int32_t BatteryStatsService::GetTotalTimeSecondIpc(int32_t statsType, int32_t uid, uint64_t& totalTimeSecond)
390 {
391 StatsXCollie statsXCollie("BatteryStatsService::GetTotalTimeSecondIpc", false);
392 totalTimeSecond = GetTotalTimeSecond(static_cast<StatsUtils::StatsType>(statsType), uid);
393 return ERR_OK;
394 }
395
GetTotalDataBytesIpc(int32_t statsType,int32_t uid,uint64_t & totalDataBytes)396 int32_t BatteryStatsService::GetTotalDataBytesIpc(int32_t statsType, int32_t uid, uint64_t& totalDataBytes)
397 {
398 StatsXCollie statsXCollie("BatteryStatsService::GetTotalDataBytesIpc", false);
399 totalDataBytes = GetTotalDataBytes(static_cast<StatsUtils::StatsType>(statsType), uid);
400 return ERR_OK;
401 }
402
ResetIpc()403 int32_t BatteryStatsService::ResetIpc()
404 {
405 StatsXCollie statsXCollie("BatteryStatsService::ResetIpc", false);
406 Reset();
407 return ERR_OK;
408 }
409
SetOnBatteryIpc(bool isOnBattery)410 int32_t BatteryStatsService::SetOnBatteryIpc(bool isOnBattery)
411 {
412 StatsXCollie statsXCollie("BatteryStatsService::SetOnBatteryIpc", false);
413 SetOnBattery(isOnBattery);
414 return ERR_OK;
415 }
416
ShellDumpIpc(const std::vector<std::string> & args,uint32_t argc,std::string & dumpShell)417 int32_t BatteryStatsService::ShellDumpIpc(const std::vector<std::string>& args, uint32_t argc, std::string& dumpShell)
418 {
419 StatsXCollie statsXCollie("BatteryStatsService::ShellDumpIpc", false);
420 dumpShell = ShellDump(args, argc);
421 return ERR_OK;
422 }
423
DestroyInstance()424 void BatteryStatsService::DestroyInstance()
425 {
426 std::lock_guard<std::mutex> lock(singletonMutex_);
427 if (instance_) {
428 instance_.clear();
429 instance_ = nullptr;
430 }
431 }
432 } // namespace PowerMgr
433 } // namespace OHOS
434