1 /*
2 * Copyright (c) 2021-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 #include "ans_inner_errors.h"
18 #include "ans_log_wrapper.h"
19 #include "js_native_api.h"
20 #include "js_native_api_types.h"
21 #include "napi_common.h"
22 #include "napi_common_util.h"
23 #include "notification_action_button.h"
24 #include "notification_capsule.h"
25 #include "notification_constant.h"
26 #include "notification_progress.h"
27 #include "notification_time.h"
28 #include "pixel_map_napi.h"
29
30 namespace OHOS {
31 namespace NotificationNapi {
32 namespace {
33 static const std::unordered_map<int32_t, std::string> ERROR_CODE_MESSAGE {
34 {ERROR_PERMISSION_DENIED, "Permission denied"},
35 {ERROR_NOT_SYSTEM_APP, "The application isn't system application"},
36 {ERROR_PARAM_INVALID, "Invalid parameter"},
37 {ERROR_SYSTEM_CAP_ERROR, "SystemCapability not found"},
38 {ERROR_INTERNAL_ERROR, "Internal error"},
39 {ERROR_IPC_ERROR, "Marshalling or unmarshalling error"},
40 {ERROR_SERVICE_CONNECT_ERROR, "Failed to connect service"},
41 {ERROR_NOTIFICATION_CLOSED, "Notification is not enabled"},
42 {ERROR_SLOT_CLOSED, "Notification slot is not enabled"},
43 {ERROR_NOTIFICATION_UNREMOVABLE, "Notification is not allowed to remove"},
44 {ERROR_NOTIFICATION_NOT_EXIST, "The notification is not exist"},
45 {ERROR_USER_NOT_EXIST, "The user is not exist"},
46 {ERROR_OVER_MAX_NUM_PER_SECOND, "Over max number notifications per second"},
47 {ERROR_DISTRIBUTED_OPERATION_FAILED, "Distributed operation failed"},
48 {ERROR_READ_TEMPLATE_CONFIG_FAILED, "Read template config failed"},
49 {ERROR_NO_MEMORY, "No memory space"},
50 {ERROR_BUNDLE_NOT_FOUND, "The specified bundle name was not found"},
51 };
52 }
53
NapiGetBoolean(napi_env env,const bool & isValue)54 napi_value Common::NapiGetBoolean(napi_env env, const bool &isValue)
55 {
56 napi_value result = nullptr;
57 napi_get_boolean(env, isValue, &result);
58 return result;
59 }
60
NapiGetNull(napi_env env)61 napi_value Common::NapiGetNull(napi_env env)
62 {
63 napi_value result = nullptr;
64 napi_get_null(env, &result);
65 return result;
66 }
67
NapiGetUndefined(napi_env env)68 napi_value Common::NapiGetUndefined(napi_env env)
69 {
70 napi_value result = nullptr;
71 napi_get_undefined(env, &result);
72 return result;
73 }
74
CreateErrorValue(napi_env env,int32_t errCode,bool newType)75 napi_value Common::CreateErrorValue(napi_env env, int32_t errCode, bool newType)
76 {
77 ANS_LOGI("enter, errorCode[%{public}d]", errCode);
78 napi_value error = Common::NapiGetNull(env);
79 if (errCode == ERR_OK && newType) {
80 return error;
81 }
82
83 napi_value code = nullptr;
84 napi_create_int32(env, errCode, &code);
85
86 auto iter = ERROR_CODE_MESSAGE.find(errCode);
87 std::string errMsg = iter != ERROR_CODE_MESSAGE.end() ? iter->second : "";
88 napi_value message = nullptr;
89 napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &message);
90
91 napi_create_error(env, nullptr, message, &error);
92 napi_set_named_property(env, error, "code", code);
93 return error;
94 }
95
NapiThrow(napi_env env,int32_t errCode)96 void Common::NapiThrow(napi_env env, int32_t errCode)
97 {
98 ANS_LOGD("enter");
99
100 napi_throw(env, CreateErrorValue(env, errCode, true));
101 }
102
GetCallbackErrorValue(napi_env env,int32_t errCode)103 napi_value Common::GetCallbackErrorValue(napi_env env, int32_t errCode)
104 {
105 napi_value result = nullptr;
106 napi_value eCode = nullptr;
107 NAPI_CALL(env, napi_create_int32(env, errCode, &eCode));
108 NAPI_CALL(env, napi_create_object(env, &result));
109 NAPI_CALL(env, napi_set_named_property(env, result, "code", eCode));
110 return result;
111 }
112
PaddingCallbackPromiseInfo(const napi_env & env,const napi_ref & callback,CallbackPromiseInfo & info,napi_value & promise)113 void Common::PaddingCallbackPromiseInfo(
114 const napi_env &env, const napi_ref &callback, CallbackPromiseInfo &info, napi_value &promise)
115 {
116 ANS_LOGD("enter");
117
118 if (callback) {
119 ANS_LOGD("Callback is not nullptr.");
120 info.callback = callback;
121 info.isCallback = true;
122 } else {
123 napi_deferred deferred = nullptr;
124 NAPI_CALL_RETURN_VOID(env, napi_create_promise(env, &deferred, &promise));
125 info.deferred = deferred;
126 info.isCallback = false;
127 }
128 }
129
ReturnCallbackPromise(const napi_env & env,const CallbackPromiseInfo & info,const napi_value & result)130 void Common::ReturnCallbackPromise(const napi_env &env, const CallbackPromiseInfo &info, const napi_value &result)
131 {
132 ANS_LOGD("enter errorCode=%{public}d", info.errorCode);
133 if (info.isCallback) {
134 SetCallback(env, info.callback, info.errorCode, result, false);
135 } else {
136 SetPromise(env, info.deferred, info.errorCode, result, false);
137 }
138 ANS_LOGD("end");
139 }
140
SetCallback(const napi_env & env,const napi_ref & callbackIn,const int32_t & errorCode,const napi_value & result,bool newType)141 void Common::SetCallback(
142 const napi_env &env, const napi_ref &callbackIn, const int32_t &errorCode, const napi_value &result, bool newType)
143 {
144 ANS_LOGD("enter");
145 napi_value undefined = nullptr;
146 napi_get_undefined(env, &undefined);
147
148 napi_value callback = nullptr;
149 napi_value resultout = nullptr;
150 napi_get_reference_value(env, callbackIn, &callback);
151 napi_value results[ARGS_TWO] = {nullptr};
152 results[PARAM0] = CreateErrorValue(env, errorCode, newType);
153 results[PARAM1] = result;
154 NAPI_CALL_RETURN_VOID(env, napi_call_function(env, undefined, callback, ARGS_TWO, &results[PARAM0], &resultout));
155 ANS_LOGD("end");
156 }
157
SetCallback(const napi_env & env,const napi_ref & callbackIn,const napi_value & result)158 void Common::SetCallback(
159 const napi_env &env, const napi_ref &callbackIn, const napi_value &result)
160 {
161 ANS_LOGD("enter");
162 napi_value undefined = nullptr;
163 napi_get_undefined(env, &undefined);
164
165 napi_value callback = nullptr;
166 napi_value resultout = nullptr;
167 napi_get_reference_value(env, callbackIn, &callback);
168 NAPI_CALL_RETURN_VOID(env, napi_call_function(env, undefined, callback, ARGS_ONE, &result, &resultout));
169 ANS_LOGD("end");
170 }
171
SetCallbackArg2(const napi_env & env,const napi_ref & callbackIn,const napi_value & result0,const napi_value & result1)172 void Common::SetCallbackArg2(
173 const napi_env &env, const napi_ref &callbackIn, const napi_value &result0, const napi_value &result1)
174 {
175 ANS_LOGD("enter");
176 napi_value result[ARGS_TWO] = {result0, result1};
177 napi_value undefined = nullptr;
178 napi_get_undefined(env, &undefined);
179
180 napi_value callback = nullptr;
181 napi_value resultout = nullptr;
182 napi_get_reference_value(env, callbackIn, &callback);
183 NAPI_CALL_RETURN_VOID(env, napi_call_function(env, undefined, callback, ARGS_TWO, result, &resultout));
184 ANS_LOGD("end");
185 }
186
SetPromise(const napi_env & env,const napi_deferred & deferred,const int32_t & errorCode,const napi_value & result,bool newType)187 void Common::SetPromise(const napi_env &env,
188 const napi_deferred &deferred, const int32_t &errorCode, const napi_value &result, bool newType)
189 {
190 ANS_LOGD("enter");
191 if (errorCode == ERR_OK) {
192 napi_resolve_deferred(env, deferred, result);
193 } else {
194 napi_reject_deferred(env, deferred, CreateErrorValue(env, errorCode, newType));
195 }
196 ANS_LOGD("end");
197 }
198
JSParaError(const napi_env & env,const napi_ref & callback)199 napi_value Common::JSParaError(const napi_env &env, const napi_ref &callback)
200 {
201 if (callback) {
202 return Common::NapiGetNull(env);
203 }
204 napi_value promise = nullptr;
205 napi_deferred deferred = nullptr;
206 napi_create_promise(env, &deferred, &promise);
207 SetPromise(env, deferred, ERROR, Common::NapiGetNull(env), false);
208 return promise;
209 }
210
ParseParaOnlyCallback(const napi_env & env,const napi_callback_info & info,napi_ref & callback)211 napi_value Common::ParseParaOnlyCallback(const napi_env &env, const napi_callback_info &info, napi_ref &callback)
212 {
213 ANS_LOGD("enter");
214
215 size_t argc = ONLY_CALLBACK_MAX_PARA;
216 napi_value argv[ONLY_CALLBACK_MAX_PARA] = {nullptr};
217 napi_value thisVar = nullptr;
218 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
219 if (argc < ONLY_CALLBACK_MIN_PARA) {
220 ANS_LOGE("Wrong number of arguments");
221 return nullptr;
222 }
223
224 // argv[0]:callback
225 napi_valuetype valuetype = napi_undefined;
226 if (argc >= ONLY_CALLBACK_MAX_PARA) {
227 NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &valuetype));
228 if (valuetype != napi_function) {
229 ANS_LOGE("Callback is not function excute promise.");
230 return Common::NapiGetNull(env);
231 }
232 napi_create_reference(env, argv[PARAM0], 1, &callback);
233 }
234
235 return Common::NapiGetNull(env);
236 }
237
CreateReturnValue(const napi_env & env,const CallbackPromiseInfo & info,const napi_value & result)238 void Common::CreateReturnValue(const napi_env &env, const CallbackPromiseInfo &info, const napi_value &result)
239 {
240 ANS_LOGD("enter errorCode=%{public}d", info.errorCode);
241 int32_t errorCode = info.errorCode == ERR_OK ? ERR_OK : ErrorToExternal(info.errorCode);
242 if (info.isCallback) {
243 SetCallback(env, info.callback, errorCode, result, true);
244 } else {
245 SetPromise(env, info.deferred, errorCode, result, true);
246 }
247 ANS_LOGD("end");
248 }
249
ErrorToExternal(uint32_t errCode)250 int32_t Common::ErrorToExternal(uint32_t errCode)
251 {
252 static std::vector<std::pair<uint32_t, int32_t>> errorsConvert = {
253 {ERR_ANS_PERMISSION_DENIED, ERROR_PERMISSION_DENIED},
254 {ERR_ANS_NON_SYSTEM_APP, ERROR_NOT_SYSTEM_APP},
255 {ERR_ANS_NOT_SYSTEM_SERVICE, ERROR_NOT_SYSTEM_APP},
256 {ERR_ANS_INVALID_PARAM, ERROR_PARAM_INVALID},
257 {ERR_ANS_INVALID_UID, ERROR_PARAM_INVALID},
258 {ERR_ANS_ICON_OVER_SIZE, ERROR_PARAM_INVALID},
259 {ERR_ANS_PICTURE_OVER_SIZE, ERROR_PARAM_INVALID},
260 {ERR_ANS_PUSH_CHECK_EXTRAINFO_INVALID, ERROR_PARAM_INVALID},
261 {ERR_ANS_NO_MEMORY, ERROR_NO_MEMORY},
262 {ERR_ANS_TASK_ERR, ERROR_INTERNAL_ERROR},
263 {ERR_ANS_PARCELABLE_FAILED, ERROR_IPC_ERROR},
264 {ERR_ANS_TRANSACT_FAILED, ERROR_IPC_ERROR},
265 {ERR_ANS_REMOTE_DEAD, ERROR_IPC_ERROR},
266 {ERR_ANS_SERVICE_NOT_READY, ERROR_SERVICE_CONNECT_ERROR},
267 {ERR_ANS_SERVICE_NOT_CONNECTED, ERROR_SERVICE_CONNECT_ERROR},
268 {ERR_ANS_NOT_ALLOWED, ERROR_NOTIFICATION_CLOSED},
269 {ERR_ANS_PREFERENCES_NOTIFICATION_SLOT_ENABLED, ERROR_SLOT_CLOSED},
270 {ERR_ANS_NOTIFICATION_IS_UNREMOVABLE, ERROR_NOTIFICATION_UNREMOVABLE},
271 {ERR_ANS_NOTIFICATION_NOT_EXISTS, ERROR_NOTIFICATION_NOT_EXIST},
272 {ERR_ANS_GET_ACTIVE_USER_FAILED, ERROR_USER_NOT_EXIST},
273 {ERR_ANS_INVALID_PID, ERROR_BUNDLE_NOT_FOUND},
274 {ERR_ANS_INVALID_BUNDLE, ERROR_BUNDLE_NOT_FOUND},
275 {ERR_ANS_OVER_MAX_ACTIVE_PERSECOND, ERROR_OVER_MAX_NUM_PER_SECOND},
276 {ERR_ANS_DISTRIBUTED_OPERATION_FAILED, ERROR_DISTRIBUTED_OPERATION_FAILED},
277 {ERR_ANS_DISTRIBUTED_GET_INFO_FAILED, ERROR_DISTRIBUTED_OPERATION_FAILED},
278 {ERR_ANS_PREFERENCES_NOTIFICATION_READ_TEMPLATE_CONFIG_FAILED, ERROR_READ_TEMPLATE_CONFIG_FAILED},
279 {ERR_ANS_REPEAT_CREATE, ERROR_REPEAT_SET},
280 {ERR_ANS_END_NOTIFICATION, ERROR_REPEAT_SET},
281 {ERR_ANS_EXPIRED_NOTIFICATION, ERROR_EXPIRED_NOTIFICATION},
282 {ERR_ANS_PUSH_CHECK_FAILED, ERROR_NO_RIGHT},
283 {ERR_ANS_PUSH_CHECK_UNREGISTERED, ERROR_NO_RIGHT},
284 {ERR_ANS_PUSH_CHECK_NETWORK_UNREACHABLE, ERROR_NETWORK_UNREACHABLE}
285 };
286
287 int32_t ExternalCode = ERROR_INTERNAL_ERROR;
288 for (const auto &errorConvert : errorsConvert) {
289 if (errCode == errorConvert.first) {
290 ExternalCode = errorConvert.second;
291 break;
292 }
293 }
294
295 ANS_LOGI("internal errorCode[%{public}u] to external errorCode[%{public}d]", errCode, ExternalCode);
296 return ExternalCode;
297 }
298 } // namespace NotificationNapi
299 } // namespace OHOS
300