1/* 2 * Copyright (c) 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 "common.h" 17 18#include "standby_service_log.h" 19 20namespace OHOS { 21namespace DevStandbyMgr { 22namespace { 23const uint32_t ASYNC_CALLBACK_PARAM_NUM = 2; 24const uint32_t STRING_MAX_SIZE = 128; 25} 26 27AsyncWorkData::AsyncWorkData(napi_env napiEnv) 28{ 29 env = napiEnv; 30} 31 32AsyncWorkData::~AsyncWorkData() 33{ 34 if (callback) { 35 STANDBYSERVICE_LOGD("AsyncWorkData::~AsyncWorkData delete callback"); 36 napi_delete_reference(env, callback); 37 callback = nullptr; 38 } 39 if (asyncWork) { 40 STANDBYSERVICE_LOGD("AsyncWorkData::~AsyncWorkData delete asyncWork"); 41 napi_delete_async_work(env, asyncWork); 42 asyncWork = nullptr; 43 } 44} 45 46napi_value Common::NapiGetNull(napi_env env) 47{ 48 napi_value result = nullptr; 49 napi_get_null(env, &result); 50 return result; 51} 52 53void Common::PaddingAsyncWorkData( 54 const napi_env& env, const napi_ref& callback, AsyncWorkData& info, napi_value& promise) 55{ 56 if (callback) { 57 info.callback = callback; 58 info.isCallback = true; 59 } else { 60 napi_deferred deferred = nullptr; 61 NAPI_CALL_RETURN_VOID(env, napi_create_promise(env, &deferred, &promise)); 62 info.deferred = deferred; 63 info.isCallback = false; 64 } 65} 66 67void Common::ReturnCallbackPromise(const napi_env& env, const AsyncWorkData& info, const napi_value& result) 68{ 69 if (info.isCallback) { 70 SetCallback(env, info.callback, info.errCode, result); 71 } else { 72 SetPromise(env, info, result); 73 } 74} 75 76void Common::SetCallback( 77 const napi_env& env, const napi_ref& callbackIn, const int32_t& errCode, const napi_value& result) 78{ 79 napi_value undefined = nullptr; 80 napi_get_undefined(env, &undefined); 81 82 napi_value callback = nullptr; 83 napi_value resultout = nullptr; 84 napi_get_reference_value(env, callbackIn, &callback); 85 napi_value results[ASYNC_CALLBACK_PARAM_NUM] = {nullptr}; 86 if (errCode == ERR_OK) { 87 results[0] = NapiGetNull(env); 88 } else { 89 int32_t errCodeInfo = FindErrCode(env, errCode); 90 std::string errMsg = FindErrMsg(env, errCode); 91 results[0] = GetCallbackErrorValue(env, errCodeInfo, errMsg); 92 } 93 results[1] = result; 94 NAPI_CALL_RETURN_VOID(env, 95 napi_call_function(env, undefined, callback, ASYNC_CALLBACK_PARAM_NUM, &results[0], &resultout)); 96} 97 98napi_value Common::SetPromise( 99 const napi_env& env, const AsyncWorkData& info, const napi_value& result) 100{ 101 if (info.errCode == ERR_OK) { 102 napi_resolve_deferred(env, info.deferred, result); 103 } else { 104 int32_t errCodeInfo = FindErrCode(env, info.errCode); 105 std::string errMsg = FindErrMsg(env, info.errCode); 106 napi_value error = nullptr; 107 napi_value eCode = nullptr; 108 napi_value eMsg = nullptr; 109 NAPI_CALL(env, napi_create_int32(env, errCodeInfo, &eCode)); 110 NAPI_CALL(env, napi_create_string_utf8(env, errMsg.c_str(), 111 errMsg.length(), &eMsg)); 112 NAPI_CALL(env, napi_create_object(env, &error)); 113 NAPI_CALL(env, napi_set_named_property(env, error, "data", eCode)); 114 NAPI_CALL(env, napi_set_named_property(env, error, "code", eCode)); 115 NAPI_CALL(env, napi_set_named_property(env, error, "message", eMsg)); 116 napi_reject_deferred(env, info.deferred, error); 117 } 118 return result; 119} 120 121napi_value Common::GetCallbackErrorValue(napi_env env, const int32_t errCode, const std::string errMsg) 122{ 123 if (errCode == ERR_OK) { 124 return NapiGetNull(env); 125 } 126 napi_value error = nullptr; 127 napi_value eCode = nullptr; 128 napi_value eMsg = nullptr; 129 NAPI_CALL(env, napi_create_int32(env, errCode, &eCode)); 130 NAPI_CALL(env, napi_create_string_utf8(env, errMsg.c_str(), 131 errMsg.length(), &eMsg)); 132 NAPI_CALL(env, napi_create_object(env, &error)); 133 NAPI_CALL(env, napi_set_named_property(env, error, "code", eCode)); 134 NAPI_CALL(env, napi_set_named_property(env, error, "message", eMsg)); 135 return error; 136} 137 138void Common::HandleErrCode(const napi_env &env, int32_t errCode) 139{ 140 STANDBYSERVICE_LOGI("HandleErrCode errCode = %{public}d", errCode); 141 if (errCode == ERR_OK) { 142 return; 143 } 144 std::string errMsg = FindErrMsg(env, errCode); 145 int32_t errCodeInfo = FindErrCode(env, errCode); 146 if (errMsg != "") { 147 napi_throw_error(env, std::to_string(errCodeInfo).c_str(), errMsg.c_str()); 148 } 149} 150 151std::string Common::FindErrMsg(const napi_env& env, const int32_t errCode) 152{ 153 if (errCode == ERR_OK) { 154 return ""; 155 } 156 auto iter = saErrCodeMsgMap.find(errCode); 157 if (iter != saErrCodeMsgMap.end()) { 158 std::string errMessage = "BussinessError "; 159 int32_t errCodeInfo = FindErrCode(env, errCode); 160 errMessage.append(std::to_string(errCodeInfo)).append(": ").append(iter->second); 161 return errMessage; 162 } 163 iter = paramErrCodeMsgMap.find(errCode); 164 if (iter != paramErrCodeMsgMap.end()) { 165 std::string errMessage = "BussinessError 401: Parameter error. "; 166 errMessage.append(paramErrCodeMsgMap[errCode]); 167 return errMessage; 168 } 169 return "Inner error."; 170} 171 172int32_t Common::FindErrCode(const napi_env& env, const int32_t errCodeIn) 173{ 174 auto iter = paramErrCodeMsgMap.find(errCodeIn); 175 if (iter != paramErrCodeMsgMap.end()) { 176 return ERR_STANDBY_INVALID_PARAM; 177 } 178 return errCodeIn > THRESHOLD ? errCodeIn / OFFSET : errCodeIn; 179} 180 181bool Common::HandleParamErr(const napi_env& env, int32_t errCode) 182{ 183 STANDBYSERVICE_LOGI("HandleParamErr errCode = %{public}d, isThrow = true", errCode); 184 if (errCode == ERR_OK) { 185 return false; 186 } 187 auto iter = paramErrCodeMsgMap.find(errCode); 188 if (iter != paramErrCodeMsgMap.end()) { 189 std::string errMessage = "BussinessError 401: Parameter error. "; 190 errMessage.append(paramErrCodeMsgMap[errCode]); 191 napi_throw_error(env, std::to_string(ERR_STANDBY_INVALID_PARAM).c_str(), errMessage.c_str()); 192 return true; 193 } 194 return false; 195} 196 197void Common::SetInt32Value(const napi_env& env, const std::string& fieldStr, const int32_t intValue, napi_value& result) 198{ 199 napi_value value = nullptr; 200 napi_create_int32(env, intValue, &value); 201 napi_set_named_property(env, result, fieldStr.c_str(), value); 202} 203 204void Common::SetUint32Value(const napi_env& env, const std::string& fieldStr, 205 const uint32_t uintValue, napi_value& result) 206{ 207 napi_value value = nullptr; 208 napi_create_uint32(env, uintValue, &value); 209 napi_set_named_property(env, result, fieldStr.c_str(), value); 210} 211 212napi_value Common::GetStringValue(const napi_env &env, const napi_value &value, std::string &result) 213{ 214 napi_valuetype valuetype = napi_undefined; 215 NAPI_CALL(env, napi_typeof(env, value, &valuetype)); 216 if (valuetype != napi_string) { 217 return nullptr; 218 } 219 220 char str[STRING_MAX_SIZE] = {0}; 221 size_t strLen = 0; 222 napi_status status = napi_get_value_string_utf8(env, value, str, STRING_MAX_SIZE - 1, &strLen); 223 if (status != napi_ok) { 224 return nullptr; 225 } 226 result = std::string(str); 227 STANDBYSERVICE_LOGD("GetStringValue result: %{public}s", result.c_str()); 228 return Common::NapiGetNull(env); 229} 230 231void Common::SetStringValue(const napi_env& env, const std::string& fieldStr, 232 const std::string& stringValue, napi_value& result) 233{ 234 napi_value value = nullptr; 235 napi_create_string_utf8(env, stringValue.c_str(), stringValue.length(), &value); 236 napi_set_named_property(env, result, fieldStr.c_str(), value); 237} 238 239napi_value Common::GetUint32Value(const napi_env& env, const napi_value& value, uint32_t& result) 240{ 241 napi_valuetype valuetype = napi_undefined; 242 NAPI_CALL(env, napi_typeof(env, value, &valuetype)); 243 if (valuetype != napi_number) { 244 return nullptr; 245 } 246 NAPI_CALL(env, napi_get_value_uint32(env, value, &result)); 247 STANDBYSERVICE_LOGI("GetUint32Value result: %{public}d", static_cast<int32_t>(result)); 248 249 return Common::NapiGetNull(env); 250} 251 252napi_value Common::GetInt32Value(const napi_env& env, const napi_value& value, int32_t& result) 253{ 254 napi_valuetype valuetype = napi_undefined; 255 NAPI_CALL(env, napi_typeof(env, value, &valuetype)); 256 if (valuetype != napi_number) { 257 return nullptr; 258 } 259 NAPI_CALL(env, napi_get_value_int32(env, value, &result)); 260 STANDBYSERVICE_LOGI("GetInt32Value result: %{public}d", static_cast<int32_t>(result)); 261 262 return Common::NapiGetNull(env); 263} 264 265napi_value Common::GetNamedInt32Value(const napi_env &env, napi_value &object, const char* utf8name, 266 int32_t& result) 267{ 268 bool hasNamedProperty = false; 269 napi_value intValue = nullptr; 270 if (napi_has_named_property(env, object, utf8name, &hasNamedProperty) != napi_ok || !hasNamedProperty) { 271 STANDBYSERVICE_LOGE("GetNamedInt32Value failed, %{public}s not exist, is nullptr", utf8name); 272 return nullptr; 273 } 274 NAPI_CALL(env, napi_get_named_property(env, object, utf8name, &intValue)); 275 if (!Common::GetInt32Value(env, intValue, result)) { 276 STANDBYSERVICE_LOGE("GetNamedInt32Value failed, %{public}s is nullptr", utf8name); 277 return nullptr; 278 } 279 STANDBYSERVICE_LOGD("GetNamedInt32Value: %{public}s is %{public}d", utf8name, result); 280 return Common::NapiGetNull(env); 281} 282 283napi_value Common::GetNamedStringValue(const napi_env &env, napi_value &object, const char* utf8name, 284 std::string& result) 285{ 286 bool hasNamedProperty = false; 287 napi_value stringValue = nullptr; 288 if (napi_has_named_property(env, object, utf8name, &hasNamedProperty) != napi_ok || !hasNamedProperty) { 289 STANDBYSERVICE_LOGE("GetNamedStringValue failed, string not exist, is nullptr"); 290 return nullptr; 291 } 292 NAPI_CALL(env, napi_get_named_property(env, object, utf8name, &stringValue)); 293 if (!Common::GetStringValue(env, stringValue, result)) { 294 STANDBYSERVICE_LOGE("GetStringValue failed, the string is nullptr"); 295 return nullptr; 296 } 297 STANDBYSERVICE_LOGD("GetNamedStringValue: result is %{public}s", result.c_str()); 298 return Common::NapiGetNull(env); 299} 300} // namespace DevStandbyMgr 301} // namespace OHOS