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 "charging_sound.h"
21 #endif
22 #include "common_event_data.h"
23 #include "common_event_manager.h"
24 #include "common_event_publish_info.h"
25 #include "common_event_support.h"
26 #include "errors.h"
27 #include "hisysevent.h"
28 #include "if_system_ability_manager.h"
29 #include "iservice_registry.h"
30 #include "string_ex.h"
31 #include "system_ability_definition.h"
32
33 #include "battery_config.h"
34 #include "battery_log.h"
35 #include "battery_service.h"
36 #include "power_vibrator.h"
37 #include "power_mgr_client.h"
38
39 using namespace OHOS::AAFwk;
40 using namespace OHOS::EventFwk;
41 using namespace OHOS::HiviewDFX;
42
43 namespace OHOS {
44 namespace PowerMgr {
45 bool g_batteryLowOnce = false;
46 bool g_batteryOkOnce = false;
47 bool g_batteryConnectOnce = false;
48 bool g_batteryDisconnectOnce = false;
49 bool g_batteryChargingOnce = false;
50 bool g_batteryDischargingOnce = false;
51 bool g_commonEventInitSuccess = false;
52 OHOS::PowerMgr::BatteryCapacityLevel g_lastCapacityLevel = OHOS::PowerMgr::BatteryCapacityLevel::LEVEL_NONE;
53 const std::string POWER_SUPPLY = "SUBSYSTEM=power_supply";
54 const std::string SHUTDOWN = "shutdown";
55 const std::string REBOOT = "reboot";
56 const std::string SEND_COMMONEVENT = "sendcommonevent";
57 const std::string SEND_CUSTOMEVENT = "sendcustomevent";
58 const std::string BATTERY_CUSTOM_EVENT = "usual.event.battery.custom";
59 const std::string BATTERY_CUSTOM_EVENT_PREFIX = "usual.event.battery";
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 == SEND_CUSTOMEVENT) {
122 info.SetUevent(ueventName);
123 PublishCustomEvent(info, BATTERY_CUSTOM_EVENT);
124 } else if (ueventAct.compare(0, BATTERY_CUSTOM_EVENT_PREFIX.size(), BATTERY_CUSTOM_EVENT_PREFIX) == 0) {
125 info.SetUevent(ueventName);
126 PublishCustomEvent(info, ueventAct);
127 } else {
128 BATTERY_HILOGE(COMP_SVC, "undefine uevent act %{public}s", ueventAct.c_str());
129 }
130 }
131 BATTERY_HILOGI(COMP_SVC, "handle uevent info %{public}s", uevent.c_str());
132 }
133
PublishChargeTypeChangedEvent(const BatteryInfo & info)134 bool BatteryNotify::PublishChargeTypeChangedEvent(const BatteryInfo& info)
135 {
136 ChargeType chargeType = info.GetChargeType();
137 bool isSuccess = true;
138 if (batteryInfoChargeType_ == chargeType) {
139 BATTERY_HILOGD(COMP_SVC, "No need to send chargetype event");
140 return isSuccess;
141 }
142 batteryInfoChargeType_ = chargeType;
143 Want want;
144 want.SetAction(CommonEventSupport::COMMON_EVENT_CHARGE_TYPE_CHANGED);
145 CommonEventData data;
146 data.SetWant(want);
147 CommonEventPublishInfo publishInfo;
148 publishInfo.SetOrdered(false);
149
150 data.SetCode(static_cast<int32_t>(chargeType));
151 BATTERY_HILOGD(COMP_SVC, "publisher chargeType=%{public}d", chargeType);
152 isSuccess = CommonEventManager::PublishCommonEvent(data, publishInfo);
153 if (!isSuccess) {
154 BATTERY_HILOGD(COMP_SVC, "failed to publish battery charge type event");
155 }
156
157 return isSuccess;
158 }
159
IsCommonEventServiceAbilityExist() const160 bool BatteryNotify::IsCommonEventServiceAbilityExist() const
161 {
162 sptr<ISystemAbilityManager> sysMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
163 if (!sysMgr) {
164 BATTERY_HILOGE(COMP_SVC,
165 "IsCommonEventServiceAbilityExist Get ISystemAbilityManager failed, no SystemAbilityManager");
166 return false;
167 }
168 sptr<IRemoteObject> remote = sysMgr->CheckSystemAbility(COMMON_EVENT_SERVICE_ID);
169 if (!remote) {
170 BATTERY_HILOGE(COMP_SVC, "No CesServiceAbility");
171 return false;
172 }
173
174 if (!g_commonEventInitSuccess) {
175 BATTERY_HILOGI(COMP_SVC, "common event service ability init success");
176 g_commonEventInitSuccess = true;
177 }
178
179 return true;
180 }
181
PublishChangedEvent(const BatteryInfo & info)182 bool BatteryNotify::PublishChangedEvent(const BatteryInfo& info)
183 {
184 Want want;
185 int32_t capacity = info.GetCapacity();
186 int32_t pluggedType = static_cast<int32_t>(info.GetPluggedType());
187 int32_t temperature = info.GetTemperature();
188 int32_t healthState = static_cast<int32_t>(info.GetHealthState());
189 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_CAPACITY, capacity);
190 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_VOLTAGE, info.GetVoltage());
191 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_TEMPERATURE, temperature);
192 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_HEALTH_STATE, healthState);
193 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_PLUGGED_TYPE, pluggedType);
194 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_CHARGE_STATE, static_cast<int32_t>(info.GetChargeState()));
195 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_PRESENT, info.IsPresent());
196 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_TECHNOLOGY, info.GetTechnology());
197 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_UEVENT, info.GetUevent());
198
199 auto capacityLevel = g_service->GetCapacityLevel();
200 if (capacityLevel != g_lastCapacityLevel) {
201 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_CAPACITY_LEVEL, static_cast<int32_t>(capacityLevel));
202 g_lastCapacityLevel = capacityLevel;
203 }
204
205 want.SetAction(CommonEventSupport::COMMON_EVENT_BATTERY_CHANGED);
206 CommonEventData data;
207 data.SetWant(want);
208 CommonEventPublishInfo publishInfo;
209 publishInfo.SetOrdered(false);
210 if (capacity != lastCapacity_ || pluggedType != lastPluggedType_ ||
211 temperature != lastTemperature_ || healthState != lastHealthState_) {
212 HiSysEventWrite(HiSysEvent::Domain::BATTERY, "CHANGED", HiSysEvent::EventType::STATISTIC,
213 "LEVEL", capacity, "CHARGER", pluggedType, "VOLTAGE", info.GetVoltage(),
214 "TEMPERATURE", temperature, "HEALTH", healthState, "CURRENT", info.GetNowCurrent());
215 lastCapacity_ = capacity;
216 lastPluggedType_ = pluggedType;
217 lastTemperature_ = temperature;
218 lastHealthState_ = healthState;
219 }
220 bool isSuccess = CommonEventManager::PublishCommonEvent(data, publishInfo);
221 if (!isSuccess) {
222 BATTERY_HILOGE(FEATURE_BATT_INFO, "failed to publish BATTERY_CHANGED event");
223 }
224 return isSuccess;
225 }
226
PublishChangedEventInner(const BatteryInfo & info) const227 bool BatteryNotify::PublishChangedEventInner(const BatteryInfo& info) const
228 {
229 Want want;
230 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_PLUGGED_MAX_CURRENT, info.GetPluggedMaxCurrent());
231 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_PLUGGED_MAX_VOLTAGE, info.GetPluggedMaxVoltage());
232 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_PLUGGED_NOW_CURRENT, info.GetNowCurrent());
233 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_CHARGE_COUNTER, info.GetChargeCounter());
234
235 want.SetAction(BatteryInfo::COMMON_EVENT_BATTERY_CHANGED_INNER);
236 CommonEventData data;
237 data.SetWant(want);
238 CommonEventPublishInfo publishInfo;
239 publishInfo.SetOrdered(false);
240 const std::vector<std::string> permissionVec { "ohos.permission.POWER_OPTIMIZATION" };
241 publishInfo.SetSubscriberPermissions(permissionVec);
242
243 bool isSuccess = true;
244 isSuccess = CommonEventManager::PublishCommonEvent(data, publishInfo);
245 if (!isSuccess) {
246 BATTERY_HILOGE(FEATURE_BATT_INFO, "failed to publish BATTERY_CHANGED_INNER event");
247 }
248 return isSuccess;
249 }
250
PublishLowEvent(const BatteryInfo & info) const251 bool BatteryNotify::PublishLowEvent(const BatteryInfo& info) const
252 {
253 bool isSuccess = true;
254
255 if (info.GetCapacity() > lowCapacity_) {
256 g_batteryLowOnce = false;
257 return isSuccess;
258 }
259
260 if (g_batteryLowOnce) {
261 return isSuccess;
262 }
263
264 Want want;
265 want.SetAction(CommonEventSupport::COMMON_EVENT_BATTERY_LOW);
266 CommonEventData data;
267 data.SetWant(want);
268 CommonEventPublishInfo publishInfo;
269 publishInfo.SetOrdered(false);
270 data.SetCode(info.GetCapacity());
271 BATTERY_HILOGD(FEATURE_BATT_INFO, "publisher capacity=%{public}d", info.GetCapacity());
272 isSuccess = CommonEventManager::PublishCommonEvent(data, publishInfo);
273 if (!isSuccess) {
274 BATTERY_HILOGE(FEATURE_BATT_INFO, "failed to publish battery_low event");
275 }
276 g_batteryLowOnce = true;
277 return isSuccess;
278 }
279
PublishOkayEvent(const BatteryInfo & info) const280 bool BatteryNotify::PublishOkayEvent(const BatteryInfo& info) const
281 {
282 bool isSuccess = true;
283
284 if (info.GetCapacity() <= lowCapacity_) {
285 g_batteryOkOnce = false;
286 return isSuccess;
287 }
288
289 if (g_batteryOkOnce) {
290 return isSuccess;
291 }
292
293 Want want;
294 want.SetAction(CommonEventSupport::COMMON_EVENT_BATTERY_OKAY);
295 CommonEventData data;
296 data.SetWant(want);
297 CommonEventPublishInfo publishInfo;
298 publishInfo.SetOrdered(false);
299 data.SetCode(info.GetCapacity());
300 BATTERY_HILOGD(FEATURE_BATT_INFO, "publisher capacity=%{public}d", info.GetCapacity());
301 isSuccess = CommonEventManager::PublishCommonEvent(data, publishInfo);
302 if (!isSuccess) {
303 BATTERY_HILOGD(FEATURE_BATT_INFO, "failed to publish battery_okay event");
304 }
305 g_batteryOkOnce = true;
306 return isSuccess;
307 }
308
PublishPowerConnectedEvent(const BatteryInfo & info) const309 bool BatteryNotify::PublishPowerConnectedEvent(const BatteryInfo& info) const
310 {
311 bool isSuccess = true;
312
313 if ((info.GetPluggedType() == BatteryPluggedType::PLUGGED_TYPE_NONE) ||
314 (info.GetPluggedType() == BatteryPluggedType::PLUGGED_TYPE_BUTT)) {
315 g_batteryConnectOnce = false;
316 return isSuccess;
317 }
318
319 if (g_batteryConnectOnce) {
320 return isSuccess;
321 }
322 StartVibrator();
323 #ifdef BATTERY_MANAGER_ENABLE_CHARGING_SOUND
324 if (g_service && g_service->IsBootCompleted()) {
325 ChargingSound::GetInstance().Start();
326 }
327 #endif
328 Want want;
329 want.SetAction(CommonEventSupport::COMMON_EVENT_POWER_CONNECTED);
330 CommonEventData data;
331 data.SetWant(want);
332 CommonEventPublishInfo publishInfo;
333 publishInfo.SetOrdered(false);
334 data.SetCode(static_cast<int32_t>(info.GetPluggedType()));
335 BATTERY_HILOGD(FEATURE_BATT_INFO, "publisher pluggedtype=%{public}u",
336 static_cast<uint32_t>(info.GetPluggedType()));
337 isSuccess = CommonEventManager::PublishCommonEvent(data, publishInfo);
338 if (!isSuccess) {
339 BATTERY_HILOGE(FEATURE_BATT_INFO, "failed to publish power_connected event");
340 }
341
342 g_batteryConnectOnce = true;
343 return isSuccess;
344 }
345
StartVibrator() const346 void BatteryNotify::StartVibrator() const
347 {
348 std::shared_ptr<PowerVibrator> vibrator = PowerVibrator::GetInstance();
349 std::string scene = "start_charge";
350 vibrator->StartVibrator(scene);
351 }
352
PublishPowerDisconnectedEvent(const BatteryInfo & info) const353 bool BatteryNotify::PublishPowerDisconnectedEvent(const BatteryInfo& info) const
354 {
355 bool isSuccess = true;
356
357 if ((info.GetPluggedType() != BatteryPluggedType::PLUGGED_TYPE_NONE) &&
358 (info.GetPluggedType() != BatteryPluggedType::PLUGGED_TYPE_BUTT)) {
359 g_batteryDisconnectOnce = false;
360 return isSuccess;
361 }
362
363 if (g_batteryDisconnectOnce) {
364 return isSuccess;
365 }
366 #ifdef BATTERY_MANAGER_ENABLE_CHARGING_SOUND
367 if (g_service && g_service->IsBootCompleted()) {
368 ChargingSound::GetInstance().Stop();
369 }
370 #endif
371 Want want;
372 want.SetAction(CommonEventSupport::COMMON_EVENT_POWER_DISCONNECTED);
373 CommonEventData data;
374 data.SetWant(want);
375 CommonEventPublishInfo publishInfo;
376 publishInfo.SetOrdered(false);
377 data.SetCode(static_cast<int32_t>(info.GetPluggedType()));
378 BATTERY_HILOGD(FEATURE_BATT_INFO, "publisher pluggedtype=%{public}u",
379 static_cast<uint32_t>(info.GetPluggedType()));
380 isSuccess = CommonEventManager::PublishCommonEvent(data, publishInfo);
381 if (!isSuccess) {
382 BATTERY_HILOGD(FEATURE_BATT_INFO, "failed to publish power_disconnected event");
383 }
384
385 g_batteryDisconnectOnce = true;
386 return isSuccess;
387 }
388
PublishChargingEvent(const BatteryInfo & info) const389 bool BatteryNotify::PublishChargingEvent(const BatteryInfo& info) const
390 {
391 bool isSuccess = true;
392
393 if ((info.GetChargeState() != BatteryChargeState::CHARGE_STATE_ENABLE) &&
394 (info.GetChargeState() != BatteryChargeState::CHARGE_STATE_FULL)) {
395 g_batteryChargingOnce = false;
396 return isSuccess;
397 }
398
399 if (g_batteryChargingOnce) {
400 return isSuccess;
401 }
402
403 Want want;
404 want.SetAction(CommonEventSupport::COMMON_EVENT_CHARGING);
405 CommonEventData data;
406 data.SetWant(want);
407 CommonEventPublishInfo publishInfo;
408 publishInfo.SetOrdered(false);
409 data.SetCode(static_cast<int32_t>(info.GetChargeState()));
410 BATTERY_HILOGD(FEATURE_BATT_INFO, "publisher chargeState=%{public}u",
411 static_cast<uint32_t>(info.GetChargeState()));
412 isSuccess = CommonEventManager::PublishCommonEvent(data, publishInfo);
413 if (!isSuccess) {
414 BATTERY_HILOGD(FEATURE_BATT_INFO, "failed to publish battery charing event");
415 }
416
417 g_batteryChargingOnce = true;
418 return isSuccess;
419 }
420
PublishDischargingEvent(const BatteryInfo & info) const421 bool BatteryNotify::PublishDischargingEvent(const BatteryInfo& info) const
422 {
423 bool isSuccess = true;
424
425 if ((info.GetChargeState() == BatteryChargeState::CHARGE_STATE_ENABLE) ||
426 (info.GetChargeState() == BatteryChargeState::CHARGE_STATE_FULL)) {
427 g_batteryDischargingOnce = false;
428 return isSuccess;
429 }
430
431 if (g_batteryDischargingOnce) {
432 return isSuccess;
433 }
434
435 Want want;
436 want.SetAction(CommonEventSupport::COMMON_EVENT_DISCHARGING);
437 CommonEventData data;
438 data.SetWant(want);
439 CommonEventPublishInfo publishInfo;
440 publishInfo.SetOrdered(false);
441 data.SetCode(static_cast<int32_t>(info.GetChargeState()));
442 BATTERY_HILOGD(FEATURE_BATT_INFO, "publisher chargeState=%{public}u",
443 static_cast<uint32_t>(info.GetChargeState()));
444 isSuccess = CommonEventManager::PublishCommonEvent(data, publishInfo);
445 if (!isSuccess) {
446 BATTERY_HILOGD(FEATURE_BATT_INFO, "failed to publish battery charing event");
447 }
448
449 g_batteryDischargingOnce = true;
450 return isSuccess;
451 }
452
PublishCustomEvent(const BatteryInfo & info,const std::string & commonEventName) const453 bool BatteryNotify::PublishCustomEvent(const BatteryInfo& info, const std::string& commonEventName) const
454 {
455 Want want;
456 want.SetParam(BatteryInfo::COMMON_EVENT_KEY_UEVENT, info.GetUevent());
457 want.SetAction(commonEventName);
458 CommonEventData data;
459 data.SetWant(want);
460 CommonEventPublishInfo publishInfo;
461 publishInfo.SetOrdered(false);
462 const std::vector<std::string> permissionVec { "ohos.permission.POWER_OPTIMIZATION" };
463 publishInfo.SetSubscriberPermissions(permissionVec);
464
465 bool isSuccess = CommonEventManager::PublishCommonEvent(data, publishInfo);
466 if (!isSuccess) {
467 BATTERY_HILOGD(FEATURE_BATT_INFO, "failed to publish battery custom event");
468 }
469 return isSuccess;
470 }
471 } // namespace PowerMgr
472 } // namespace OHOS
473