• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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