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