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 #ifdef BATTERY_MANAGER_ENABLE_CHARGING_SOUND
20 #include "ffrt_utils.h"
21 #ifdef CONFIG_USE_JEMALLOC_DFX_INTF
22 #include "memory_guard.h"
23 #endif
24 #endif
25 #include "common_event_data.h"
26 #include "common_event_manager.h"
27 #include "common_event_publish_info.h"
28 #include "common_event_support.h"
29 #include "errors.h"
30 #include "hisysevent.h"
31 #include "if_system_ability_manager.h"
32 #include "iservice_registry.h"
33 #include "string_ex.h"
34 #include "system_ability_definition.h"
35
36 #include <hookmgr.h>
37 #include "battery_hookmgr.h"
38
39 #include "battery_config.h"
40 #include "battery_log.h"
41 #include "battery_service.h"
42 #include "power_vibrator.h"
43 #include "power_mgr_client.h"
44 #include <dlfcn.h>
45
46 using namespace OHOS::AAFwk;
47 using namespace OHOS::EventFwk;
48 using namespace OHOS::HiviewDFX;
49
50 namespace OHOS {
51 namespace PowerMgr {
52 bool g_batteryLowOnce = false;
53 bool g_batteryOkOnce = false;
54 bool g_batteryConnectOnce = false;
55 bool g_batteryDisconnectOnce = false;
56 bool g_batteryChargingOnce = false;
57 bool g_batteryDischargingOnce = false;
58 bool g_commonEventInitSuccess = false;
59 OHOS::PowerMgr::BatteryCapacityLevel g_lastCapacityLevel = OHOS::PowerMgr::BatteryCapacityLevel::LEVEL_NONE;
60 const std::string POWER_SUPPLY = "SUBSYSTEM=power_supply";
61 const std::string SHUTDOWN = "shutdown";
62 const std::string REBOOT = "reboot";
63 const std::string SEND_COMMONEVENT = "sendcommonevent";
64 const std::string SEND_CUSTOMEVENT = "sendcustomevent";
65 const std::string SEND_POPUP = "sendpopup";
66 const std::string BATTERY_CUSTOM_EVENT_PREFIX = "usual.event.";
67 sptr<BatteryService> g_service = DelayedSpSingleton<BatteryService>::GetInstance();
68
BatteryNotify()69 BatteryNotify::BatteryNotify()
70 {
71 const int32_t DEFAULT_LOW_CAPACITY = 20;
72 lowCapacity_ = BatteryConfig::GetInstance().GetInt("soc.low", DEFAULT_LOW_CAPACITY);
73 BATTERY_HILOGI(COMP_SVC, "Low broadcast power=%{public}d", lowCapacity_);
74 }
75
PublishEvents(BatteryInfo & info)76 int32_t BatteryNotify::PublishEvents(BatteryInfo& info)
77 {
78 if (!g_commonEventInitSuccess) {
79 if (!IsCommonEventServiceAbilityExist()) {
80 return ERR_NO_INIT;
81 }
82 }
83 if (info.GetUevent() != POWER_SUPPLY && info.GetUevent() != "" &&
84 info.GetUevent() != INVALID_STRING_VALUE) {
85 HandleUevent(info);
86 return ERR_OK;
87 }
88
89 bool isAllSuccess = true;
90 bool ret = PublishChangedEvent(info);
91 isAllSuccess &= ret;
92 ret = PublishChangedEventInner(info);
93 isAllSuccess &= ret;
94 std::lock_guard<std::mutex> lock(mutex_);
95 ret = PublishLowEvent(info);
96 isAllSuccess &= ret;
97 ret = PublishOkayEvent(info);
98 isAllSuccess &= ret;
99
100 #ifdef BATTERY_MANAGER_ENABLE_WIRELESS_CHARGE
101 PublishEventContext context {.pluggedType = info.GetPluggedType(),
102 .lastPluggedType = lastPowerPluggedType_,
103 .wirelessChargerEnable = BatteryConfig::GetInstance().GetWirelessChargerConf()};
104 HookMgrExecute(
105 GetBatteryHookMgr(), static_cast<int32_t>(BatteryHookStage::BATTERY_PUBLISH_EVENT), &context, nullptr);
106 #endif
107 ret = PublishPowerConnectedEvent(info);
108 isAllSuccess &= ret;
109 ret = PublishPowerDisconnectedEvent(info);
110 isAllSuccess &= ret;
111 ret = PublishChargingEvent(info);
112 isAllSuccess &= ret;
113 ret = PublishDischargingEvent(info);
114 isAllSuccess &= ret;
115 ret = PublishChargeTypeChangedEvent(info);
116 isAllSuccess &= ret;
117 lastPowerPluggedType_ = info.GetPluggedType();
118 return isAllSuccess ? ERR_OK : ERR_NO_INIT;
119 }
120
HandleUevent(BatteryInfo & info)121 void BatteryNotify::HandleUevent(BatteryInfo& info)
122 {
123 std::string uevent = info.GetUevent();
124 auto pos = uevent.rfind('$');
125 if (pos != std::string::npos) {
126 std::string ueventName = uevent.substr(0, pos);
127 std::string ueventAct = uevent.substr(++pos);
128 BATTERY_HILOGI(COMP_SVC, "%{public}s decision %{public}s",
129 ueventName.c_str(), ueventAct.c_str());
130 if (ueventAct == SHUTDOWN) {
131 const std::string reason = "POWEROFF_CHARGE_DISABLE";
132 PowerMgrClient::GetInstance().ShutDownDevice(reason);
133 } else if (ueventAct == REBOOT) {
134 PowerMgrClient::GetInstance().RebootDevice(ueventName);
135 } else if (ueventAct == SEND_COMMONEVENT) {
136 info.SetUevent(ueventName);
137 PublishChangedEvent(info);
138 } else if (ueventAct.compare(0, BATTERY_CUSTOM_EVENT_PREFIX.size(), BATTERY_CUSTOM_EVENT_PREFIX) == 0) {
139 info.SetUevent(ueventName);
140 PublishCustomEvent(info, ueventAct);
141 } else if (ueventAct == SEND_POPUP) {
142 info.SetUevent(ueventName);
143 PublishChangedEvent(info);
144 HandleNotification(ueventName);
145 } else {
146 BATTERY_HILOGE(COMP_SVC, "undefine uevent act %{public}s", ueventAct.c_str());
147 }
148 }
149 BATTERY_HILOGI(COMP_SVC, "handle uevent info %{public}s", uevent.c_str());
150 }
151
PublishChargeTypeChangedEvent(const BatteryInfo & info)152 bool BatteryNotify::PublishChargeTypeChangedEvent(const BatteryInfo& info)
153 {
154 ChargeType chargeType = info.GetChargeType();
155 bool isSuccess = true;
156 if (batteryInfoChargeType_ == chargeType) {
157 BATTERY_HILOGD(COMP_SVC, "No need to send chargetype event");
158 return isSuccess;
159 }
160 batteryInfoChargeType_ = chargeType;
161 Want want;
162 want.SetAction(CommonEventSupport::COMMON_EVENT_CHARGE_TYPE_CHANGED);
163 CommonEventData data;
164 data.SetWant(want);
165 CommonEventPublishInfo publishInfo;
166 publishInfo.SetOrdered(false);
167
168 data.SetCode(static_cast<int32_t>(chargeType));
169 BATTERY_HILOGD(COMP_SVC, "publisher chargeType=%{public}d", chargeType);
170 isSuccess = CommonEventManager::PublishCommonEvent(data, publishInfo);
171 if (!isSuccess) {
172 BATTERY_HILOGD(COMP_SVC, "failed to publish battery charge type event");
173 }
174
175 return isSuccess;
176 }
177
IsCommonEventServiceAbilityExist() const178 bool BatteryNotify::IsCommonEventServiceAbilityExist() const
179 {
180 sptr<ISystemAbilityManager> sysMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
181 if (!sysMgr) {
182 BATTERY_HILOGE(COMP_SVC,
183 "IsCommonEventServiceAbilityExist Get ISystemAbilityManager failed, no SystemAbilityManager");
184 return false;
185 }
186 sptr<IRemoteObject> remote = sysMgr->CheckSystemAbility(COMMON_EVENT_SERVICE_ID);
187 if (!remote) {
188 BATTERY_HILOGE(COMP_SVC, "No CesServiceAbility");
189 return false;
190 }
191
192 if (!g_commonEventInitSuccess) {
193 BATTERY_HILOGI(COMP_SVC, "common event service ability init success");
194 g_commonEventInitSuccess = true;
195 }
196
197 return true;
198 }
199
PublishChangedEvent(const BatteryInfo & info)200 bool BatteryNotify::PublishChangedEvent(const BatteryInfo& info)
201 {
202 Want want;
203 int32_t capacity = info.GetCapacity();
204 int32_t pluggedType = static_cast<int32_t>(info.GetPluggedType());
205 int32_t temperature = info.GetTemperature();
206 int32_t healthState = static_cast<int32_t>(info.GetHealthState());
207 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_CAPACITY, capacity);
208 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_VOLTAGE, info.GetVoltage());
209 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_TEMPERATURE, temperature);
210 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_HEALTH_STATE, healthState);
211 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_PLUGGED_TYPE, pluggedType);
212 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_CHARGE_STATE, static_cast<int32_t>(info.GetChargeState()));
213 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_PRESENT, info.IsPresent());
214 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_TECHNOLOGY, info.GetTechnology());
215 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_UEVENT, info.GetUevent());
216
217 auto capacityLevel = static_cast<uint32_t>(BatteryCapacityLevel::LEVEL_NONE);
218 g_service->GetCapacityLevel(capacityLevel);
219 if (static_cast<BatteryCapacityLevel>(capacityLevel) != g_lastCapacityLevel) {
220 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_CAPACITY_LEVEL, static_cast<int32_t>(capacityLevel));
221 g_lastCapacityLevel = static_cast<BatteryCapacityLevel>(capacityLevel);
222 }
223
224 want.SetAction(CommonEventSupport::COMMON_EVENT_BATTERY_CHANGED);
225 CommonEventData data;
226 data.SetWant(want);
227 CommonEventPublishInfo publishInfo;
228 publishInfo.SetOrdered(false);
229 if (capacity != lastCapacity_ || pluggedType != lastPluggedType_ ||
230 temperature != lastTemperature_ || healthState != lastHealthState_) {
231 HiSysEventWrite(HiSysEvent::Domain::BATTERY, "CHANGED", HiSysEvent::EventType::STATISTIC,
232 "LEVEL", capacity, "CHARGER", pluggedType, "VOLTAGE", info.GetVoltage(),
233 "TEMPERATURE", temperature, "HEALTH", healthState, "CURRENT", info.GetNowCurrent(),
234 "CHARGE_MODE", static_cast<int32_t>(info.GetChargeType()));
235 lastCapacity_ = capacity;
236 lastPluggedType_ = pluggedType;
237 lastTemperature_ = temperature;
238 lastHealthState_ = healthState;
239 }
240 bool isSuccess = CommonEventManager::PublishCommonEvent(data, publishInfo);
241 if (!isSuccess) {
242 BATTERY_HILOGE(FEATURE_BATT_INFO, "failed to publish BATTERY_CHANGED event");
243 }
244 return isSuccess;
245 }
246
PublishChangedEventInner(const BatteryInfo & info) const247 bool BatteryNotify::PublishChangedEventInner(const BatteryInfo& info) const
248 {
249 Want want;
250 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_PLUGGED_MAX_CURRENT, info.GetPluggedMaxCurrent());
251 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_PLUGGED_MAX_VOLTAGE, info.GetPluggedMaxVoltage());
252 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_PLUGGED_NOW_CURRENT, info.GetNowCurrent());
253 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_CHARGE_COUNTER, info.GetChargeCounter());
254
255 want.SetAction(BatteryInfo::COMMON_EVENT_BATTERY_CHANGED_INNER);
256 CommonEventData data;
257 data.SetWant(want);
258 CommonEventPublishInfo publishInfo;
259 publishInfo.SetOrdered(false);
260 const std::vector<std::string> permissionVec { "ohos.permission.POWER_OPTIMIZATION" };
261 publishInfo.SetSubscriberPermissions(permissionVec);
262
263 bool isSuccess = true;
264 isSuccess = CommonEventManager::PublishCommonEvent(data, publishInfo);
265 if (!isSuccess) {
266 BATTERY_HILOGE(FEATURE_BATT_INFO, "failed to publish BATTERY_CHANGED_INNER event");
267 }
268 return isSuccess;
269 }
270
PublishLowEvent(const BatteryInfo & info) const271 bool BatteryNotify::PublishLowEvent(const BatteryInfo& info) const
272 {
273 bool isSuccess = true;
274
275 if (info.GetCapacity() > lowCapacity_) {
276 g_batteryLowOnce = false;
277 return isSuccess;
278 }
279
280 if (g_batteryLowOnce) {
281 return isSuccess;
282 }
283
284 Want want;
285 want.SetAction(CommonEventSupport::COMMON_EVENT_BATTERY_LOW);
286 CommonEventData data;
287 data.SetWant(want);
288 CommonEventPublishInfo publishInfo;
289 publishInfo.SetOrdered(false);
290 data.SetCode(info.GetCapacity());
291 BATTERY_HILOGD(FEATURE_BATT_INFO, "publisher capacity=%{public}d", info.GetCapacity());
292 isSuccess = CommonEventManager::PublishCommonEvent(data, publishInfo);
293 if (!isSuccess) {
294 BATTERY_HILOGE(FEATURE_BATT_INFO, "failed to publish battery_low event");
295 }
296 g_batteryLowOnce = true;
297 return isSuccess;
298 }
299
PublishOkayEvent(const BatteryInfo & info) const300 bool BatteryNotify::PublishOkayEvent(const BatteryInfo& info) const
301 {
302 bool isSuccess = true;
303
304 if (info.GetCapacity() <= lowCapacity_) {
305 g_batteryOkOnce = false;
306 return isSuccess;
307 }
308
309 if (g_batteryOkOnce) {
310 return isSuccess;
311 }
312
313 Want want;
314 want.SetAction(CommonEventSupport::COMMON_EVENT_BATTERY_OKAY);
315 CommonEventData data;
316 data.SetWant(want);
317 CommonEventPublishInfo publishInfo;
318 publishInfo.SetOrdered(false);
319 data.SetCode(info.GetCapacity());
320 BATTERY_HILOGD(FEATURE_BATT_INFO, "publisher capacity=%{public}d", info.GetCapacity());
321 isSuccess = CommonEventManager::PublishCommonEvent(data, publishInfo);
322 if (!isSuccess) {
323 BATTERY_HILOGD(FEATURE_BATT_INFO, "failed to publish battery_okay event");
324 }
325 g_batteryOkOnce = true;
326 return isSuccess;
327 }
328
329 #ifdef BATTERY_MANAGER_ENABLE_CHARGING_SOUND
330 namespace {
331 std::atomic<bool> g_stopping = false;
332 std::atomic<bool> g_released = true;
333 constexpr int MAX_PLAY_TIME_MS = 2000;
334 constexpr int TICK_INTERVAL_MS = 100;
335 constexpr int US_PER_MS = 1000;
336
337 // be careful: most of the shared libraries in ohos do not support dynamic (un-)loading.
338 // for now, if the current process does not hav certain libs as dependency (thus they won't be unloaded),
339 // re-dlopen after dlclosing libmedia_client.z.so causes crashes (use of released symbols somehow).
340 // known libraries that should not be unloaded: configpolicy_util, image_framework.
AntiMemLeak()341 void AntiMemLeak()
342 {
343 // this indirectly opened library causes mem leak, do not reopen it.
344 // check global variables in third_party/libphonenumber/cpp/src/phonenumbers/ohos/update_metadata.cc
345 // if there are any further libraries causing mem-leaks or crashes, add them here.
346 void* tmpHandle = dlopen("libphonenumber_standard.z.so", RTLD_LAZY | RTLD_NODELETE);
347 if (!tmpHandle) {
348 BATTERY_HILOGE(FEATURE_BATT_INFO, "dlopen libphonenumber_standard.z.so failed");
349 } else {
350 dlclose(tmpHandle);
351 }
352 }
353
StartChargingSoundFunc()354 void StartChargingSoundFunc()
355 {
356 #ifdef CONFIG_USE_JEMALLOC_DFX_INTF
357 OHOS::PowerMgr::MemoryGuard guard;
358 #endif
359 if (!g_service || !g_service->IsBootCompleted()) {
360 return;
361 }
362 bool expected = true;
363 bool ret = g_released.compare_exchange_strong(expected, false);
364 if (!ret) {
365 BATTERY_HILOGE(FEATURE_BATT_INFO, "charging sound not released");
366 return;
367 }
368 AntiMemLeak();
369 void* handle = dlopen("libcharging_sound.z.so", RTLD_NOLOAD);
370 if (!handle) {
371 BATTERY_HILOGI(FEATURE_BATT_INFO, "libcharging_sound not loaded");
372 handle = dlopen("libcharging_sound.z.so", RTLD_LAZY);
373 }
374 if (!handle) {
375 BATTERY_HILOGE(FEATURE_BATT_INFO, "dlopen libcharging_sound failed: ret=%{public}s", dlerror());
376 g_released.store(true);
377 return;
378 }
379 auto ChargingSoundStart = reinterpret_cast<bool(*)(void)>(dlsym(handle, "ChargingSoundStart"));
380 auto IsPlaying = reinterpret_cast<bool (*)(void)>(dlsym(handle, "IsPlaying"));
381 if (!IsPlaying || !ChargingSoundStart) {
382 BATTERY_HILOGE(FEATURE_BATT_INFO, "dlsym failed");
383 dlclose(handle);
384 g_released.store(true);
385 return;
386 }
387 g_stopping.store(false);
388 ffrt::submit([ChargingSoundStart, IsPlaying, handle]() {
389 #ifdef CONFIG_USE_JEMALLOC_DFX_INTF
390 OHOS::PowerMgr::MemoryGuard guard;
391 #endif
392 if (!ChargingSoundStart()) {
393 BATTERY_HILOGE(FEATURE_BATT_INFO, "ChargingSoundStart failed");
394 g_released.store(true);
395 return;
396 }
397 for (int timePassed = 0; timePassed < MAX_PLAY_TIME_MS; timePassed += TICK_INTERVAL_MS) {
398 if (g_stopping.load()) {
399 break;
400 }
401 if (!IsPlaying()) {
402 break;
403 }
404 usleep(TICK_INTERVAL_MS * US_PER_MS);
405 }
406 dlclose(handle);
407 g_released.store(true);
408 });
409 }
410 }
411 #endif
412
PublishPowerConnectedEvent(const BatteryInfo & info) const413 bool BatteryNotify::PublishPowerConnectedEvent(const BatteryInfo& info) const
414 {
415 bool isSuccess = true;
416
417 if ((info.GetPluggedType() == BatteryPluggedType::PLUGGED_TYPE_NONE) ||
418 (info.GetPluggedType() == BatteryPluggedType::PLUGGED_TYPE_BUTT)) {
419 g_batteryConnectOnce = false;
420 return isSuccess;
421 }
422
423 if (g_batteryConnectOnce) {
424 return isSuccess;
425 }
426 StartVibrator();
427 #ifdef BATTERY_MANAGER_ENABLE_CHARGING_SOUND
428 StartChargingSoundFunc();
429 #endif
430 Want want;
431 want.SetAction(CommonEventSupport::COMMON_EVENT_POWER_CONNECTED);
432 CommonEventData data;
433 data.SetWant(want);
434 CommonEventPublishInfo publishInfo;
435 publishInfo.SetOrdered(false);
436 data.SetCode(static_cast<int32_t>(info.GetPluggedType()));
437 BATTERY_HILOGD(FEATURE_BATT_INFO, "publisher pluggedtype=%{public}u",
438 static_cast<uint32_t>(info.GetPluggedType()));
439 isSuccess = CommonEventManager::PublishCommonEvent(data, publishInfo);
440 if (!isSuccess) {
441 BATTERY_HILOGE(FEATURE_BATT_INFO, "failed to publish power_connected event");
442 }
443
444 g_batteryConnectOnce = true;
445 return isSuccess;
446 }
447
StartVibrator() const448 void BatteryNotify::StartVibrator() const
449 {
450 std::shared_ptr<PowerVibrator> vibrator = PowerVibrator::GetInstance();
451 std::string scene = "start_charge";
452 vibrator->StartVibrator(scene);
453 }
454
PublishPowerDisconnectedEvent(const BatteryInfo & info) const455 bool BatteryNotify::PublishPowerDisconnectedEvent(const BatteryInfo& info) const
456 {
457 bool isSuccess = true;
458
459 if ((info.GetPluggedType() != BatteryPluggedType::PLUGGED_TYPE_NONE) &&
460 (info.GetPluggedType() != BatteryPluggedType::PLUGGED_TYPE_BUTT)) {
461 g_batteryDisconnectOnce = false;
462 return isSuccess;
463 }
464
465 if (g_batteryDisconnectOnce) {
466 return isSuccess;
467 }
468 #ifdef BATTERY_MANAGER_ENABLE_CHARGING_SOUND
469 g_stopping.store(true);
470 #endif
471 Want want;
472 want.SetAction(CommonEventSupport::COMMON_EVENT_POWER_DISCONNECTED);
473 CommonEventData data;
474 data.SetWant(want);
475 CommonEventPublishInfo publishInfo;
476 publishInfo.SetOrdered(false);
477 data.SetCode(static_cast<int32_t>(info.GetPluggedType()));
478 BATTERY_HILOGD(FEATURE_BATT_INFO, "publisher pluggedtype=%{public}u",
479 static_cast<uint32_t>(info.GetPluggedType()));
480 isSuccess = CommonEventManager::PublishCommonEvent(data, publishInfo);
481 if (!isSuccess) {
482 BATTERY_HILOGD(FEATURE_BATT_INFO, "failed to publish power_disconnected event");
483 }
484
485 g_batteryDisconnectOnce = true;
486 return isSuccess;
487 }
488
PublishChargingEvent(const BatteryInfo & info) const489 bool BatteryNotify::PublishChargingEvent(const BatteryInfo& info) const
490 {
491 bool isSuccess = true;
492
493 if ((info.GetChargeState() != BatteryChargeState::CHARGE_STATE_ENABLE) &&
494 (info.GetChargeState() != BatteryChargeState::CHARGE_STATE_FULL)) {
495 g_batteryChargingOnce = false;
496 return isSuccess;
497 }
498
499 if (g_batteryChargingOnce) {
500 return isSuccess;
501 }
502
503 Want want;
504 want.SetAction(CommonEventSupport::COMMON_EVENT_CHARGING);
505 CommonEventData data;
506 data.SetWant(want);
507 CommonEventPublishInfo publishInfo;
508 publishInfo.SetOrdered(false);
509 data.SetCode(static_cast<int32_t>(info.GetChargeState()));
510 BATTERY_HILOGD(FEATURE_BATT_INFO, "publisher chargeState=%{public}u",
511 static_cast<uint32_t>(info.GetChargeState()));
512 isSuccess = CommonEventManager::PublishCommonEvent(data, publishInfo);
513 if (!isSuccess) {
514 BATTERY_HILOGD(FEATURE_BATT_INFO, "failed to publish battery charing event");
515 }
516
517 g_batteryChargingOnce = true;
518 return isSuccess;
519 }
520
PublishDischargingEvent(const BatteryInfo & info) const521 bool BatteryNotify::PublishDischargingEvent(const BatteryInfo& info) const
522 {
523 bool isSuccess = true;
524
525 if ((info.GetChargeState() == BatteryChargeState::CHARGE_STATE_ENABLE) ||
526 (info.GetChargeState() == BatteryChargeState::CHARGE_STATE_FULL)) {
527 g_batteryDischargingOnce = false;
528 return isSuccess;
529 }
530
531 if (g_batteryDischargingOnce) {
532 return isSuccess;
533 }
534
535 Want want;
536 want.SetAction(CommonEventSupport::COMMON_EVENT_DISCHARGING);
537 CommonEventData data;
538 data.SetWant(want);
539 CommonEventPublishInfo publishInfo;
540 publishInfo.SetOrdered(false);
541 data.SetCode(static_cast<int32_t>(info.GetChargeState()));
542 BATTERY_HILOGD(FEATURE_BATT_INFO, "publisher chargeState=%{public}u",
543 static_cast<uint32_t>(info.GetChargeState()));
544 isSuccess = CommonEventManager::PublishCommonEvent(data, publishInfo);
545 if (!isSuccess) {
546 BATTERY_HILOGD(FEATURE_BATT_INFO, "failed to publish battery charing event");
547 }
548
549 g_batteryDischargingOnce = true;
550 return isSuccess;
551 }
552
PublishCustomEvent(const BatteryInfo & info,const std::string & commonEventName) const553 bool BatteryNotify::PublishCustomEvent(const BatteryInfo& info, const std::string& commonEventName) const
554 {
555 UEVENT_CHECK_INFO ueventCheckInfo = {
556 .UeventName = info.GetUevent(),
557 .checkResult = true
558 };
559 int ret = HookMgrExecute(GetBatteryHookMgr(), static_cast<int32_t>(BatteryHookStage::BATTERY_UEVENT_CHECK),
560 (void*)&ueventCheckInfo, nullptr);
561 if (ret == 0 && !ueventCheckInfo.checkResult) {
562 BATTERY_HILOGW(FEATURE_BATT_INFO, "PublishCustomEvent fail, uevent=%{public}s, checkResult=%{public}d",
563 ueventCheckInfo.UeventName.c_str(), ueventCheckInfo.checkResult);
564 return false;
565 }
566 Want want;
567 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_UEVENT, info.GetUevent());
568 want.SetAction(commonEventName);
569 CommonEventData data;
570 data.SetWant(want);
571 CommonEventPublishInfo publishInfo;
572 publishInfo.SetOrdered(false);
573 const std::vector<std::string> permissionVec { "ohos.permission.POWER_OPTIMIZATION" };
574 publishInfo.SetSubscriberPermissions(permissionVec);
575
576 bool isSuccess = CommonEventManager::PublishCommonEvent(data, publishInfo);
577 if (!isSuccess) {
578 BATTERY_HILOGD(FEATURE_BATT_INFO, "failed to publish battery custom event");
579 }
580 return isSuccess;
581 }
582
HandleNotification(const std::string & ueventName) const583 bool BatteryNotify::HandleNotification(const std::string& ueventName) const
584 {
585 #ifdef BATTERY_SUPPORT_NOTIFICATION
586 std::unordered_map<std::string, std::vector<BatteryConfig::PopupConf>> popupCfg =
587 BatteryConfig::GetInstance().GetPopupConf();
588 auto iter = popupCfg.find(ueventName);
589 if (iter == popupCfg.end()) {
590 BATTERY_HILOGW(COMP_SVC, "HandleNotification not found conf: %{public}s", ueventName.c_str());
591 return false;
592 }
593 typedef void(*HandleNotificationFunc)(const std::string&, int32_t,
594 const std::unordered_map<std::string, BatteryConfig::NotificationConf>&);
595 void* handler = dlopen("libbattery_notification.z.so", RTLD_LAZY | RTLD_NODELETE);
596 if (handler == nullptr) {
597 BATTERY_HILOGE(FEATURE_BATT_INFO, "dlopen HandleNotificationFunc failed, reason : %{public}s", dlerror());
598 return false;
599 }
600 HandleNotificationFunc HandleNotification =
601 reinterpret_cast<HandleNotificationFunc>(dlsym(handler, "HandleNotification"));
602 if (HandleNotification == nullptr) {
603 BATTERY_HILOGE(FEATURE_BATT_INFO, "HandleNotificationFunc is null, reason : %{public}s", dlerror());
604 dlclose(handler);
605 handler = nullptr;
606 return false;
607 }
608 auto nConfMap = BatteryConfig::GetInstance().GetNotificationConf();
609 for (auto& item : iter->second) {
610 HandleNotification(item.name, item.action, nConfMap);
611 BATTERY_HILOGI(COMP_SVC, "popupName=%{public}s, popupAction=%{public}d", item.name.c_str(), item.action);
612 }
613 dlclose(handler);
614 handler = nullptr;
615 #endif
616 return true;
617 }
618
619 } // namespace PowerMgr
620 } // namespace OHOS
621