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_notify.h"
17 #include <regex>
18
19 #include "common_event_data.h"
20 #include "common_event_manager.h"
21 #include "common_event_publish_info.h"
22 #include "common_event_support.h"
23 #include "errors.h"
24 #include "hisysevent.h"
25 #include "if_system_ability_manager.h"
26 #include "iservice_registry.h"
27 #include "string_ex.h"
28 #include "system_ability_definition.h"
29
30 #include "battery_config.h"
31 #include "battery_log.h"
32 #include "battery_service.h"
33 #include "power_vibrator.h"
34 #include "power_mgr_client.h"
35
36 using namespace OHOS::AAFwk;
37 using namespace OHOS::EventFwk;
38 using namespace OHOS::HiviewDFX;
39
40 namespace OHOS {
41 namespace PowerMgr {
42 bool g_batteryLowOnce = false;
43 bool g_batteryOkOnce = false;
44 bool g_batteryConnectOnce = false;
45 bool g_batteryDisconnectOnce = false;
46 bool g_batteryChargingOnce = false;
47 bool g_batteryDischargingOnce = false;
48 bool g_commonEventInitSuccess = false;
49 OHOS::PowerMgr::BatteryCapacityLevel g_lastCapacityLevel = OHOS::PowerMgr::BatteryCapacityLevel::LEVEL_NONE;
50 const std::string POWER_SUPPLY = "SUBSYSTEM=power_supply";
51 const std::string SHUTDOWN = "shutdown";
52 const std::string REBOOT = "reboot";
53 sptr<BatteryService> g_service = DelayedSpSingleton<BatteryService>::GetInstance();
54
BatteryNotify()55 BatteryNotify::BatteryNotify()
56 {
57 const int32_t DEFAULT_LOW_CAPACITY = 20;
58 lowCapacity_ = BatteryConfig::GetInstance().GetInt("soc.low", DEFAULT_LOW_CAPACITY);
59 BATTERY_HILOGI(COMP_SVC, "Low broadcast power=%{public}d", lowCapacity_);
60 }
61
PublishEvents(const BatteryInfo & info)62 int32_t BatteryNotify::PublishEvents(const BatteryInfo& info)
63 {
64 if (g_commonEventInitSuccess) {
65 BATTERY_HILOGI(COMP_SVC, "common event service ability init success");
66 } else {
67 if (!IsCommonEventServiceAbilityExist()) {
68 return ERR_NO_INIT;
69 }
70 }
71 if (info.GetUevent() != POWER_SUPPLY && info.GetUevent() != "") {
72 HandleUevent(info);
73 return ERR_OK;
74 }
75
76 bool isAllSuccess = true;
77 bool ret = PublishChangedEvent(info);
78 isAllSuccess &= ret;
79 ret = PublishChangedEventInner(info);
80 isAllSuccess &= ret;
81 ret = PublishLowEvent(info);
82 isAllSuccess &= ret;
83 ret = PublishOkayEvent(info);
84 isAllSuccess &= ret;
85 ret = PublishPowerConnectedEvent(info);
86 isAllSuccess &= ret;
87 ret = PublishPowerDisconnectedEvent(info);
88 isAllSuccess &= ret;
89 ret = PublishChargingEvent(info);
90 isAllSuccess &= ret;
91 ret = PublishDischargingEvent(info);
92 isAllSuccess &= ret;
93 ret = PublishChargeTypeChangedEvent(info);
94 isAllSuccess &= ret;
95
96 return isAllSuccess ? ERR_OK : ERR_NO_INIT;
97 }
98
HandleUevent(const BatteryInfo & info)99 void BatteryNotify::HandleUevent(const BatteryInfo& info)
100 {
101 std::string ueventName = info.GetUevent();
102 auto& batteryConfig = BatteryConfig::GetInstance();
103 const UeventMap& ueventActionMap = batteryConfig.GetUeventActionMap();
104 for (auto& eventInfo : ueventActionMap) {
105 if (eventInfo.first == POWER_SUPPLY) {
106 continue;
107 }
108 for (auto& event : eventInfo.second) {
109 std::regex rString(event.first);
110 if (!std::regex_match(ueventName, rString)) {
111 continue;
112 }
113 BATTERY_HILOGI(COMP_SVC, "%{public}s decision %{public}s",
114 ueventName.c_str(), event.second.c_str());
115 if (event.second == SHUTDOWN) {
116 PowerMgrClient::GetInstance().ShutDownDevice(ueventName);
117 } else if (event.second == REBOOT) {
118 PowerMgrClient::GetInstance().RebootDevice(ueventName);
119 } else {
120 PublishChangedEvent(info);
121 }
122 return;
123 }
124 }
125 BATTERY_HILOGE(COMP_SVC, "undefine uevent name%{public}s", ueventName.c_str());
126 }
127
PublishChargeTypeChangedEvent(const BatteryInfo & info)128 bool BatteryNotify::PublishChargeTypeChangedEvent(const BatteryInfo& info)
129 {
130 ChargeType chargeType = info.GetChargeType();
131 bool isSuccess = true;
132 if (batteryInfoChargeType_ == chargeType) {
133 BATTERY_HILOGD(COMP_SVC, "No need to send chargetype event");
134 return isSuccess;
135 }
136 batteryInfoChargeType_ = chargeType;
137 Want want;
138 want.SetAction(CommonEventSupport::COMMON_EVENT_CHARGE_TYPE_CHANGED);
139 CommonEventData data;
140 data.SetWant(want);
141 CommonEventPublishInfo publishInfo;
142 publishInfo.SetOrdered(false);
143
144 data.SetCode(static_cast<int32_t>(chargeType));
145 BATTERY_HILOGD(COMP_SVC, "publisher chargeType=%{public}d", chargeType);
146 isSuccess = CommonEventManager::PublishCommonEvent(data, publishInfo);
147 if (!isSuccess) {
148 BATTERY_HILOGD(COMP_SVC, "failed to publish battery charge type event");
149 }
150
151 return isSuccess;
152 }
153
IsCommonEventServiceAbilityExist() const154 bool BatteryNotify::IsCommonEventServiceAbilityExist() const
155 {
156 sptr<ISystemAbilityManager> sysMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
157 if (!sysMgr) {
158 BATTERY_HILOGE(COMP_SVC,
159 "IsCommonEventServiceAbilityExist Get ISystemAbilityManager failed, no SystemAbilityManager");
160 return false;
161 }
162 sptr<IRemoteObject> remote = sysMgr->CheckSystemAbility(COMMON_EVENT_SERVICE_ID);
163 if (!remote) {
164 BATTERY_HILOGE(COMP_SVC, "No CesServiceAbility");
165 return false;
166 }
167
168 g_commonEventInitSuccess = true;
169 return true;
170 }
171
PublishChangedEvent(const BatteryInfo & info) const172 bool BatteryNotify::PublishChangedEvent(const BatteryInfo& info) const
173 {
174 Want want;
175 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_CAPACITY, info.GetCapacity());
176 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_VOLTAGE, info.GetVoltage());
177 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_TEMPERATURE, info.GetTemperature());
178 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_HEALTH_STATE, static_cast<int32_t>(info.GetHealthState()));
179 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_PLUGGED_TYPE, static_cast<int32_t>(info.GetPluggedType()));
180 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_CHARGE_STATE, static_cast<int32_t>(info.GetChargeState()));
181 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_PRESENT, info.IsPresent());
182 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_TECHNOLOGY, info.GetTechnology());
183 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_UEVENT, info.GetUevent());
184
185 auto capacityLevel = g_service->GetCapacityLevel();
186 if (capacityLevel != g_lastCapacityLevel) {
187 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_CAPACITY_LEVEL, static_cast<int32_t>(capacityLevel));
188 g_lastCapacityLevel = capacityLevel;
189 }
190
191 want.SetAction(CommonEventSupport::COMMON_EVENT_BATTERY_CHANGED);
192 CommonEventData data;
193 data.SetWant(want);
194 CommonEventPublishInfo publishInfo;
195 publishInfo.SetOrdered(false);
196 bool isSuccess = true;
197
198 HiSysEventWrite(HiSysEvent::Domain::BATTERY, "CHANGED", HiSysEvent::EventType::STATISTIC,
199 "LEVEL", info.GetCapacity(), "CHARGER", static_cast<int32_t>(info.GetPluggedType()),
200 "VOLTAGE", info.GetVoltage(), "TEMPERATURE", info.GetTemperature(),
201 "HEALTH", static_cast<int32_t>(info.GetHealthState()), "CURRENT", info.GetNowCurrent());
202 isSuccess = CommonEventManager::PublishCommonEvent(data, publishInfo);
203 if (!isSuccess) {
204 BATTERY_HILOGE(FEATURE_BATT_INFO, "failed to publish BATTERY_CHANGED event");
205 }
206 return isSuccess;
207 }
208
PublishChangedEventInner(const BatteryInfo & info) const209 bool BatteryNotify::PublishChangedEventInner(const BatteryInfo& info) const
210 {
211 Want want;
212 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_PLUGGED_MAX_CURRENT, info.GetPluggedMaxCurrent());
213 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_PLUGGED_MAX_VOLTAGE, info.GetPluggedMaxVoltage());
214 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_PLUGGED_NOW_CURRENT, info.GetNowCurrent());
215 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_CHARGE_COUNTER, info.GetChargeCounter());
216
217 want.SetAction(BatteryInfo::COMMON_EVENT_BATTERY_CHANGED_INNER);
218 CommonEventData data;
219 data.SetWant(want);
220 CommonEventPublishInfo publishInfo;
221 publishInfo.SetOrdered(false);
222
223 bool isSuccess = true;
224 isSuccess = CommonEventManager::PublishCommonEvent(data, publishInfo);
225 if (!isSuccess) {
226 BATTERY_HILOGE(FEATURE_BATT_INFO, "failed to publish BATTERY_CHANGED_INNER event");
227 }
228 return isSuccess;
229 }
230
PublishLowEvent(const BatteryInfo & info) const231 bool BatteryNotify::PublishLowEvent(const BatteryInfo& info) const
232 {
233 bool isSuccess = true;
234
235 if (info.GetCapacity() > lowCapacity_) {
236 g_batteryLowOnce = false;
237 return isSuccess;
238 }
239
240 if (g_batteryLowOnce) {
241 return isSuccess;
242 }
243
244 Want want;
245 want.SetAction(CommonEventSupport::COMMON_EVENT_BATTERY_LOW);
246 CommonEventData data;
247 data.SetWant(want);
248 CommonEventPublishInfo publishInfo;
249 publishInfo.SetOrdered(false);
250 data.SetCode(info.GetCapacity());
251 BATTERY_HILOGD(FEATURE_BATT_INFO, "publisher capacity=%{public}d", info.GetCapacity());
252 isSuccess = CommonEventManager::PublishCommonEvent(data, publishInfo);
253 if (!isSuccess) {
254 BATTERY_HILOGE(FEATURE_BATT_INFO, "failed to publish battery_low event");
255 }
256 g_batteryLowOnce = true;
257 return isSuccess;
258 }
259
PublishOkayEvent(const BatteryInfo & info) const260 bool BatteryNotify::PublishOkayEvent(const BatteryInfo& info) const
261 {
262 bool isSuccess = true;
263
264 if (info.GetCapacity() <= lowCapacity_) {
265 g_batteryOkOnce = false;
266 return isSuccess;
267 }
268
269 if (g_batteryOkOnce) {
270 return isSuccess;
271 }
272
273 Want want;
274 want.SetAction(CommonEventSupport::COMMON_EVENT_BATTERY_OKAY);
275 CommonEventData data;
276 data.SetWant(want);
277 CommonEventPublishInfo publishInfo;
278 publishInfo.SetOrdered(false);
279 data.SetCode(info.GetCapacity());
280 BATTERY_HILOGD(FEATURE_BATT_INFO, "publisher capacity=%{public}d", info.GetCapacity());
281 isSuccess = CommonEventManager::PublishCommonEvent(data, publishInfo);
282 if (!isSuccess) {
283 BATTERY_HILOGD(FEATURE_BATT_INFO, "failed to publish battery_okay event");
284 }
285 g_batteryOkOnce = true;
286 return isSuccess;
287 }
288
PublishPowerConnectedEvent(const BatteryInfo & info) const289 bool BatteryNotify::PublishPowerConnectedEvent(const BatteryInfo& info) const
290 {
291 bool isSuccess = true;
292
293 if ((info.GetPluggedType() == BatteryPluggedType::PLUGGED_TYPE_NONE) ||
294 (info.GetPluggedType() == BatteryPluggedType::PLUGGED_TYPE_BUTT)) {
295 g_batteryConnectOnce = false;
296 return isSuccess;
297 }
298
299 if (g_batteryConnectOnce) {
300 return isSuccess;
301 }
302 StartVibrator();
303 Want want;
304 want.SetAction(CommonEventSupport::COMMON_EVENT_POWER_CONNECTED);
305 CommonEventData data;
306 data.SetWant(want);
307 CommonEventPublishInfo publishInfo;
308 publishInfo.SetOrdered(false);
309 data.SetCode(static_cast<int32_t>(info.GetPluggedType()));
310 BATTERY_HILOGD(FEATURE_BATT_INFO, "publisher pluggedtype=%{public}u",
311 static_cast<uint32_t>(info.GetPluggedType()));
312 isSuccess = CommonEventManager::PublishCommonEvent(data, publishInfo);
313 if (!isSuccess) {
314 BATTERY_HILOGE(FEATURE_BATT_INFO, "failed to publish power_connected event");
315 }
316
317 g_batteryConnectOnce = true;
318 return isSuccess;
319 }
320
StartVibrator() const321 void BatteryNotify::StartVibrator() const
322 {
323 std::shared_ptr<PowerVibrator> vibrator = PowerVibrator::GetInstance();
324 std::string scene = "start_charge";
325 vibrator->StartVibrator(scene);
326 }
327
PublishPowerDisconnectedEvent(const BatteryInfo & info) const328 bool BatteryNotify::PublishPowerDisconnectedEvent(const BatteryInfo& info) const
329 {
330 bool isSuccess = true;
331
332 if ((info.GetPluggedType() != BatteryPluggedType::PLUGGED_TYPE_NONE) &&
333 (info.GetPluggedType() != BatteryPluggedType::PLUGGED_TYPE_BUTT)) {
334 g_batteryDisconnectOnce = false;
335 return isSuccess;
336 }
337
338 if (g_batteryDisconnectOnce) {
339 return isSuccess;
340 }
341
342 Want want;
343 want.SetAction(CommonEventSupport::COMMON_EVENT_POWER_DISCONNECTED);
344 CommonEventData data;
345 data.SetWant(want);
346 CommonEventPublishInfo publishInfo;
347 publishInfo.SetOrdered(false);
348 data.SetCode(static_cast<int32_t>(info.GetPluggedType()));
349 BATTERY_HILOGD(FEATURE_BATT_INFO, "publisher pluggedtype=%{public}u",
350 static_cast<uint32_t>(info.GetPluggedType()));
351 isSuccess = CommonEventManager::PublishCommonEvent(data, publishInfo);
352 if (!isSuccess) {
353 BATTERY_HILOGD(FEATURE_BATT_INFO, "failed to publish power_disconnected event");
354 }
355
356 g_batteryDisconnectOnce = true;
357 return isSuccess;
358 }
359
PublishChargingEvent(const BatteryInfo & info) const360 bool BatteryNotify::PublishChargingEvent(const BatteryInfo& info) const
361 {
362 bool isSuccess = true;
363
364 if ((info.GetChargeState() != BatteryChargeState::CHARGE_STATE_ENABLE) &&
365 (info.GetChargeState() != BatteryChargeState::CHARGE_STATE_FULL)) {
366 g_batteryChargingOnce = false;
367 return isSuccess;
368 }
369
370 if (g_batteryChargingOnce) {
371 return isSuccess;
372 }
373
374 Want want;
375 want.SetAction(CommonEventSupport::COMMON_EVENT_CHARGING);
376 CommonEventData data;
377 data.SetWant(want);
378 CommonEventPublishInfo publishInfo;
379 publishInfo.SetOrdered(false);
380 data.SetCode(static_cast<int32_t>(info.GetChargeState()));
381 BATTERY_HILOGD(FEATURE_BATT_INFO, "publisher chargeState=%{public}u",
382 static_cast<uint32_t>(info.GetChargeState()));
383 isSuccess = CommonEventManager::PublishCommonEvent(data, publishInfo);
384 if (!isSuccess) {
385 BATTERY_HILOGD(FEATURE_BATT_INFO, "failed to publish battery charing event");
386 }
387
388 g_batteryChargingOnce = true;
389 return isSuccess;
390 }
391
PublishDischargingEvent(const BatteryInfo & info) const392 bool BatteryNotify::PublishDischargingEvent(const BatteryInfo& info) const
393 {
394 bool isSuccess = true;
395
396 if ((info.GetChargeState() == BatteryChargeState::CHARGE_STATE_ENABLE) ||
397 (info.GetChargeState() == BatteryChargeState::CHARGE_STATE_FULL)) {
398 g_batteryDischargingOnce = false;
399 return isSuccess;
400 }
401
402 if (g_batteryDischargingOnce) {
403 return isSuccess;
404 }
405
406 Want want;
407 want.SetAction(CommonEventSupport::COMMON_EVENT_DISCHARGING);
408 CommonEventData data;
409 data.SetWant(want);
410 CommonEventPublishInfo publishInfo;
411 publishInfo.SetOrdered(false);
412 data.SetCode(static_cast<int32_t>(info.GetChargeState()));
413 BATTERY_HILOGD(FEATURE_BATT_INFO, "publisher chargeState=%{public}u",
414 static_cast<uint32_t>(info.GetChargeState()));
415 isSuccess = CommonEventManager::PublishCommonEvent(data, publishInfo);
416 if (!isSuccess) {
417 BATTERY_HILOGD(FEATURE_BATT_INFO, "failed to publish battery charing event");
418 }
419
420 g_batteryDischargingOnce = true;
421 return isSuccess;
422 }
423 } // namespace PowerMgr
424 } // namespace OHOS
425