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