1f16e0440Sopenharmony_ci/* 2f16e0440Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 3f16e0440Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4f16e0440Sopenharmony_ci * you may not use this file except in compliance with the License. 5f16e0440Sopenharmony_ci * You may obtain a copy of the License at 6f16e0440Sopenharmony_ci * 7f16e0440Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8f16e0440Sopenharmony_ci * 9f16e0440Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10f16e0440Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11f16e0440Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12f16e0440Sopenharmony_ci * See the License for the specific language governing permissions and 13f16e0440Sopenharmony_ci * limitations under the License. 14f16e0440Sopenharmony_ci */ 15f16e0440Sopenharmony_ci 16f16e0440Sopenharmony_ci#include "system_battery.h" 17f16e0440Sopenharmony_ci 18f16e0440Sopenharmony_ci#include <string> 19f16e0440Sopenharmony_ci#include <cstddef> 20f16e0440Sopenharmony_ci#include <memory> 21f16e0440Sopenharmony_ci#include "new" 22f16e0440Sopenharmony_ci#include "napi/native_common.h" 23f16e0440Sopenharmony_ci 24f16e0440Sopenharmony_ci#include "battery_log.h" 25f16e0440Sopenharmony_ci#include "battery_srv_client.h" 26f16e0440Sopenharmony_ci#include "power_common.h" 27f16e0440Sopenharmony_ci 28f16e0440Sopenharmony_ciusing namespace OHOS::PowerMgr; 29f16e0440Sopenharmony_ci 30f16e0440Sopenharmony_cinamespace { 31f16e0440Sopenharmony_ciconst uint32_t MAX_ARGC = 1; 32f16e0440Sopenharmony_ciconst uint32_t ARGC_ONE = 0; 33f16e0440Sopenharmony_ciconst double LEVEL_RANGES = 0.01; 34f16e0440Sopenharmony_ci 35f16e0440Sopenharmony_ciconst std::string RESPONSE_CHARGING = "charging"; 36f16e0440Sopenharmony_ciconst std::string RESPONSE_LEVEL = "level"; 37f16e0440Sopenharmony_ciconst std::string FUNC_SUCEESS_NAME = "success"; 38f16e0440Sopenharmony_ciconst std::string FUNC_FAIL_NAME = "fail"; 39f16e0440Sopenharmony_ciconst std::string FUNC_COMPLETE_NAME = "complete"; 40f16e0440Sopenharmony_ci 41f16e0440Sopenharmony_ciconst uint32_t COMMON_ERROR_COED = 200; 42f16e0440Sopenharmony_ciconst std::string GET_BATTERY_ERROR_MSG = "Battery level is not available"; 43f16e0440Sopenharmony_ci} 44f16e0440Sopenharmony_ci 45f16e0440Sopenharmony_civoid SystemBattery::GetBatteryStats(napi_env env) 46f16e0440Sopenharmony_ci{ 47f16e0440Sopenharmony_ci if (!batteryInfo_.GetBatteryInfo()) { 48f16e0440Sopenharmony_ci error_.SetErrorMsg(COMMON_ERROR_COED, GET_BATTERY_ERROR_MSG); 49f16e0440Sopenharmony_ci } 50f16e0440Sopenharmony_ci if (!error_.IsError()) { 51f16e0440Sopenharmony_ci BATTERY_HILOGD(FEATURE_BATT_INFO, "Call the js success method"); 52f16e0440Sopenharmony_ci SuccessCallback(env); 53f16e0440Sopenharmony_ci } else { 54f16e0440Sopenharmony_ci BATTERY_HILOGD(FEATURE_BATT_INFO, "Call the js fail method"); 55f16e0440Sopenharmony_ci FailCallback(env); 56f16e0440Sopenharmony_ci } 57f16e0440Sopenharmony_ci BATTERY_HILOGD(FEATURE_BATT_INFO, "Call the js complete method"); 58f16e0440Sopenharmony_ci CompleteCallback(env); 59f16e0440Sopenharmony_ci} 60f16e0440Sopenharmony_ci 61f16e0440Sopenharmony_cinapi_value SystemBattery::CreateResponse(napi_env env) 62f16e0440Sopenharmony_ci{ 63f16e0440Sopenharmony_ci napi_value level = nullptr; 64f16e0440Sopenharmony_ci napi_value charging = nullptr; 65f16e0440Sopenharmony_ci NAPI_CALL(env, napi_create_double(env, batteryInfo_.GetLevel(), &level)); 66f16e0440Sopenharmony_ci NAPI_CALL(env, napi_create_uint32(env, batteryInfo_.IsCharging(), &charging)); 67f16e0440Sopenharmony_ci 68f16e0440Sopenharmony_ci napi_value response = nullptr; 69f16e0440Sopenharmony_ci NAPI_CALL(env, napi_create_object(env, &response)); 70f16e0440Sopenharmony_ci NAPI_CALL(env, napi_set_named_property(env, response, RESPONSE_CHARGING.c_str(), charging)); 71f16e0440Sopenharmony_ci NAPI_CALL(env, napi_set_named_property(env, response, RESPONSE_LEVEL.c_str(), level)); 72f16e0440Sopenharmony_ci return response; 73f16e0440Sopenharmony_ci} 74f16e0440Sopenharmony_ci 75f16e0440Sopenharmony_cibool SystemBattery::CheckValueType(napi_env env, napi_value value, napi_valuetype checkType) 76f16e0440Sopenharmony_ci{ 77f16e0440Sopenharmony_ci napi_valuetype valueType = napi_undefined; 78f16e0440Sopenharmony_ci napi_typeof(env, value, &valueType); 79f16e0440Sopenharmony_ci if (valueType != checkType) { 80f16e0440Sopenharmony_ci BATTERY_HILOGW(FEATURE_BATT_INFO, "Check input parameter error"); 81f16e0440Sopenharmony_ci return false; 82f16e0440Sopenharmony_ci } 83f16e0440Sopenharmony_ci return true; 84f16e0440Sopenharmony_ci} 85f16e0440Sopenharmony_ci 86f16e0440Sopenharmony_cinapi_value SystemBattery::GetOptionsFunc(napi_env env, napi_value options, const std::string& name) 87f16e0440Sopenharmony_ci{ 88f16e0440Sopenharmony_ci napi_value property = nullptr; 89f16e0440Sopenharmony_ci napi_status status = napi_get_named_property(env, options, name.c_str(), &property); 90f16e0440Sopenharmony_ci if (status != napi_ok) { 91f16e0440Sopenharmony_ci BATTERY_HILOGW(FEATURE_BATT_INFO, "Failed to obtain %{public}s", name.c_str()); 92f16e0440Sopenharmony_ci return nullptr; 93f16e0440Sopenharmony_ci } 94f16e0440Sopenharmony_ci if (!CheckValueType(env, property, napi_function)) { 95f16e0440Sopenharmony_ci BATTERY_HILOGW(FEATURE_BATT_INFO, "The %{public}s argument is not a function", name.c_str()); 96f16e0440Sopenharmony_ci return nullptr; 97f16e0440Sopenharmony_ci } 98f16e0440Sopenharmony_ci return property; 99f16e0440Sopenharmony_ci} 100f16e0440Sopenharmony_ci 101f16e0440Sopenharmony_cibool SystemBattery::CreateCallbackRef(napi_env env, napi_value options) 102f16e0440Sopenharmony_ci{ 103f16e0440Sopenharmony_ci RETURN_IF_WITH_RET(!CheckValueType(env, options, napi_object), false); 104f16e0440Sopenharmony_ci 105f16e0440Sopenharmony_ci napi_value succCallBack = GetOptionsFunc(env, options, FUNC_SUCEESS_NAME); 106f16e0440Sopenharmony_ci if (succCallBack != nullptr) { 107f16e0440Sopenharmony_ci napi_create_reference(env, succCallBack, 1, &successRef_); 108f16e0440Sopenharmony_ci } 109f16e0440Sopenharmony_ci 110f16e0440Sopenharmony_ci napi_value failCallBack = GetOptionsFunc(env, options, FUNC_FAIL_NAME); 111f16e0440Sopenharmony_ci if (failCallBack != nullptr) { 112f16e0440Sopenharmony_ci napi_create_reference(env, failCallBack, 1, &failRef_); 113f16e0440Sopenharmony_ci } 114f16e0440Sopenharmony_ci 115f16e0440Sopenharmony_ci napi_value completeCallBack = GetOptionsFunc(env, options, FUNC_COMPLETE_NAME); 116f16e0440Sopenharmony_ci if (completeCallBack != nullptr) { 117f16e0440Sopenharmony_ci napi_create_reference(env, completeCallBack, 1, &completeRef_); 118f16e0440Sopenharmony_ci } 119f16e0440Sopenharmony_ci return true; 120f16e0440Sopenharmony_ci} 121f16e0440Sopenharmony_ci 122f16e0440Sopenharmony_civoid SystemBattery::SuccessCallback(napi_env env) 123f16e0440Sopenharmony_ci{ 124f16e0440Sopenharmony_ci RETURN_IF(successRef_ == nullptr); 125f16e0440Sopenharmony_ci napi_value success = nullptr; 126f16e0440Sopenharmony_ci napi_get_reference_value(env, successRef_, &success); 127f16e0440Sopenharmony_ci napi_value argv = nullptr; 128f16e0440Sopenharmony_ci argv = CreateResponse(env); 129f16e0440Sopenharmony_ci if (argv == nullptr) { 130f16e0440Sopenharmony_ci BATTERY_HILOGW(FEATURE_BATT_INFO, "Failed to create BatteryResponse"); 131f16e0440Sopenharmony_ci napi_delete_reference(env, successRef_); 132f16e0440Sopenharmony_ci return; 133f16e0440Sopenharmony_ci } 134f16e0440Sopenharmony_ci 135f16e0440Sopenharmony_ci napi_value callResult = 0; 136f16e0440Sopenharmony_ci const size_t argc = 1; 137f16e0440Sopenharmony_ci napi_status status = napi_call_function(env, nullptr, success, argc, &argv, &callResult); 138f16e0440Sopenharmony_ci napi_delete_reference(env, successRef_); 139f16e0440Sopenharmony_ci if (status != napi_ok) { 140f16e0440Sopenharmony_ci BATTERY_HILOGW(FEATURE_BATT_INFO, "Failed to execute the callback function SUCCESS"); 141f16e0440Sopenharmony_ci return; 142f16e0440Sopenharmony_ci } 143f16e0440Sopenharmony_ci BATTERY_HILOGI(FEATURE_BATT_INFO, "Callbacks to incoming parameters, level: %{public}f, isCharging: %{public}d", 144f16e0440Sopenharmony_ci batteryInfo_.GetLevel(), batteryInfo_.IsCharging()); 145f16e0440Sopenharmony_ci} 146f16e0440Sopenharmony_ci 147f16e0440Sopenharmony_civoid SystemBattery::FailCallback(napi_env env) 148f16e0440Sopenharmony_ci{ 149f16e0440Sopenharmony_ci RETURN_IF(failRef_ == nullptr); 150f16e0440Sopenharmony_ci napi_value fail = nullptr; 151f16e0440Sopenharmony_ci napi_get_reference_value(env, failRef_, &fail); 152f16e0440Sopenharmony_ci 153f16e0440Sopenharmony_ci napi_value data = nullptr; 154f16e0440Sopenharmony_ci napi_value code = nullptr; 155f16e0440Sopenharmony_ci std::string msg = error_.GetMsg(); 156f16e0440Sopenharmony_ci napi_status strStatus = napi_create_string_utf8(env, msg.c_str(), msg.size(), &data); 157f16e0440Sopenharmony_ci napi_status intStatus = napi_create_int32(env, error_.GetCode(), &code); 158f16e0440Sopenharmony_ci if (strStatus != napi_ok || intStatus != napi_ok) { 159f16e0440Sopenharmony_ci BATTERY_HILOGW(FEATURE_BATT_INFO, "Napi failed to create a parameter, code: %{public}d, msg: %{public}s", 160f16e0440Sopenharmony_ci error_.GetCode(), msg.c_str()); 161f16e0440Sopenharmony_ci napi_delete_reference(env, failRef_); 162f16e0440Sopenharmony_ci return; 163f16e0440Sopenharmony_ci } 164f16e0440Sopenharmony_ci 165f16e0440Sopenharmony_ci napi_value argv[] = { data, code }; 166f16e0440Sopenharmony_ci napi_value callResult = 0; 167f16e0440Sopenharmony_ci const size_t argc = 2; 168f16e0440Sopenharmony_ci napi_status status = napi_call_function(env, nullptr, fail, argc, argv, &callResult); 169f16e0440Sopenharmony_ci if (status != napi_ok) { 170f16e0440Sopenharmony_ci BATTERY_HILOGW(FEATURE_BATT_INFO, "Call fail function is failed"); 171f16e0440Sopenharmony_ci } 172f16e0440Sopenharmony_ci napi_delete_reference(env, failRef_); 173f16e0440Sopenharmony_ci} 174f16e0440Sopenharmony_ci 175f16e0440Sopenharmony_civoid SystemBattery::CompleteCallback(napi_env env) 176f16e0440Sopenharmony_ci{ 177f16e0440Sopenharmony_ci RETURN_IF(completeRef_ == nullptr); 178f16e0440Sopenharmony_ci napi_value complete = nullptr; 179f16e0440Sopenharmony_ci napi_get_reference_value(env, completeRef_, &complete); 180f16e0440Sopenharmony_ci napi_value callResult = 0; 181f16e0440Sopenharmony_ci const size_t argc = 0; 182f16e0440Sopenharmony_ci napi_status status = napi_call_function(env, nullptr, complete, argc, nullptr, &callResult); 183f16e0440Sopenharmony_ci if (status != napi_ok) { 184f16e0440Sopenharmony_ci BATTERY_HILOGW(FEATURE_BATT_INFO, "Call complete function is failed"); 185f16e0440Sopenharmony_ci } 186f16e0440Sopenharmony_ci napi_delete_reference(env, completeRef_); 187f16e0440Sopenharmony_ci} 188f16e0440Sopenharmony_ci 189f16e0440Sopenharmony_civoid SystemBattery::Error::SetErrorMsg(int32_t code, const std::string& msg) 190f16e0440Sopenharmony_ci{ 191f16e0440Sopenharmony_ci code_ = code; 192f16e0440Sopenharmony_ci msg_ = msg; 193f16e0440Sopenharmony_ci BATTERY_HILOGW(FEATURE_BATT_INFO, "Error message, code: %{public}d, msg: %{public}s", 194f16e0440Sopenharmony_ci code_, msg_.c_str()); 195f16e0440Sopenharmony_ci} 196f16e0440Sopenharmony_ci 197f16e0440Sopenharmony_cibool SystemBattery::BatteryInfo::GetBatteryInfo() 198f16e0440Sopenharmony_ci{ 199f16e0440Sopenharmony_ci BatterySrvClient& g_battClient = BatterySrvClient::GetInstance(); 200f16e0440Sopenharmony_ci capacity_ = g_battClient.GetCapacity(); 201f16e0440Sopenharmony_ci chargingState_ = g_battClient.GetChargingStatus(); 202f16e0440Sopenharmony_ci BATTERY_HILOGI(FEATURE_BATT_INFO, "Get battery info, capacity: %{public}d, charging: %{public}d", 203f16e0440Sopenharmony_ci capacity_, static_cast<int32_t>(chargingState_)); 204f16e0440Sopenharmony_ci return (capacity_ != INVALID_BATT_INT_VALUE) && (chargingState_ != BatteryChargeState::CHARGE_STATE_BUTT); 205f16e0440Sopenharmony_ci} 206f16e0440Sopenharmony_ci 207f16e0440Sopenharmony_cidouble SystemBattery::BatteryInfo::GetLevel() const 208f16e0440Sopenharmony_ci{ 209f16e0440Sopenharmony_ci // Current battery level, which ranges from 0.00 to 1.00. 210f16e0440Sopenharmony_ci return (capacity_ * LEVEL_RANGES); 211f16e0440Sopenharmony_ci} 212f16e0440Sopenharmony_ci 213f16e0440Sopenharmony_ciuint32_t SystemBattery::BatteryInfo::IsCharging() const 214f16e0440Sopenharmony_ci{ 215f16e0440Sopenharmony_ci return static_cast<uint32_t>(chargingState_ == BatteryChargeState::CHARGE_STATE_ENABLE || 216f16e0440Sopenharmony_ci chargingState_ == BatteryChargeState::CHARGE_STATE_FULL); 217f16e0440Sopenharmony_ci} 218f16e0440Sopenharmony_ci 219f16e0440Sopenharmony_cistatic napi_value GetStatus(napi_env env, napi_callback_info info) 220f16e0440Sopenharmony_ci{ 221f16e0440Sopenharmony_ci BATTERY_HILOGD(FEATURE_BATT_INFO, "Call the GetBatteryStats method"); 222f16e0440Sopenharmony_ci size_t argc = MAX_ARGC; 223f16e0440Sopenharmony_ci napi_value argv[argc]; 224f16e0440Sopenharmony_ci napi_value thisVar = nullptr; 225f16e0440Sopenharmony_ci void *data = nullptr; 226f16e0440Sopenharmony_ci NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data)); 227f16e0440Sopenharmony_ci 228f16e0440Sopenharmony_ci if (argc != MAX_ARGC) { 229f16e0440Sopenharmony_ci BATTERY_HILOGW(FEATURE_BATT_INFO, "Lack of parameter, argc: %{public}zu", argc); 230f16e0440Sopenharmony_ci return nullptr; 231f16e0440Sopenharmony_ci } 232f16e0440Sopenharmony_ci 233f16e0440Sopenharmony_ci std::unique_ptr<SystemBattery> asyncInfo = std::make_unique<SystemBattery>(); 234f16e0440Sopenharmony_ci RETURN_IF_WITH_RET(!asyncInfo->CreateCallbackRef(env, argv[ARGC_ONE]), nullptr); 235f16e0440Sopenharmony_ci 236f16e0440Sopenharmony_ci napi_value resource = nullptr; 237f16e0440Sopenharmony_ci NAPI_CALL(env, napi_create_string_utf8(env, "GetStatus", NAPI_AUTO_LENGTH, &resource)); 238f16e0440Sopenharmony_ci napi_create_async_work( 239f16e0440Sopenharmony_ci env, 240f16e0440Sopenharmony_ci nullptr, 241f16e0440Sopenharmony_ci resource, 242f16e0440Sopenharmony_ci [](napi_env env, void *data) { 243f16e0440Sopenharmony_ci BATTERY_HILOGD(FEATURE_BATT_INFO, "async_work callback function is called"); 244f16e0440Sopenharmony_ci }, 245f16e0440Sopenharmony_ci [](napi_env env, napi_status status, void *data) { 246f16e0440Sopenharmony_ci SystemBattery *asyncInfo = reinterpret_cast<SystemBattery*>(data); 247f16e0440Sopenharmony_ci if (asyncInfo != nullptr) { 248f16e0440Sopenharmony_ci asyncInfo->GetBatteryStats(env); 249f16e0440Sopenharmony_ci napi_delete_async_work(env, asyncInfo->asyncWork); 250f16e0440Sopenharmony_ci delete asyncInfo; 251f16e0440Sopenharmony_ci } 252f16e0440Sopenharmony_ci }, 253f16e0440Sopenharmony_ci reinterpret_cast<void*>(asyncInfo.get()), 254f16e0440Sopenharmony_ci &asyncInfo->asyncWork); 255f16e0440Sopenharmony_ci NAPI_CALL(env, napi_queue_async_work_with_qos(env, asyncInfo->asyncWork, napi_qos_utility)); 256f16e0440Sopenharmony_ci asyncInfo.release(); 257f16e0440Sopenharmony_ci return nullptr; 258f16e0440Sopenharmony_ci} 259f16e0440Sopenharmony_ci 260f16e0440Sopenharmony_ciEXTERN_C_START 261f16e0440Sopenharmony_ci/* 262f16e0440Sopenharmony_ci * function for module exports 263f16e0440Sopenharmony_ci */ 264f16e0440Sopenharmony_cistatic napi_value SystemBatteryInit(napi_env env, napi_value exports) 265f16e0440Sopenharmony_ci{ 266f16e0440Sopenharmony_ci BATTERY_HILOGI(COMP_FWK, "SystemBattery init"); 267f16e0440Sopenharmony_ci napi_property_descriptor desc[] = { 268f16e0440Sopenharmony_ci DECLARE_NAPI_FUNCTION("getStatus", GetStatus) 269f16e0440Sopenharmony_ci }; 270f16e0440Sopenharmony_ci NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc)); 271f16e0440Sopenharmony_ci BATTERY_HILOGI(COMP_FWK, "SystemBattery init end"); 272f16e0440Sopenharmony_ci return exports; 273f16e0440Sopenharmony_ci} 274f16e0440Sopenharmony_ciEXTERN_C_END 275f16e0440Sopenharmony_ci 276f16e0440Sopenharmony_ci/* 277f16e0440Sopenharmony_ci * Module definition 278f16e0440Sopenharmony_ci */ 279f16e0440Sopenharmony_cistatic napi_module g_module = { 280f16e0440Sopenharmony_ci .nm_version = 1, 281f16e0440Sopenharmony_ci .nm_flags = 0, 282f16e0440Sopenharmony_ci .nm_filename = "battery", 283f16e0440Sopenharmony_ci .nm_register_func = SystemBatteryInit, 284f16e0440Sopenharmony_ci .nm_modname = "battery", 285f16e0440Sopenharmony_ci .nm_priv = ((void*)0), 286f16e0440Sopenharmony_ci .reserved = {0} 287f16e0440Sopenharmony_ci}; 288f16e0440Sopenharmony_ci 289f16e0440Sopenharmony_ci/* 290f16e0440Sopenharmony_ci * Module registration 291f16e0440Sopenharmony_ci */ 292f16e0440Sopenharmony_ciextern "C" __attribute__((constructor)) void RegisterModule(void) 293f16e0440Sopenharmony_ci{ 294f16e0440Sopenharmony_ci napi_module_register(&g_module); 295f16e0440Sopenharmony_ci} 296