1 /*
2 * Copyright (c) 2021 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_service.h"
17 #include <unistd.h>
18 #include "battery_dump.h"
19 #include "file_ex.h"
20 #include "system_ability_definition.h"
21 #include "battery_log.h"
22 #include "power_mgr_client.h"
23 #include "v1_0/battery_interface_proxy.h"
24 #include "display_manager.h"
25 #include "ui_service_mgr_client.h"
26 #include "wm_common.h"
27
28 namespace OHOS {
29 namespace PowerMgr {
30 namespace {
31 const std::string BATTERY_SERVICE_NAME = "BatteryService";
32 const std::string BATTERY_LOW_CAPACITY_PARAMS = "{\"cancelButton\":\"LowCapacity\"}";
33 constexpr int32_t HELP_DMUP_PARAM = 2;
34 constexpr int32_t BATTERY_LOW_CAPACITY = 10;
35 constexpr int32_t UI_DIALOG_POWER_WIDTH_NARROW = 400;
36 constexpr int32_t UI_DIALOG_POWER_HEIGHT_NARROW = 240;
37 constexpr int32_t UI_DEFAULT_WIDTH = 2560;
38 constexpr int32_t UI_DEFAULT_HEIGHT = 1600;
39 constexpr int32_t UI_DEFAULT_BUTTOM_CLIP = 50 * 2;
40 constexpr int32_t UI_HALF = 2;
41 constexpr int32_t BATTERY_FULL_CAPACITY = 100;
42 constexpr int32_t SEC_TO_MSEC = 1000;
43 constexpr int32_t NSEC_TO_MSEC = 1000000;
44 constexpr int32_t BATTERY_EMERGENCY_THRESHOLD = 5;
45 constexpr int32_t BATTERY_LOW_THRESHOLD = 20;
46 constexpr int32_t BATTERY_NORMAL_THRESHOLD = 90;
47 constexpr int32_t BATTERY_HIGH_THRESHOLD = 95;
48 sptr<BatteryService> g_service;
49 int32_t g_lastChargeState = 0;
50 bool g_initConfig = true;
51 bool g_lastLowCapacity = false;
52 }
53
54 const bool G_REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(
55 DelayedSpSingleton<BatteryService>::GetInstance().GetRefPtr());
56 sptr<IBatteryInterface> ibatteryInterface;
57
BatteryService()58 BatteryService::BatteryService()
59 : SystemAbility(POWER_MANAGER_BATT_SERVICE_ID, true)
60 {
61 }
62
~BatteryService()63 BatteryService::~BatteryService() {}
64
GetCurrentTime()65 static int64_t GetCurrentTime()
66 {
67 timespec tm {};
68 clock_gettime(CLOCK_MONOTONIC, &tm);
69
70 return tm.tv_sec * SEC_TO_MSEC + (tm.tv_nsec / NSEC_TO_MSEC);
71 }
72
OnDump()73 void BatteryService::OnDump()
74 {
75 BATTERY_HILOGD(COMP_SVC, "OnDump");
76 }
77
OnStart()78 void BatteryService::OnStart()
79 {
80 if (ready_) {
81 BATTERY_HILOGD(COMP_SVC, "Service is ready, nothing to do");
82 return;
83 }
84 if (!(Init())) {
85 BATTERY_HILOGE(COMP_SVC, "Call init failed");
86 return;
87 }
88 if (!(InitBatteryd())) {
89 BATTERY_HILOGE(COMP_SVC, "Call initBatteryd failed");
90 return;
91 }
92 if (!Publish(this)) {
93 BATTERY_HILOGE(COMP_SVC, "Register to system ability manager failed");
94 return;
95 }
96 ready_ = true;
97 }
98
Init()99 bool BatteryService::Init()
100 {
101 if (!eventRunner_) {
102 eventRunner_ = AppExecFwk::EventRunner::Create(BATTERY_SERVICE_NAME);
103 if (eventRunner_ == nullptr) {
104 BATTERY_HILOGE(COMP_SVC, "Init failed due to create EventRunner");
105 return false;
106 }
107 }
108 if (!handler_) {
109 handler_ = std::make_shared<BatteryServiceEventHandler>(eventRunner_,
110 DelayedSpSingleton<BatteryService>::GetInstance());
111 if (handler_ == nullptr) {
112 BATTERY_HILOGE(COMP_SVC, "Init failed due to create handler error");
113 return false;
114 }
115 }
116
117 return true;
118 }
119
InitBatteryd()120 bool BatteryService::InitBatteryd()
121 {
122 sptr<OHOS::HDI::Battery::V1_0::IBatteryCallback> callback = new OHOS::HDI::Battery::V1_0::BatteryCallbackImpl();
123 ibatteryInterface = OHOS::HDI::Battery::V1_0::IBatteryInterface::Get();
124 if (ibatteryInterface == nullptr) {
125 BATTERY_HILOGE(COMP_SVC, "ibatteryInterface is nullptr");
126 return false;
127 }
128 ErrCode ret = ibatteryInterface->Register(callback);
129
130 BatteryCallbackImpl::BatteryEventCallback eventCb =
131 std::bind(&BatteryService::HandleBatteryCallbackEvent, this, std::placeholders::_1);
132 BatteryCallbackImpl::RegisterBatteryEvent(eventCb);
133
134 BATTERY_HILOGD(COMP_SVC, "InitBatteryd ret: %{public}d", ret);
135 return SUCCEEDED(ret);
136 }
137
InitConfig()138 void BatteryService::InitConfig()
139 {
140 batteryConfig_ = std::make_unique<HDI::Battery::V1_0::BatteryConfig>();
141 if (batteryConfig_ == nullptr) {
142 BATTERY_HILOGE(COMP_SVC, "instantiate batteryconfig error.");
143 return;
144 }
145 batteryConfig_->Init();
146
147 batteryLed_ = std::make_unique<HDI::Battery::V1_0::BatteryLed>();
148 if (batteryLed_ == nullptr) {
149 BATTERY_HILOGE(COMP_SVC, "instantiate BatteryLed error.");
150 return;
151 }
152 batteryLed_->InitLedsSysfs();
153 }
154
HandleBatteryCallbackEvent(const OHOS::HDI::Battery::V1_0::BatteryInfo & event)155 int32_t BatteryService::HandleBatteryCallbackEvent(const OHOS::HDI::Battery::V1_0::BatteryInfo& event)
156 {
157 BatteryInfo batteryInfo;
158 BATTERY_HILOGD(COMP_SVC,
159 "capacity=%{public}d, voltage=%{public}d, temperature=%{public}d, " \
160 "healthState=%{public}d, pluggedType=%{public}d, pluggedMaxCurrent=%{public}d, " \
161 "pluggedMaxVoltage=%{public}d, chargeState=%{public}d, chargeCounter=%{public}d, present=%{public}d, " \
162 "technology=%{public}s", event.capacity, event.voltage,
163 event.temperature, event.healthState, event.pluggedType,
164 event.pluggedMaxCurrent, event.pluggedMaxVoltage, event.chargeState,
165 event.chargeCounter, event.present, event.technology.c_str());
166
167 batteryInfo.SetCapacity(event.capacity);
168 batteryInfo.SetVoltage(event.voltage);
169 batteryInfo.SetTemperature(event.temperature);
170 batteryInfo.SetHealthState(BatteryHealthState(event.healthState));
171 batteryInfo.SetPluggedType(BatteryPluggedType(event.pluggedType));
172 batteryInfo.SetPluggedMaxCurrent(event.pluggedMaxCurrent);
173 batteryInfo.SetPluggedMaxVoltage(event.pluggedMaxVoltage);
174 batteryInfo.SetChargeState(BatteryChargeState(event.chargeState));
175 batteryInfo.SetChargeCounter(event.chargeCounter);
176 batteryInfo.SetPresent(event.present);
177 batteryInfo.SetTechnology(event.technology);
178
179 if (g_initConfig) {
180 InitConfig();
181 g_initConfig = false;
182 }
183 batteryLed_->UpdateLedColor(event.chargeState, event.capacity);
184 WakeupDevice(event.chargeState);
185 HandlePopupEvent(event.capacity);
186 CalculateRemainingChargeTime(event.capacity);
187
188 BatteryServiceSubscriber::Update(batteryInfo);
189 HandleTemperature(event.temperature);
190 HandleCapacity(event.capacity, event.chargeState);
191 return ERR_OK;
192 }
193
OnStop()194 void BatteryService::OnStop()
195 {
196 if (!ready_) {
197 return;
198 }
199 eventRunner_.reset();
200 handler_.reset();
201 ready_ = false;
202
203 if (ibatteryInterface == nullptr) {
204 BATTERY_HILOGE(COMP_SVC, "ibatteryInterface is nullptr");
205 return;
206 }
207 ibatteryInterface->UnRegister();
208 }
209
WakeupDevice(const int32_t & chargestate)210 void BatteryService::WakeupDevice(const int32_t& chargestate)
211 {
212 if ((g_lastChargeState == CHARGE_STATE_NONE || g_lastChargeState == CHARGE_STATE_RESERVED) &&
213 (chargestate != CHARGE_STATE_NONE && chargestate !=CHARGE_STATE_RESERVED)) {
214 auto& powerMgrClient = PowerMgrClient::GetInstance();
215 powerMgrClient.WakeupDevice();
216 }
217 g_lastChargeState = chargestate;
218 return;
219 }
220
HandlePopupEvent(const int32_t capacity)221 void BatteryService::HandlePopupEvent(const int32_t capacity)
222 {
223 bool ret = false;
224 if ((capacity < BATTERY_LOW_CAPACITY) && (g_lastLowCapacity == false)) {
225 ret = ShowDialog(BATTERY_LOW_CAPACITY_PARAMS);
226 if (!ret) {
227 BATTERY_HILOGI(COMP_SVC, "failed to popup");
228 return;
229 }
230 g_lastLowCapacity = true;
231 }
232
233 if (capacity >= BATTERY_LOW_CAPACITY) {
234 g_lastLowCapacity = false;
235 }
236 }
237
ShowDialog(const std::string & params)238 bool BatteryService::ShowDialog(const std::string ¶ms)
239 {
240 int pos_x;
241 int pos_y;
242 int width;
243 int height;
244 bool wideScreen;
245
246 GetDisplayPosition(pos_x, pos_y, width, height, wideScreen);
247
248 if (params.empty()) {
249 return false;
250 }
251
252 Ace::UIServiceMgrClient::GetInstance()->ShowDialog(
253 "battery_dialog",
254 params,
255 OHOS::Rosen::WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW,
256 pos_x,
257 pos_y,
258 width,
259 height,
260 [this](int32_t id, const std::string& event, const std::string& params) {
261 BATTERY_HILOGD(COMP_SVC, "Dialog callback: %{public}s, %{public}s", event.c_str(), params.c_str());
262 if (event == "EVENT_CANCEL") {
263 Ace::UIServiceMgrClient::GetInstance()->CancelDialog(id);
264 }
265 });
266 return true;
267 }
268
GetDisplayPosition(int32_t & offsetX,int32_t & offsetY,int32_t & width,int32_t & height,bool & wideScreen)269 void BatteryService::GetDisplayPosition(
270 int32_t& offsetX, int32_t& offsetY, int32_t& width, int32_t& height, bool& wideScreen)
271 {
272 wideScreen = true;
273 auto display = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
274 if (display == nullptr) {
275 BATTERY_HILOGI(COMP_SVC, "dialog GetDefaultDisplay fail, try again.");
276 display = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
277 }
278
279 if (display != nullptr) {
280 BATTERY_HILOGI(COMP_SVC, "display size: %{public}d x %{public}d",
281 display->GetWidth(), display->GetHeight());
282 if (display->GetWidth() < display->GetHeight()) {
283 BATTERY_HILOGI(COMP_SVC, "share dialog narrow.");
284 const int NARROW_WIDTH_N = 3;
285 const int NARROW_WIDTH_D = 4;
286 const int NARROW_HEIGHT_RATE = 8;
287 wideScreen = false;
288 width = display->GetWidth() * NARROW_WIDTH_N / NARROW_WIDTH_D;
289 height = display->GetHeight() / NARROW_HEIGHT_RATE;
290 } else {
291 BATTERY_HILOGI(COMP_SVC, "share dialog wide.");
292 const int NARROW_WIDTH_N = 1;
293 const int NARROW_WIDTH_D = 3;
294 const int NARROW_HEIGHT_RATE = 6;
295 wideScreen = true;
296 width = display->GetWidth() * NARROW_WIDTH_N / NARROW_WIDTH_D;
297 height = display->GetHeight() / NARROW_HEIGHT_RATE;
298 }
299 offsetX = (display->GetWidth() - width) / UI_HALF;
300 offsetY = display->GetHeight() - height - UI_DEFAULT_BUTTOM_CLIP;
301 } else {
302 BATTERY_HILOGI(COMP_SVC, "dialog get display fail, use default wide.");
303 wideScreen = false;
304 width = UI_DIALOG_POWER_WIDTH_NARROW;
305 height = UI_DIALOG_POWER_HEIGHT_NARROW;
306 offsetX = (UI_DEFAULT_WIDTH - width) / UI_HALF;
307 offsetY = UI_DEFAULT_HEIGHT - height - UI_DEFAULT_BUTTOM_CLIP;
308 }
309 BATTERY_HILOGI(COMP_SVC, "GetDisplayPosition: %{public}d, %{public}d (%{public}d x %{public}d)",
310 offsetX, offsetY, width, height);
311 }
312
HandleTemperature(const int32_t & temperature)313 void BatteryService::HandleTemperature(const int32_t& temperature)
314 {
315 auto tempConf = batteryConfig_->GetTempConf();
316 BATTERY_HILOGI(COMP_SVC, "temperature=%{public}d, tempConf.lower=%{public}d, tempConf.upper=%{public}d",
317 temperature, tempConf.lower, tempConf.upper);
318
319 auto& powerMgrClient = PowerMgrClient::GetInstance();
320 if (((temperature <= tempConf.lower) || (temperature >= tempConf.upper)) && (tempConf.lower != tempConf.upper)) {
321 std::string reason = "TemperatureOutOfRange";
322 powerMgrClient.ShutDownDevice(reason);
323 }
324 return;
325 }
326
HandleCapacity(const int32_t & capacity,const int32_t & chargeState)327 void BatteryService::HandleCapacity(const int32_t& capacity, const int32_t& chargeState)
328 {
329 auto& powerMgrClient = PowerMgrClient::GetInstance();
330 if ((capacity <= batteryConfig_->GetCapacityConf()) &&
331 ((chargeState == CHARGE_STATE_NONE) || (chargeState == CHARGE_STATE_RESERVED))) {
332 std::string reason = "LowCapacity";
333 powerMgrClient.ShutDownDevice(reason);
334 }
335 return;
336 }
337
GetCapacity()338 int32_t BatteryService::GetCapacity()
339 {
340 int capacity;
341 BATTERY_HILOGD(FEATURE_BATT_INFO, "Enter");
342 if (ibatteryInterface == nullptr) {
343 BATTERY_HILOGE(FEATURE_BATT_INFO, "ibatteryInterface is nullptr");
344 return ERR_NO_INIT;
345 }
346 ibatteryInterface->GetCapacity(capacity);
347 return capacity;
348 }
349
ChangePath(const std::string path)350 void BatteryService::ChangePath(const std::string path)
351 {
352 BATTERY_HILOGD(FEATURE_BATT_INFO, "Enter");
353 if (ibatteryInterface == nullptr) {
354 BATTERY_HILOGE(FEATURE_BATT_INFO, "ibatteryInterface is nullptr");
355 return;
356 }
357 ibatteryInterface->ChangePath(path);
358 return;
359 }
360
GetChargingStatus()361 BatteryChargeState BatteryService::GetChargingStatus()
362 {
363 BATTERY_HILOGD(FEATURE_BATT_INFO, "Enter");
364 OHOS::HDI::Battery::V1_0::BatteryChargeState chargeState = OHOS::HDI::Battery::V1_0::BatteryChargeState(0);
365
366 if (ibatteryInterface == nullptr) {
367 BATTERY_HILOGE(FEATURE_BATT_INFO, "ibatteryInterface is nullptr");
368 return OHOS::PowerMgr::BatteryChargeState(chargeState);
369 }
370
371 ibatteryInterface->GetChargeState(chargeState);
372 return OHOS::PowerMgr::BatteryChargeState(chargeState);
373 }
374
GetHealthStatus()375 BatteryHealthState BatteryService::GetHealthStatus()
376 {
377 BATTERY_HILOGD(FEATURE_BATT_INFO, "Enter");
378 OHOS::HDI::Battery::V1_0::BatteryHealthState healthState = OHOS::HDI::Battery::V1_0::BatteryHealthState(0);
379
380 if (ibatteryInterface == nullptr) {
381 BATTERY_HILOGE(FEATURE_BATT_INFO, "ibatteryInterface is nullptr");
382 return OHOS::PowerMgr::BatteryHealthState(healthState);
383 }
384
385 ibatteryInterface->GetHealthState(healthState);
386 return OHOS::PowerMgr::BatteryHealthState(healthState);
387 }
388
GetPluggedType()389 BatteryPluggedType BatteryService::GetPluggedType()
390 {
391 OHOS::HDI::Battery::V1_0::BatteryPluggedType pluggedType = OHOS::HDI::Battery::V1_0::BatteryPluggedType(0);
392
393 if (ibatteryInterface == nullptr) {
394 BATTERY_HILOGE(FEATURE_BATT_INFO, "ibatteryInterface is nullptr");
395 return OHOS::PowerMgr::BatteryPluggedType(pluggedType);
396 }
397
398 ibatteryInterface->GetPluggedType(pluggedType);
399 return OHOS::PowerMgr::BatteryPluggedType(pluggedType);
400 }
401
GetVoltage()402 int32_t BatteryService::GetVoltage()
403 {
404 int voltage;
405 if (ibatteryInterface == nullptr) {
406 BATTERY_HILOGE(FEATURE_BATT_INFO, "ibatteryInterface is nullptr");
407 return ERR_NO_INIT;
408 }
409 ibatteryInterface->GetVoltage(voltage);
410 return voltage;
411 }
412
GetPresent()413 bool BatteryService::GetPresent()
414 {
415 bool present = false;
416
417 if (ibatteryInterface == nullptr) {
418 BATTERY_HILOGE(FEATURE_BATT_INFO, "ibatteryInterface is nullptr");
419 return present;
420 }
421
422 ibatteryInterface->GetPresent(present);
423 return present;
424 }
425
GetTechnology()426 std::string BatteryService::GetTechnology()
427 {
428 if (ibatteryInterface == nullptr) {
429 BATTERY_HILOGE(FEATURE_BATT_INFO, "ibatteryInterface is nullptr");
430 return "";
431 }
432
433 std::string technology;
434 ibatteryInterface->GetTechnology(technology);
435 return technology;
436 }
437
GetBatteryTemperature()438 int32_t BatteryService::GetBatteryTemperature()
439 {
440 int temperature;
441 BATTERY_HILOGD(FEATURE_BATT_INFO, "Enter");
442 if (ibatteryInterface == nullptr) {
443 BATTERY_HILOGE(FEATURE_BATT_INFO, "ibatteryInterface is nullptr");
444 return ERR_NO_INIT;
445 }
446 ibatteryInterface->GetTemperature(temperature);
447 return temperature;
448 }
449
CalculateRemainingChargeTime(int32_t capacity)450 void BatteryService::CalculateRemainingChargeTime(int32_t capacity)
451 {
452 if (capacity > BATTERY_FULL_CAPACITY) {
453 BATTERY_HILOGE(FEATURE_BATT_INFO, "capacity error");
454 return;
455 }
456
457 int64_t onceTime = 0;
458 if (((capacity - lastCapacity_) >= 1) && (lastCapacity_ != 0)) {
459 onceTime = (GetCurrentTime() - lastTime_) / (capacity - lastCapacity_);
460 remainTime_ = (BATTERY_FULL_CAPACITY - capacity) * onceTime;
461 }
462
463 lastCapacity_ = capacity;
464 lastTime_ = GetCurrentTime();
465 }
466
GetRemainingChargeTime()467 int64_t BatteryService::GetRemainingChargeTime()
468 {
469 return remainTime_;
470 }
471
GetBatteryLevel()472 int32_t BatteryService::GetBatteryLevel()
473 {
474 int32_t batteryLevel;
475 int32_t capacity = GetCapacity();
476 if (capacity < BATTERY_EMERGENCY_THRESHOLD) {
477 batteryLevel = static_cast<int32_t>(BatteryLevel::LEVEL_EMERGENCY);
478 } else if (capacity <= BATTERY_LOW_THRESHOLD) {
479 batteryLevel = static_cast<int32_t>(BatteryLevel::LEVEL_LOW);
480 } else if (capacity <= BATTERY_NORMAL_THRESHOLD) {
481 batteryLevel = static_cast<int32_t>(BatteryLevel::LEVEL_NORMAL);
482 } else if (capacity <= BATTERY_HIGH_THRESHOLD) {
483 batteryLevel = static_cast<int32_t>(BatteryLevel::LEVEL_HIGH);
484 } else {
485 batteryLevel = static_cast<int32_t>(BatteryLevel::LEVEL_NONE);
486 }
487
488 return batteryLevel;
489 }
490
Dump(int32_t fd,const std::vector<std::u16string> & args)491 int32_t BatteryService::Dump(int32_t fd, const std::vector<std::u16string> &args)
492 {
493 g_service = DelayedSpSingleton<BatteryService>::GetInstance();
494 BatteryDump& batteryDump = BatteryDump::GetInstance();
495 if ((args.empty()) || (args[0].size() != HELP_DMUP_PARAM)) {
496 BATTERY_HILOGD(FEATURE_BATT_INFO, "param cannot be empty or the length is not 2");
497 dprintf(fd, "cmd param number is not equal to 2\n");
498 batteryDump.DumpHelp(fd);
499 return ERR_NO_INIT;
500 }
501
502 bool helpRet = batteryDump.DumpBatteryHelp(fd, args);
503 bool getBatteryInfo = batteryDump.GetBatteryInfo(fd, g_service, args);
504 bool total = helpRet + getBatteryInfo;
505 if (!total) {
506 dprintf(fd, "cmd param is error\n");
507 batteryDump.DumpHelp(fd);
508 return ERR_NO_INIT;
509 }
510
511 return ERR_OK;
512 }
513 } // namespace PowerMgr
514 } // namespace OHOS
515
516