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