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