1/*
2 * Copyright (c) 2022 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_interface_impl.h"
17#include "battery_config.h"
18#include "battery_log.h"
19#include "battery_xcollie.h"
20
21namespace OHOS {
22namespace HDI {
23namespace Battery {
24namespace V2_0 {
25namespace {
26sptr<BatteryInterfaceImpl::BatteryDeathRecipient> g_deathRecipient = nullptr;
27bool g_isHdiStart = false;
28}
29
30extern "C" IBatteryInterface *BatteryInterfaceImplGetInstance(void)
31{
32    using OHOS::HDI::Battery::V2_0::BatteryInterfaceImpl;
33    BatteryInterfaceImpl *service = new (std::nothrow) BatteryInterfaceImpl();
34    if (service == nullptr) {
35        return nullptr;
36    }
37
38    if (service->Init() != HDF_SUCCESS) {
39        delete service;
40        return nullptr;
41    }
42
43    return service;
44}
45
46int32_t BatteryInterfaceImpl::Init()
47{
48    powerSupplyProvider_ = std::make_unique<OHOS::HDI::Battery::V2_0::PowerSupplyProvider>();
49    if (powerSupplyProvider_ == nullptr) {
50        BATTERY_HILOGE(COMP_HDI, "make_unique PowerSupplyProvider error");
51        return HDF_ERR_MALLOC_FAIL;
52    }
53    powerSupplyProvider_->InitBatteryPath();
54    powerSupplyProvider_->InitPowerSupplySysfs();
55
56    auto& batteryConfig = BatteryConfig::GetInstance();
57    batteryConfig.ParseConfig();
58
59    loop_ = std::make_unique<OHOS::HDI::Battery::V2_0::BatteryThread>();
60    if (loop_ == nullptr) {
61        BATTERY_HILOGE(COMP_HDI, "make_unique BatteryThread error");
62        return HDF_ERR_MALLOC_FAIL;
63    }
64
65    if (batteryCallback_ != nullptr) {
66        loop_->InitCallback(batteryCallback_);
67    } else {
68        BATTERY_HILOGW(COMP_HDI, "batteryCallback_ is nullptr");
69    }
70    loop_->StartThread(this);
71
72    return HDF_SUCCESS;
73}
74
75int32_t BatteryInterfaceImpl::Register(const sptr<IBatteryCallback>& callback)
76{
77    if (callback == nullptr) {
78        BATTERY_HILOGW(FEATURE_BATT_INFO, "callback is nullptr");
79        return HDF_ERR_INVALID_PARAM;
80    }
81    if (!g_isHdiStart) {
82        batteryCallback_ = callback;
83        loop_->InitCallback(batteryCallback_);
84
85        g_deathRecipient = new BatteryInterfaceImpl::BatteryDeathRecipient(this);
86        if (g_deathRecipient == nullptr) {
87            BATTERY_HILOGE(COMP_HDI, "Failed to allocate BatteryDeathRecipient");
88            return HDF_ERR_MALLOC_FAIL;
89        }
90        AddBatteryDeathRecipient(batteryCallback_);
91        g_isHdiStart = true;
92    }
93    return HDF_SUCCESS;
94}
95
96int32_t BatteryInterfaceImpl::UnRegister()
97{
98    RemoveBatteryDeathRecipient(batteryCallback_);
99    batteryCallback_ = nullptr;
100    g_isHdiStart = false;
101    return HDF_SUCCESS;
102}
103
104int32_t BatteryInterfaceImpl::ChangePath(const std::string& path)
105{
106    powerSupplyProvider_->SetSysFilePath(path);
107    powerSupplyProvider_->InitPowerSupplySysfs();
108    return HDF_SUCCESS;
109}
110
111int32_t BatteryInterfaceImpl::GetCapacity(int32_t& capacity)
112{
113    return powerSupplyProvider_->ParseCapacity(&capacity);
114}
115
116int32_t BatteryInterfaceImpl::GetVoltage(int32_t& voltage)
117{
118    return powerSupplyProvider_->ParseVoltage(&voltage);
119}
120
121int32_t BatteryInterfaceImpl::GetTemperature(int32_t& temperature)
122{
123    return powerSupplyProvider_->ParseTemperature(&temperature);
124}
125
126int32_t BatteryInterfaceImpl::GetHealthState(BatteryHealthState& healthState)
127{
128    int32_t state = 0;
129    int32_t ret = powerSupplyProvider_->ParseHealthState(&state);
130    if (ret != HDF_SUCCESS) {
131        return ret;
132    }
133
134    healthState = BatteryHealthState(state);
135    return HDF_SUCCESS;
136}
137
138int32_t BatteryInterfaceImpl::GetPluggedType(BatteryPluggedType& pluggedType)
139{
140    int32_t type = 0;
141    int32_t ret = powerSupplyProvider_->ParsePluggedType(&type);
142    if (ret != HDF_SUCCESS) {
143        return ret;
144    }
145
146    pluggedType = BatteryPluggedType(type);
147    return HDF_SUCCESS;
148}
149
150int32_t BatteryInterfaceImpl::GetChargeState(BatteryChargeState& chargeState)
151{
152    int32_t state = 0;
153    int32_t ret = powerSupplyProvider_->ParseChargeState(&state);
154    if (ret != HDF_SUCCESS) {
155        return ret;
156    }
157
158    chargeState = BatteryChargeState(state);
159    return HDF_SUCCESS;
160}
161
162int32_t BatteryInterfaceImpl::GetPresent(bool& present)
163{
164    int8_t isPresent = 0;
165    int32_t ret = powerSupplyProvider_->ParsePresent(&isPresent);
166    if (ret != HDF_SUCCESS) {
167        return ret;
168    }
169
170    present = bool(isPresent);
171    return HDF_SUCCESS;
172}
173
174int32_t BatteryInterfaceImpl::GetTechnology(std::string& technology)
175{
176    return powerSupplyProvider_->ParseTechnology(technology);
177}
178
179int32_t BatteryInterfaceImpl::GetTotalEnergy(int32_t& totalEnergy)
180{
181    return powerSupplyProvider_->ParseTotalEnergy(&totalEnergy);
182}
183
184int32_t BatteryInterfaceImpl::GetCurrentAverage(int32_t& curAverage)
185{
186    return powerSupplyProvider_->ParseCurrentAverage(&curAverage);
187}
188
189int32_t BatteryInterfaceImpl::GetCurrentNow(int32_t& curNow)
190{
191    return powerSupplyProvider_->ParseCurrentNow(&curNow);
192}
193
194int32_t BatteryInterfaceImpl::GetRemainEnergy(int32_t& remainEnergy)
195{
196    return powerSupplyProvider_->ParseRemainEnergy(&remainEnergy);
197}
198
199int32_t BatteryInterfaceImpl::GetBatteryInfo(BatteryInfo& info)
200{
201    if (powerSupplyProvider_ == nullptr) {
202        return HDF_FAILURE;
203    }
204
205    BatterydInfo batteryInfo = powerSupplyProvider_->GetBatteryInfo();
206    info.capacity = batteryInfo.capacity_;
207    info.voltage = batteryInfo.voltage_;
208    info.temperature = batteryInfo.temperature_;
209    info.healthState = batteryInfo.healthState_;
210    info.pluggedType = batteryInfo.pluggedType_;
211    info.pluggedMaxCurrent = batteryInfo.pluggedMaxCurrent_;
212    info.pluggedMaxVoltage = batteryInfo.pluggedMaxVoltage_;
213    info.chargeState = batteryInfo.chargeState_;
214    info.chargeCounter = batteryInfo.chargeCounter_;
215    info.curNow = batteryInfo.curNow_;
216    info.curAverage = batteryInfo.curAverage_;
217    info.remainEnergy = batteryInfo.remainEnergy_;
218    info.totalEnergy = batteryInfo.totalEnergy_;
219    info.present = batteryInfo.present_;
220    info.technology = batteryInfo.technology_;
221
222    return HDF_SUCCESS;
223}
224
225int32_t BatteryInterfaceImpl::SetChargingLimit(const std::vector<ChargingLimit>& chargingLimit)
226{
227    auto& batteryConfig = BatteryConfig::GetInstance();
228    BatteryConfig::ChargerConfig chargerConfig = batteryConfig.GetChargerConfig();
229
230    return powerSupplyProvider_->SetChargingLimit(chargingLimit, chargerConfig.currentPath, chargerConfig.voltagePath);
231}
232
233int32_t BatteryInterfaceImpl::GetChargeType(ChargeType& chargeType)
234{
235    auto& batteryConfig = BatteryConfig::GetInstance();
236    BatteryConfig::ChargerConfig chargerConfig = batteryConfig.GetChargerConfig();
237
238    int32_t type = static_cast<int32_t>(CHARGE_TYPE_NONE);
239    int32_t ret = powerSupplyProvider_->ParseChargeType(&type, chargerConfig.chargeTypePath);
240    if (ret != HDF_SUCCESS) {
241        return ret;
242    }
243
244    chargeType = ChargeType(type);
245    return HDF_SUCCESS;
246}
247
248int32_t BatteryInterfaceImpl::SetBatteryConfig(const std::string& sceneName, const std::string& value)
249{
250    Battery::BatteryXCollie batteryXcollie("Battery_SetBatteryConfig");
251    auto& batteryConfig = BatteryConfig::GetInstance();
252    std::map<std::string, BatteryConfig::ChargeSceneConfig>
253        chargeSceneConfigMap = batteryConfig.GetChargeSceneConfigMap();
254    if (chargeSceneConfigMap.empty()) {
255        BATTERY_HILOGE(FEATURE_BATT_INFO, "chargeSceneConfigMap is empty");
256        return HDF_ERR_NOT_SUPPORT;
257    }
258
259    std::map<std::string, BatteryConfig::ChargeSceneConfig>::iterator it = chargeSceneConfigMap.find(sceneName);
260    if (it != chargeSceneConfigMap.end()) {
261        std::string setPath = (it -> second).setPath;
262        return powerSupplyProvider_->SetConfigByPath(setPath, value);
263    }
264
265    BATTERY_HILOGW(FEATURE_BATT_INFO, "key:%{public}s not found", sceneName.c_str());
266    return HDF_ERR_NOT_SUPPORT;
267}
268
269int32_t BatteryInterfaceImpl::GetBatteryConfig(const std::string& sceneName, std::string& value)
270{
271    Battery::BatteryXCollie batteryXcollie("Battery_GetBatteryConfig");
272    auto& batteryConfig = BatteryConfig::GetInstance();
273    std::map<std::string, BatteryConfig::ChargeSceneConfig>
274        chargeSceneConfigMap = batteryConfig.GetChargeSceneConfigMap();
275    if (chargeSceneConfigMap.empty()) {
276        BATTERY_HILOGE(FEATURE_BATT_INFO, "chargeSceneConfigMap is empty");
277        value = "";
278        return HDF_ERR_NOT_SUPPORT;
279    }
280
281    std::map<std::string, BatteryConfig::ChargeSceneConfig>::iterator it = chargeSceneConfigMap.find(sceneName);
282    if (it != chargeSceneConfigMap.end()) {
283        std::string getPath = (it -> second).getPath;
284        return powerSupplyProvider_->GetConfigByPath(getPath, value);
285    }
286
287    BATTERY_HILOGE(FEATURE_BATT_INFO, "key:%{public}s not found", sceneName.c_str());
288    value = "";
289    return HDF_ERR_NOT_SUPPORT;
290}
291
292int32_t BatteryInterfaceImpl::IsBatteryConfigSupported(const std::string& sceneName, bool& value)
293{
294    Battery::BatteryXCollie batteryXcollie("Battery_IsBatteryConfigSupported");
295    auto& batteryConfig = BatteryConfig::GetInstance();
296    std::map<std::string, BatteryConfig::ChargeSceneConfig>
297        chargeSceneConfigMap = batteryConfig.GetChargeSceneConfigMap();
298    if (chargeSceneConfigMap.empty()) {
299        BATTERY_HILOGE(FEATURE_BATT_INFO, "chargeSceneConfigMap is empty");
300        value = false;
301        return HDF_ERR_NOT_SUPPORT;
302    }
303
304    std::map<std::string, BatteryConfig::ChargeSceneConfig>::iterator it = chargeSceneConfigMap.find(sceneName);
305    if (it != chargeSceneConfigMap.end()) {
306        std::string supportPath = (it -> second).supportPath;
307        std::string type = (it -> second).type;
308        std::string expectValue = (it -> second).expectValue;
309        BATTERY_HILOGI(FEATURE_BATT_INFO,
310            "is support charge config, path:%{public}s, type:%{public}s, expect_value:%{public}s",
311            supportPath.c_str(), type.c_str(), expectValue.c_str());
312
313        if (type == "dir") {
314            return powerSupplyProvider_->CheckPathExists(supportPath, value);
315        } else if (type == "file") {
316            std::string temp;
317            int ret = powerSupplyProvider_->GetConfigByPath(supportPath, temp);
318            value = ret == HDF_SUCCESS ? expectValue == temp : false;
319            return ret;
320        } else {
321            value = false;
322            return HDF_SUCCESS;
323        }
324    }
325    BATTERY_HILOGE(FEATURE_BATT_INFO, "key:%{public}s not found", sceneName.c_str());
326    value = false;
327    return HDF_ERR_NOT_SUPPORT;
328}
329
330int32_t BatteryInterfaceImpl::AddBatteryDeathRecipient(const sptr<IBatteryCallback>& callback)
331{
332    const sptr<IRemoteObject>& remote = OHOS::HDI::hdi_objcast<IBatteryCallback>(callback);
333    bool result = remote->AddDeathRecipient(g_deathRecipient);
334    if (!result) {
335        BATTERY_HILOGE(COMP_HDI, "AddDeathRecipient fail");
336        return HDF_FAILURE;
337    }
338
339    return HDF_SUCCESS;
340}
341
342int32_t BatteryInterfaceImpl::RemoveBatteryDeathRecipient(const sptr<IBatteryCallback>& callback)
343{
344    if (callback == nullptr) {
345        BATTERY_HILOGW(FEATURE_BATT_INFO, "remove callback is nullptr");
346        return HDF_ERR_INVALID_PARAM;
347    }
348    const sptr<IRemoteObject>& remote = OHOS::HDI::hdi_objcast<IBatteryCallback>(callback);
349    bool result = remote->RemoveDeathRecipient(g_deathRecipient);
350    if (!result) {
351        BATTERY_HILOGE(COMP_HDI, "RemoveDeathRecipient fail");
352        return HDF_FAILURE;
353    }
354
355    return HDF_SUCCESS;
356}
357
358void BatteryInterfaceImpl::BatteryDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& object)
359{
360    interfaceImpl_->UnRegister();
361}
362}  // namespace V2_0
363}  // namespace Battery
364}  // namespace Hdi
365}  // namespace OHOS
366