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 
20 namespace OHOS {
21 namespace DevStandbyMgr {
22 namespace {
23 const uint32_t ASYNC_CALLBACK_PARAM_NUM = 2;
24 const uint32_t STRING_MAX_SIZE = 128;
25 }
26 
AsyncWorkData(napi_env napiEnv)27 AsyncWorkData::AsyncWorkData(napi_env napiEnv)
28 {
29     env = napiEnv;
30 }
31 
~AsyncWorkData()32 AsyncWorkData::~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 
NapiGetNull(napi_env env)46 napi_value Common::NapiGetNull(napi_env env)
47 {
48     napi_value result = nullptr;
49     napi_get_null(env, &result);
50     return result;
51 }
52 
PaddingAsyncWorkData(const napi_env & env,const napi_ref & callback,AsyncWorkData & info,napi_value & promise)53 void 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 
ReturnCallbackPromise(const napi_env & env,const AsyncWorkData & info,const napi_value & result)67 void 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 
SetCallback(const napi_env & env,const napi_ref & callbackIn,const int32_t & errCode,const napi_value & result)76 void 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 
SetPromise(const napi_env & env,const AsyncWorkData & info,const napi_value & result)98 napi_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 
GetCallbackErrorValue(napi_env env,const int32_t errCode,const std::string errMsg)121 napi_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 
HandleErrCode(const napi_env & env,int32_t errCode)138 void 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 
FindErrMsg(const napi_env & env,const int32_t errCode)151 std::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 
FindErrCode(const napi_env & env,const int32_t errCodeIn)172 int32_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 
HandleParamErr(const napi_env & env,int32_t errCode)181 bool 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 
SetInt32Value(const napi_env & env,const std::string & fieldStr,const int32_t intValue,napi_value & result)197 void 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 
SetUint32Value(const napi_env & env,const std::string & fieldStr,const uint32_t uintValue,napi_value & result)204 void 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 
GetStringValue(const napi_env & env,const napi_value & value,std::string & result)212 napi_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 
SetStringValue(const napi_env & env,const std::string & fieldStr,const std::string & stringValue,napi_value & result)231 void 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 
GetUint32Value(const napi_env & env,const napi_value & value,uint32_t & result)239 napi_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 
GetInt32Value(const napi_env & env,const napi_value & value,int32_t & result)252 napi_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 
GetNamedInt32Value(const napi_env & env,napi_value & object,const char * utf8name,int32_t & result)265 napi_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 
GetNamedStringValue(const napi_env & env,napi_value & object,const char * utf8name,std::string & result)283 napi_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