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
41 namespace OHOS {
42 namespace PowerMgr {
43 sptr<BatteryStatsService> BatteryStatsService::instance_ = nullptr;
44 std::mutex BatteryStatsService::singletonMutex_;
45 namespace {
46 auto g_statsService = BatteryStatsService::GetInstance();
47 const bool G_REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(g_statsService.GetRefPtr());
48 SysParam::BootCompletedCallback g_bootCompletedCallback;
49 }
50 std::atomic_bool BatteryStatsService::isBootCompleted_ = false;
51
BatteryStatsService()52 BatteryStatsService::BatteryStatsService() : SystemAbility(POWER_MANAGER_BATT_STATS_SERVICE_ID, true) {}
53
~BatteryStatsService()54 BatteryStatsService::~BatteryStatsService() {}
55
GetInstance()56 sptr<BatteryStatsService> BatteryStatsService::GetInstance()
57 {
58 if (instance_ == nullptr) {
59 std::lock_guard<std::mutex> lock(singletonMutex_);
60 if (instance_ == nullptr) {
61 instance_ = new BatteryStatsService();
62 }
63 }
64 return instance_;
65 }
66
OnStart()67 void BatteryStatsService::OnStart()
68 {
69 if (ready_) {
70 STATS_HILOGI(COMP_SVC, "OnStart is ready, nothing to do");
71 return;
72 }
73 if (!(Init())) {
74 STATS_HILOGE(COMP_SVC, "Call init failed");
75 return;
76 }
77 AddSystemAbilityListener(DFX_SYS_EVENT_SERVICE_ABILITY_ID);
78 AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
79 if (!Publish(BatteryStatsService::GetInstance())) {
80 STATS_HILOGE(COMP_SVC, "OnStart register to system ability manager failed");
81 return;
82 }
83 RegisterBootCompletedCallback();
84 ready_ = true;
85 }
86
OnStop()87 void BatteryStatsService::OnStop()
88 {
89 if (!ready_) {
90 STATS_HILOGI(COMP_SVC, "OnStop is not ready, nothing to do");
91 return;
92 }
93 ready_ = false;
94 isBootCompleted_ = false;
95 RemoveSystemAbilityListener(DFX_SYS_EVENT_SERVICE_ABILITY_ID);
96 RemoveSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
97 HiviewDFX::HiSysEventManager::RemoveListener(listenerPtr_);
98 if (!OHOS::EventFwk::CommonEventManager::UnSubscribeCommonEvent(subscriberPtr_)) {
99 STATS_HILOGE(COMP_SVC, "OnStart unregister to commonevent manager failed");
100 }
101 }
102
RegisterBootCompletedCallback()103 void BatteryStatsService::RegisterBootCompletedCallback()
104 {
105 g_bootCompletedCallback = []() {
106 isBootCompleted_ = true;
107 };
108 SysParam::RegisterBootCompletedCallback(g_bootCompletedCallback);
109 }
110
111
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)112 void BatteryStatsService::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
113 {
114 STATS_HILOGI(COMP_SVC, "systemAbilityId=%{public}d, deviceId=%{private}s", systemAbilityId,
115 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 0;
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 0;
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
GetLastError()344 StatsError BatteryStatsService::GetLastError()
345 {
346 StatsError tmpError = lastError_;
347 lastError_ = StatsError::ERR_OK;
348 return tmpError;
349 }
350
DestroyInstance()351 void BatteryStatsService::DestroyInstance()
352 {
353 std::lock_guard<std::mutex> lock(singletonMutex_);
354 if (instance_) {
355 instance_.clear();
356 instance_ = nullptr;
357 }
358 }
359 } // namespace PowerMgr
360 } // namespace OHOS
361