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