• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 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 const uint32_t MAX_PARAM_NUM = 5;
33 
34 namespace {
35 static const std::unordered_map<int32_t, std::string> ERROR_CODE_MESSAGE {
36     {ERROR_PERMISSION_DENIED, "Permission denied"},
37     {ERROR_NOT_SYSTEM_APP, "The application isn't system application"},
38     {ERROR_PARAM_INVALID, "Invalid parameter"},
39     {ERROR_SYSTEM_CAP_ERROR, "SystemCapability not found"},
40     {ERROR_INTERNAL_ERROR, "Internal error"},
41     {ERROR_IPC_ERROR, "Marshalling or unmarshalling error"},
42     {ERROR_SERVICE_CONNECT_ERROR, "Failed to connect to the service"},
43     {ERROR_NOTIFICATION_CLOSED, "Notification disabled"},
44     {ERROR_SLOT_CLOSED, "Notification slot disabled"},
45     {ERROR_NOTIFICATION_UNREMOVABLE, "Notification deletion disabled"},
46     {ERROR_NOTIFICATION_NOT_EXIST, "The notification does not exist"},
47     {ERROR_USER_NOT_EXIST, "The user does not exist"},
48     {ERROR_OVER_MAX_NUM_PER_SECOND, "The notification sending frequency reaches the upper limit"},
49     {ERROR_DISTRIBUTED_OPERATION_FAILED, "Distributed operation failed"},
50     {ERROR_READ_TEMPLATE_CONFIG_FAILED, "Failed to read the template configuration"},
51     {ERROR_NO_MEMORY, "No memory space"},
52     {ERROR_BUNDLE_NOT_FOUND, "The specified bundle name was not found"},
53     {ERROR_NO_AGENT_SETTING, "There is no corresponding agent relationship configuration"},
54     {ERROR_DIALOG_IS_POPPING, "Dialog is popping"},
55     {ERROR_SETTING_WINDOW_EXIST, "The notification settings window is already displayed"},
56     {ERROR_NO_PROFILE_TEMPLATE, "Not exit noNotDisturb profile template"},
57     {ERROR_REPEAT_SET, "Repeat create or end"},
58     {ERROR_NO_RIGHT, "No permission"},
59     {ERROR_EXPIRED_NOTIFICATION, "Low update version"},
60     {ERROR_NETWORK_UNREACHABLE, "Network unreachable"},
61     {ERROR_REJECTED_WITH_DISABLE_NOTIFICATION,
62         "The application is not allowed to publish notifications due to permission control settings"},
63     {ERROR_DISTRIBUTED_OPERATION_TIMEOUT, "Distributed operation timeout"},
64 };
65 }
66 
NapiGetBoolean(napi_env env,const bool & isValue)67 napi_value Common::NapiGetBoolean(napi_env env, const bool &isValue)
68 {
69     napi_value result = nullptr;
70     napi_get_boolean(env, isValue, &result);
71     return result;
72 }
73 
NapiGetNull(napi_env env)74 napi_value Common::NapiGetNull(napi_env env)
75 {
76     napi_value result = nullptr;
77     napi_get_null(env, &result);
78     return result;
79 }
80 
NapiGetUndefined(napi_env env)81 napi_value Common::NapiGetUndefined(napi_env env)
82 {
83     napi_value result = nullptr;
84     napi_get_undefined(env, &result);
85     return result;
86 }
87 
CreateErrorValue(napi_env env,int32_t errCode,bool newType)88 napi_value Common::CreateErrorValue(napi_env env, int32_t errCode, bool newType)
89 {
90     ANS_LOGI("enter, errorCode[%{public}d]", errCode);
91     napi_value error = Common::NapiGetNull(env);
92     if (errCode == ERR_OK && newType) {
93         return error;
94     }
95 
96     napi_value code = nullptr;
97     napi_create_int32(env, errCode, &code);
98 
99     auto iter = ERROR_CODE_MESSAGE.find(errCode);
100     std::string errMsg = iter != ERROR_CODE_MESSAGE.end() ? iter->second : "";
101     napi_value message = nullptr;
102     napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &message);
103 
104     napi_create_error(env, nullptr, message, &error);
105     napi_set_named_property(env, error, "code", code);
106     return error;
107 }
108 
CreateErrorValue(napi_env env,int32_t errCode,std::string & msg)109 napi_value Common::CreateErrorValue(napi_env env, int32_t errCode, std::string &msg)
110 {
111     ANS_LOGI("enter, errorCode[%{public}d]", errCode);
112     napi_value error = Common::NapiGetNull(env);
113     if (errCode == ERR_OK) {
114         return error;
115     }
116 
117     napi_value code = nullptr;
118     napi_create_int32(env, errCode, &code);
119 
120     auto iter = ERROR_CODE_MESSAGE.find(errCode);
121     std::string errMsg = iter != ERROR_CODE_MESSAGE.end() ? iter->second : "";
122     napi_value message = nullptr;
123     napi_create_string_utf8(env, errMsg.append(" ").append(msg).c_str(), NAPI_AUTO_LENGTH, &message);
124 
125     napi_create_error(env, nullptr, message, &error);
126     napi_set_named_property(env, error, "code", code);
127     return error;
128 }
129 
NapiThrow(napi_env env,int32_t errCode)130 void Common::NapiThrow(napi_env env, int32_t errCode)
131 {
132     ANS_LOGD("enter");
133 
134     napi_throw(env, CreateErrorValue(env, errCode, true));
135 }
136 
NapiThrow(napi_env env,int32_t errCode,std::string & msg)137 void Common::NapiThrow(napi_env env, int32_t errCode, std::string &msg)
138 {
139     ANS_LOGD("enter");
140 
141     napi_throw(env, CreateErrorValue(env, errCode, msg));
142 }
143 
GetCallbackErrorValue(napi_env env,int32_t errCode)144 napi_value Common::GetCallbackErrorValue(napi_env env, int32_t errCode)
145 {
146     napi_value result = nullptr;
147     napi_value eCode = nullptr;
148     NAPI_CALL(env, napi_create_int32(env, errCode, &eCode));
149     NAPI_CALL(env, napi_create_object(env, &result));
150     NAPI_CALL(env, napi_set_named_property(env, result, "code", eCode));
151     return result;
152 }
153 
PaddingCallbackPromiseInfo(const napi_env & env,const napi_ref & callback,CallbackPromiseInfo & info,napi_value & promise)154 void Common::PaddingCallbackPromiseInfo(
155     const napi_env &env, const napi_ref &callback, CallbackPromiseInfo &info, napi_value &promise)
156 {
157     ANS_LOGD("enter");
158 
159     if (callback) {
160         ANS_LOGD("Callback is not nullptr.");
161         info.callback = callback;
162         info.isCallback = true;
163     } else {
164         napi_deferred deferred = nullptr;
165         NAPI_CALL_RETURN_VOID(env, napi_create_promise(env, &deferred, &promise));
166         info.deferred = deferred;
167         info.isCallback = false;
168     }
169 }
170 
ReturnCallbackPromise(const napi_env & env,const CallbackPromiseInfo & info,const napi_value & result)171 void Common::ReturnCallbackPromise(const napi_env &env, const CallbackPromiseInfo &info, const napi_value &result)
172 {
173     ANS_LOGD("enter errorCode=%{public}d", info.errorCode);
174     if (info.isCallback) {
175         SetCallback(env, info.callback, info.errorCode, result, false);
176     } else {
177         SetPromise(env, info.deferred, info.errorCode, result, false);
178     }
179     ANS_LOGD("end");
180 }
181 
SetCallback(const napi_env & env,const napi_ref & callbackIn,const int32_t & errorCode,const napi_value & result,bool newType)182 void Common::SetCallback(
183     const napi_env &env, const napi_ref &callbackIn, const int32_t &errorCode, const napi_value &result, bool newType)
184 {
185     ANS_LOGD("enter");
186     napi_value undefined = nullptr;
187     napi_get_undefined(env, &undefined);
188 
189     napi_value callback = nullptr;
190     napi_value resultout = nullptr;
191     napi_get_reference_value(env, callbackIn, &callback);
192     napi_value results[ARGS_TWO] = {nullptr};
193     results[PARAM0] = CreateErrorValue(env, errorCode, newType);
194     results[PARAM1] = result;
195     napi_status napi_result = napi_call_function(env, undefined, callback, ARGS_TWO, &results[PARAM0], &resultout);
196     if (napi_result != napi_ok) {
197         ANS_LOGE("napi_call_function failed, result = %{public}d", napi_result);
198     }
199     NAPI_CALL_RETURN_VOID(env, napi_result);
200     ANS_LOGI("end");
201 }
202 
SetCallback(const napi_env & env,const napi_ref & callbackIn,const napi_value & result)203 void Common::SetCallback(
204     const napi_env &env, const napi_ref &callbackIn, const napi_value &result)
205 {
206     ANS_LOGD("enter");
207     napi_value undefined = nullptr;
208     napi_get_undefined(env, &undefined);
209 
210     napi_value callback = nullptr;
211     napi_value resultout = nullptr;
212     napi_get_reference_value(env, callbackIn, &callback);
213     napi_status napi_result = napi_call_function(env, undefined, callback, ARGS_ONE, &result, &resultout);
214     if (napi_result != napi_ok) {
215         ANS_LOGE("napi_call_function failed, result = %{public}d", napi_result);
216     }
217     NAPI_CALL_RETURN_VOID(env, napi_result);
218     ANS_LOGI("end");
219 }
220 
SetCallbackArg2(const napi_env & env,const napi_ref & callbackIn,const napi_value & result0,const napi_value & result1)221 void Common::SetCallbackArg2(
222     const napi_env &env, const napi_ref &callbackIn, const napi_value &result0, const napi_value &result1)
223 {
224     ANS_LOGD("enter");
225     napi_value result[ARGS_TWO] = {result0, result1};
226     napi_value undefined = nullptr;
227     napi_get_undefined(env, &undefined);
228 
229     napi_value callback = nullptr;
230     napi_value resultout = nullptr;
231     napi_get_reference_value(env, callbackIn, &callback);
232     napi_status napi_result = napi_call_function(env, undefined, callback, ARGS_TWO, result, &resultout);
233     if (napi_result != napi_ok) {
234         ANS_LOGE("napi_call_function failed, result = %{public}d", napi_result);
235     }
236     NAPI_CALL_RETURN_VOID(env, napi_result);
237     ANS_LOGI("end");
238 }
239 
SetPromise(const napi_env & env,const napi_deferred & deferred,const int32_t & errorCode,const napi_value & result,bool newType)240 void Common::SetPromise(const napi_env &env,
241     const napi_deferred &deferred, const int32_t &errorCode, const napi_value &result, bool newType)
242 {
243     ANS_LOGD("enter");
244     if (errorCode == ERR_OK) {
245         napi_resolve_deferred(env, deferred, result);
246     } else {
247         napi_reject_deferred(env, deferred, CreateErrorValue(env, errorCode, newType));
248     }
249     ANS_LOGD("end");
250 }
251 
JSParaError(const napi_env & env,const napi_ref & callback)252 napi_value Common::JSParaError(const napi_env &env, const napi_ref &callback)
253 {
254     if (callback) {
255         return Common::NapiGetNull(env);
256     }
257     napi_value promise = nullptr;
258     napi_deferred deferred = nullptr;
259     napi_create_promise(env, &deferred, &promise);
260     SetPromise(env, deferred, ERROR, Common::NapiGetNull(env), false);
261     return promise;
262 }
263 
ParseParaOnlyCallback(const napi_env & env,const napi_callback_info & info,napi_ref & callback)264 napi_value Common::ParseParaOnlyCallback(const napi_env &env, const napi_callback_info &info, napi_ref &callback)
265 {
266     ANS_LOGD("enter");
267 
268     size_t argc = ONLY_CALLBACK_MAX_PARA;
269     napi_value argv[ONLY_CALLBACK_MAX_PARA] = {nullptr};
270     napi_value thisVar = nullptr;
271     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
272     if (argc < ONLY_CALLBACK_MIN_PARA) {
273         ANS_LOGE("Wrong number of arguments");
274         Common::NapiThrow(env, ERROR_PARAM_INVALID, MANDATORY_PARAMETER_ARE_LEFT_UNSPECIFIED);
275         return nullptr;
276     }
277 
278     // argv[0]:callback
279     napi_valuetype valuetype = napi_undefined;
280     if (argc >= ONLY_CALLBACK_MAX_PARA) {
281         NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &valuetype));
282         if (valuetype != napi_function) {
283             ANS_LOGE("Callback is not function excute promise.");
284             return Common::NapiGetNull(env);
285         }
286         napi_create_reference(env, argv[PARAM0], 1, &callback);
287     }
288 
289     return Common::NapiGetNull(env);
290 }
291 
CreateReturnValue(const napi_env & env,const CallbackPromiseInfo & info,const napi_value & result)292 void Common::CreateReturnValue(const napi_env &env, const CallbackPromiseInfo &info, const napi_value &result)
293 {
294     ANS_LOGD("enter errorCode=%{public}d", info.errorCode);
295     int32_t errorCode = info.errorCode == ERR_OK ? ERR_OK : ErrorToExternal(info.errorCode);
296     if (info.isCallback) {
297         SetCallback(env, info.callback, errorCode, result, true);
298     } else {
299         SetPromise(env, info.deferred, errorCode, result, true);
300     }
301     ANS_LOGD("end");
302 }
303 
ErrorToExternal(uint32_t errCode)304 int32_t Common::ErrorToExternal(uint32_t errCode)
305 {
306     static std::vector<std::pair<uint32_t, int32_t>> errorsConvert = {
307         {ERR_ANS_PERMISSION_DENIED, ERROR_PERMISSION_DENIED},
308         {ERR_ANS_NON_SYSTEM_APP, ERROR_NOT_SYSTEM_APP},
309         {ERR_ANS_NOT_SYSTEM_SERVICE, ERROR_NOT_SYSTEM_APP},
310         {ERR_ANS_INVALID_PARAM, ERROR_PARAM_INVALID},
311         {ERR_ANS_INVALID_UID, ERROR_PARAM_INVALID},
312         {ERR_ANS_ICON_OVER_SIZE, ERROR_PARAM_INVALID},
313         {ERR_ANS_PICTURE_OVER_SIZE, ERROR_PARAM_INVALID},
314         {ERR_ANS_PUSH_CHECK_EXTRAINFO_INVALID, ERROR_PARAM_INVALID},
315         {ERR_ANS_NO_MEMORY, ERROR_NO_MEMORY},
316         {ERR_ANS_TASK_ERR, ERROR_INTERNAL_ERROR},
317         {ERR_ANS_PARCELABLE_FAILED, ERROR_IPC_ERROR},
318         {ERR_ANS_TRANSACT_FAILED, ERROR_IPC_ERROR},
319         {ERR_ANS_REMOTE_DEAD, ERROR_IPC_ERROR},
320         {ERR_ANS_SERVICE_NOT_READY, ERROR_SERVICE_CONNECT_ERROR},
321         {ERR_ANS_SERVICE_NOT_CONNECTED, ERROR_SERVICE_CONNECT_ERROR},
322         {ERR_ANS_NOT_ALLOWED, ERROR_NOTIFICATION_CLOSED},
323         {ERR_ANS_PREFERENCES_NOTIFICATION_SLOT_ENABLED, ERROR_SLOT_CLOSED},
324         {ERR_ANS_NOTIFICATION_IS_UNREMOVABLE, ERROR_NOTIFICATION_UNREMOVABLE},
325         {ERR_ANS_NOTIFICATION_NOT_EXISTS, ERROR_NOTIFICATION_NOT_EXIST},
326         {ERR_ANS_GET_ACTIVE_USER_FAILED, ERROR_USER_NOT_EXIST},
327         {ERR_ANS_INVALID_PID, ERROR_BUNDLE_NOT_FOUND},
328         {ERR_ANS_INVALID_BUNDLE, ERROR_BUNDLE_NOT_FOUND},
329         {ERR_ANS_OVER_MAX_ACTIVE_PERSECOND, ERROR_OVER_MAX_NUM_PER_SECOND},
330         {ERR_ANS_OVER_MAX_UPDATE_PERSECOND, ERROR_OVER_MAX_NUM_PER_SECOND},
331         {ERR_ANS_DISTRIBUTED_OPERATION_FAILED, ERROR_DISTRIBUTED_OPERATION_FAILED},
332         {ERR_ANS_DISTRIBUTED_GET_INFO_FAILED, ERROR_DISTRIBUTED_OPERATION_FAILED},
333         {ERR_ANS_PREFERENCES_NOTIFICATION_READ_TEMPLATE_CONFIG_FAILED, ERROR_READ_TEMPLATE_CONFIG_FAILED},
334         {ERR_ANS_REPEAT_CREATE, ERROR_REPEAT_SET},
335         {ERR_ANS_END_NOTIFICATION, ERROR_REPEAT_SET},
336         {ERR_ANS_EXPIRED_NOTIFICATION, ERROR_EXPIRED_NOTIFICATION},
337         {ERR_ANS_PUSH_CHECK_FAILED, ERROR_NO_RIGHT},
338         {ERR_ANS_PUSH_CHECK_UNREGISTERED, ERROR_NO_RIGHT},
339         {ERR_ANS_PUSH_CHECK_NETWORK_UNREACHABLE, ERROR_NETWORK_UNREACHABLE},
340         {ERR_ANS_NO_AGENT_SETTING, ERROR_NO_AGENT_SETTING},
341         {ERR_ANS_DIALOG_IS_POPPING, ERROR_DIALOG_IS_POPPING},
342         {ERR_ANS_NO_PROFILE_TEMPLATE, ERROR_NO_PROFILE_TEMPLATE},
343         {ERR_ANS_REJECTED_WITH_DISABLE_NOTIFICATION, ERROR_REJECTED_WITH_DISABLE_NOTIFICATION},
344         {ERR_ANS_OPERATION_TIMEOUT, ERROR_DISTRIBUTED_OPERATION_TIMEOUT},
345     };
346 
347     int32_t ExternalCode = ERROR_INTERNAL_ERROR;
348     for (const auto &errorConvert : errorsConvert) {
349         if (errCode == errorConvert.first) {
350             ExternalCode = errorConvert.second;
351             break;
352         }
353     }
354 
355     ANS_LOGI("internal errorCode[%{public}u] to external errorCode[%{public}d]", errCode, ExternalCode);
356     return ExternalCode;
357 }
358 
NapiReturnCapErrCb(napi_env env,napi_callback_info info)359 napi_value Common::NapiReturnCapErrCb(napi_env env, napi_callback_info info)
360 {
361     size_t argc = MAX_PARAM_NUM;
362     napi_value argv[MAX_PARAM_NUM] = {nullptr};
363     napi_value thisVar = nullptr;
364     napi_ref callback = nullptr;
365     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
366     for (size_t i = 0; i < argc && i < MAX_PARAM_NUM; ++i) {
367         napi_valuetype valuetype = napi_undefined;
368         NAPI_CALL(env, napi_typeof(env, argv[i], &valuetype));
369         if (valuetype == napi_function) {
370             napi_create_reference(env, argv[i], 1, &callback);
371             SetCallback(env, callback, ERROR_SYSTEM_CAP_ERROR, nullptr, false);
372             napi_delete_reference(env, callback);
373             return NapiGetNull(env);
374         }
375     }
376 
377     return NapiReturnCapErr(env, info);
378 }
379 
NapiReturnCapErr(napi_env env,napi_callback_info info)380 napi_value Common::NapiReturnCapErr(napi_env env, napi_callback_info info)
381 {
382     napi_value promise = nullptr;
383     napi_deferred deferred = nullptr;
384     napi_create_promise(env, &deferred, &promise);
385     SetPromise(env, deferred, ERROR_SYSTEM_CAP_ERROR, Common::NapiGetNull(env), false);
386     return promise;
387 }
388 
NapiReturnFalseCb(napi_env env,napi_callback_info info)389 napi_value Common::NapiReturnFalseCb(napi_env env, napi_callback_info info)
390 {
391     return Common::NapiReturnFalseCbInner(env, info, false);
392 }
393 
NapiReturnFalseCbNewType(napi_env env,napi_callback_info info)394 napi_value Common::NapiReturnFalseCbNewType(napi_env env, napi_callback_info info)
395 {
396     return Common::NapiReturnFalseCbInner(env, info, true);
397 }
398 
NapiReturnFalseCbInner(napi_env env,napi_callback_info info,bool newType)399 napi_value Common::NapiReturnFalseCbInner(napi_env env, napi_callback_info info, bool newType)
400 {
401     size_t argc = ONLY_CALLBACK_MAX_PARA;
402     napi_value argv[ONLY_CALLBACK_MAX_PARA] = {nullptr};
403     napi_value thisVar = nullptr;
404     napi_ref callback = nullptr;
405     napi_value result = nullptr;
406     napi_get_boolean(env, false, &result);
407     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
408     if (argc >= ONLY_CALLBACK_MIN_PARA) {
409         napi_valuetype valuetype = napi_undefined;
410         NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &valuetype));
411         if (valuetype == napi_function) {
412             napi_create_reference(env, argv[PARAM0], 1, &callback);
413             SetCallback(env, callback, 0, result, true);
414             napi_delete_reference(env, callback);
415             return NapiGetNull(env);
416         }
417     }
418     napi_value promise = nullptr;
419     napi_deferred deferred = nullptr;
420     napi_create_promise(env, &deferred, &promise);
421     SetPromise(env, deferred, 0, result, false);
422     return promise;
423 }
424 }  // namespace NotificationNapi
425 }  // namespace OHOS
426