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 namespace {
44 auto g_statsService = DelayedStatsSpSingleton<BatteryStatsService>::GetInstance();
45 const bool G_REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(g_statsService.GetRefPtr());
46 SysParam::BootCompletedCallback g_bootCompletedCallback;
47 }
48 std::atomic_bool BatteryStatsService::isBootCompleted_ = false;
49
BatteryStatsService()50 BatteryStatsService::BatteryStatsService() : SystemAbility(POWER_MANAGER_BATT_STATS_SERVICE_ID, true) {}
51
~BatteryStatsService()52 BatteryStatsService::~BatteryStatsService() {}
53
OnStart()54 void BatteryStatsService::OnStart()
55 {
56 if (ready_) {
57 STATS_HILOGI(COMP_SVC, "OnStart is ready, nothing to do");
58 return;
59 }
60 if (!(Init())) {
61 STATS_HILOGE(COMP_SVC, "Call init failed");
62 return;
63 }
64 AddSystemAbilityListener(DFX_SYS_EVENT_SERVICE_ABILITY_ID);
65 AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
66 if (!Publish(DelayedStatsSpSingleton<BatteryStatsService>::GetInstance())) {
67 STATS_HILOGE(COMP_SVC, "OnStart register to system ability manager failed");
68 return;
69 }
70 RegisterBootCompletedCallback();
71 ready_ = true;
72 }
73
OnStop()74 void BatteryStatsService::OnStop()
75 {
76 if (!ready_) {
77 STATS_HILOGI(COMP_SVC, "OnStop is not ready, nothing to do");
78 return;
79 }
80 ready_ = false;
81 isBootCompleted_ = false;
82 RemoveSystemAbilityListener(DFX_SYS_EVENT_SERVICE_ABILITY_ID);
83 RemoveSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
84 HiviewDFX::HiSysEventManager::RemoveListener(listenerPtr_);
85 if (!OHOS::EventFwk::CommonEventManager::UnSubscribeCommonEvent(subscriberPtr_)) {
86 STATS_HILOGE(COMP_SVC, "OnStart unregister to commonevent manager failed");
87 }
88 }
89
RegisterBootCompletedCallback()90 void BatteryStatsService::RegisterBootCompletedCallback()
91 {
92 g_bootCompletedCallback = []() {
93 isBootCompleted_ = true;
94 };
95 SysParam::RegisterBootCompletedCallback(g_bootCompletedCallback);
96 }
97
98
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)99 void BatteryStatsService::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
100 {
101 STATS_HILOGI(COMP_SVC, "systemAbilityId=%{public}d, deviceId=%{private}s", systemAbilityId,
102 deviceId.c_str());
103 if (systemAbilityId == DFX_SYS_EVENT_SERVICE_ABILITY_ID) {
104 AddHiSysEventListener();
105 }
106 if (systemAbilityId == COMMON_EVENT_SERVICE_ID) {
107 SubscribeCommonEvent();
108 }
109 }
110
Init()111 bool BatteryStatsService::Init()
112 {
113 if (parser_ == nullptr) {
114 parser_ = std::make_shared<BatteryStatsParser>();
115 if (!parser_->Init()) {
116 STATS_HILOGE(COMP_SVC, "Battery stats parser initialization failed");
117 return false;
118 }
119 }
120
121 if (core_ == nullptr) {
122 core_ = std::make_shared<BatteryStatsCore>();
123 if (!core_->Init()) {
124 STATS_HILOGE(COMP_SVC, "Battery stats core initialization failed");
125 return false;
126 }
127 }
128
129 if (detector_ == nullptr) {
130 detector_ = std::make_shared<BatteryStatsDetector>();
131 }
132
133 return true;
134 }
135
SubscribeCommonEvent()136 bool BatteryStatsService::SubscribeCommonEvent()
137 {
138 using namespace OHOS::EventFwk;
139 bool result = false;
140 MatchingSkills matchingSkills;
141 matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_SHUTDOWN);
142 matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_BOOT_COMPLETED);
143 matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_BATTERY_CHANGED);
144 CommonEventSubscribeInfo subscribeInfo(matchingSkills);
145 subscribeInfo.SetThreadMode(CommonEventSubscribeInfo::ThreadMode::COMMON);
146 if (!subscriberPtr_) {
147 subscriberPtr_ = std::make_shared<BatteryStatsSubscriber>(subscribeInfo);
148 }
149 result = CommonEventManager::SubscribeCommonEvent(subscriberPtr_);
150 if (!result) {
151 STATS_HILOGE(COMP_SVC, "Subscribe CommonEvent failed");
152 }
153 return result;
154 }
155
AddHiSysEventListener()156 bool BatteryStatsService::AddHiSysEventListener()
157 {
158 if (!listenerPtr_) {
159 OHOS::EventFwk::CommonEventSubscribeInfo info;
160 listenerPtr_ = std::make_shared<BatteryStatsListener>();
161 }
162 OHOS::HiviewDFX::ListenerRule statsRule("PowerStats");
163 OHOS::HiviewDFX::ListenerRule distSchedRule("DISTSCHEDULE", StatsHiSysEvent::START_REMOTE_ABILITY);
164 std::vector<OHOS::HiviewDFX::ListenerRule> sysRules;
165 sysRules.push_back(statsRule);
166 sysRules.push_back(distSchedRule);
167 auto res = HiviewDFX::HiSysEventManager::AddListener(listenerPtr_, sysRules);
168 if (res != 0) {
169 STATS_HILOGE(COMP_SVC, "Listener added failed");
170 }
171 return res;
172 }
173
IsServiceReady() const174 bool BatteryStatsService::IsServiceReady() const
175 {
176 return ready_;
177 }
178
GetBatteryStats()179 BatteryStatsInfoList BatteryStatsService::GetBatteryStats()
180 {
181 std::lock_guard lock(mutex_);
182 BatteryStatsInfoList statsInfoList = {};
183 if (!Permission::IsSystem()) {
184 lastError_ = StatsError::ERR_SYSTEM_API_DENIED;
185 return statsInfoList;
186 }
187 core_->ComputePower();
188 statsInfoList = core_->GetBatteryStats();
189 return statsInfoList;
190 }
191
Dump(int32_t fd,const std::vector<std::u16string> & args)192 int32_t BatteryStatsService::Dump(int32_t fd, const std::vector<std::u16string>& args)
193 {
194 if (!isBootCompleted_) {
195 return ERR_NO_INIT;
196 }
197 if (!Permission::IsSystem()) {
198 return ERR_PERMISSION_DENIED;
199 }
200 std::lock_guard lock(mutex_);
201 std::vector<std::string> argsInStr;
202 std::transform(args.begin(), args.end(), std::back_inserter(argsInStr),
203 [](const std::u16string &arg) {
204 std::string ret = Str16ToStr8(arg);
205 STATS_HILOGD(COMP_SVC, "arg: %{public}s", ret.c_str());
206 return ret;
207 });
208 std::string result;
209 BatteryStatsDumper::Dump(argsInStr, result);
210 if (!SaveStringToFd(fd, result)) {
211 STATS_HILOGE(COMP_SVC, "Dump save to fd failed, %{public}s", result.c_str());
212 return ERR_OK;
213 }
214 return ERR_OK;
215 }
216
GetAppStatsMah(const int32_t & uid)217 double BatteryStatsService::GetAppStatsMah(const int32_t& uid)
218 {
219 std::lock_guard lock(mutex_);
220 if (!Permission::IsSystem()) {
221 lastError_ = StatsError::ERR_SYSTEM_API_DENIED;
222 return StatsUtils::DEFAULT_VALUE;
223 }
224 core_->ComputePower();
225 return core_->GetAppStatsMah(uid);
226 }
227
GetAppStatsPercent(const int32_t & uid)228 double BatteryStatsService::GetAppStatsPercent(const int32_t& uid)
229 {
230 std::lock_guard lock(mutex_);
231 if (!Permission::IsSystem()) {
232 lastError_ = StatsError::ERR_SYSTEM_API_DENIED;
233 return StatsUtils::DEFAULT_VALUE;
234 }
235 core_->ComputePower();
236 return core_->GetAppStatsPercent(uid);
237 }
238
GetPartStatsMah(const BatteryStatsInfo::ConsumptionType & type)239 double BatteryStatsService::GetPartStatsMah(const BatteryStatsInfo::ConsumptionType& type)
240 {
241 std::lock_guard lock(mutex_);
242 if (!Permission::IsSystem()) {
243 lastError_ = StatsError::ERR_SYSTEM_API_DENIED;
244 return StatsUtils::DEFAULT_VALUE;
245 }
246 core_->ComputePower();
247 return core_->GetPartStatsMah(type);
248 }
249
GetPartStatsPercent(const BatteryStatsInfo::ConsumptionType & type)250 double BatteryStatsService::GetPartStatsPercent(const BatteryStatsInfo::ConsumptionType& type)
251 {
252 std::lock_guard lock(mutex_);
253 if (!Permission::IsSystem()) {
254 lastError_ = StatsError::ERR_SYSTEM_API_DENIED;
255 return StatsUtils::DEFAULT_VALUE;
256 }
257 core_->ComputePower();
258 return core_->GetPartStatsPercent(type);
259 }
260
GetTotalTimeSecond(const StatsUtils::StatsType & statsType,const int32_t & uid)261 uint64_t BatteryStatsService::GetTotalTimeSecond(const StatsUtils::StatsType& statsType, const int32_t& uid)
262 {
263 if (!Permission::IsSystem()) {
264 lastError_ = StatsError::ERR_SYSTEM_API_DENIED;
265 return 0;
266 }
267 STATS_HILOGD(COMP_SVC, "statsType: %{public}d, uid: %{public}d", statsType, uid);
268 uint64_t timeSecond;
269 if (uid > StatsUtils::INVALID_VALUE) {
270 double timeMs = static_cast<double>(core_->GetTotalTimeMs(uid, statsType));
271 timeSecond = round(timeMs / StatsUtils::MS_IN_SECOND);
272 } else {
273 double timeMs = static_cast<double>(core_->GetTotalTimeMs(statsType));
274 timeSecond = round(timeMs / StatsUtils::MS_IN_SECOND);
275 }
276 return timeSecond;
277 }
278
GetTotalDataBytes(const StatsUtils::StatsType & statsType,const int32_t & uid)279 uint64_t BatteryStatsService::GetTotalDataBytes(const StatsUtils::StatsType& statsType, const int32_t& uid)
280 {
281 if (!Permission::IsSystem()) {
282 lastError_ = StatsError::ERR_SYSTEM_API_DENIED;
283 return 0;
284 }
285 return core_->GetTotalDataCount(statsType, uid);
286 }
287
Reset()288 void BatteryStatsService::Reset()
289 {
290 if (!Permission::IsSystem()) {
291 return;
292 }
293 core_->Reset();
294 }
295
GetBatteryStatsCore() const296 std::shared_ptr<BatteryStatsCore> BatteryStatsService::GetBatteryStatsCore() const
297 {
298 return core_;
299 }
300
GetBatteryStatsParser() const301 std::shared_ptr<BatteryStatsParser> BatteryStatsService::GetBatteryStatsParser() const
302 {
303 return parser_;
304 }
305
GetBatteryStatsDetector() const306 std::shared_ptr<BatteryStatsDetector> BatteryStatsService::GetBatteryStatsDetector() const
307 {
308 return detector_;
309 }
310
SetOnBattery(bool isOnBattery)311 void BatteryStatsService::SetOnBattery(bool isOnBattery)
312 {
313 if (!Permission::IsSystem()) {
314 return;
315 }
316 StatsHelper::SetOnBattery(isOnBattery);
317 }
318
ShellDump(const std::vector<std::string> & args,uint32_t argc)319 std::string BatteryStatsService::ShellDump(const std::vector<std::string>& args, uint32_t argc)
320 {
321 if (!Permission::IsSystem()|| !isBootCompleted_) {
322 return "";
323 }
324 std::lock_guard lock(mutex_);
325 pid_t pid = IPCSkeleton::GetCallingPid();
326 std::string result;
327 bool ret = BatteryStatsDumper::Dump(args, result);
328 STATS_HILOGI(COMP_SVC, "PID: %{public}d, Dump result :%{public}d", pid, ret);
329 return result;
330 }
331
GetLastError()332 StatsError BatteryStatsService::GetLastError()
333 {
334 StatsError tmpError = lastError_;
335 lastError_ = StatsError::ERR_OK;
336 return tmpError;
337 }
338 } // namespace PowerMgr
339 } // namespace OHOS
340