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 "cancel.h"
17
18 namespace OHOS {
19 namespace NotificationNapi {
20 constexpr int8_t CANCEL_MAX_PARA = 3;
21 constexpr int8_t CANCEL_GROUP_MAX_PARA = 2;
22 constexpr int8_t CANCEL_GROUP_MIN_PARA = 1;
23 constexpr int8_t CANCEL_AS_BUNDLE_MAX_PARA = 4;
24
ParseParameters(const napi_env & env,const napi_callback_info & info,ParametersInfoCancel & paras)25 napi_value ParseParameters(const napi_env &env, const napi_callback_info &info, ParametersInfoCancel ¶s)
26 {
27 ANS_LOGI("enter");
28
29 size_t argc = CANCEL_MAX_PARA;
30 napi_value argv[CANCEL_MAX_PARA] = {nullptr};
31 napi_value thisVar = nullptr;
32 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
33 if (argc < 1) {
34 ANS_LOGW("Wrong number of arguments");
35 return nullptr;
36 }
37
38 napi_valuetype valuetype = napi_undefined;
39 // argv[0]: id: number
40 NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &valuetype));
41 if (valuetype != napi_number) {
42 ANS_LOGW("Wrong argument type. Number expected.");
43 return nullptr;
44 }
45 NAPI_CALL(env, napi_get_value_int32(env, argv[PARAM0], ¶s.id));
46
47 // argv[1]: label: string / callback
48 if (argc >= CANCEL_MAX_PARA - 1) {
49 NAPI_CALL(env, napi_typeof(env, argv[PARAM1], &valuetype));
50 if (valuetype == napi_undefined || valuetype == napi_null) {
51 return Common::NapiGetNull(env);
52 }
53 if (valuetype != napi_number && valuetype != napi_boolean &&
54 valuetype != napi_string && valuetype != napi_function) {
55 ANS_LOGW("Wrong argument type. String or function expected.");
56 return nullptr;
57 }
58 if (valuetype == napi_number) {
59 int64_t number = 0;
60 NAPI_CALL(env, napi_get_value_int64(env, argv[PARAM1], &number));
61 paras.label = std::to_string(number);
62 } else if (valuetype == napi_boolean) {
63 bool result = false;
64 NAPI_CALL(env, napi_get_value_bool(env, argv[PARAM1], &result));
65 paras.label = std::to_string(result);
66 } else if (valuetype == napi_string) {
67 char str[STR_MAX_SIZE] = {0};
68 size_t strLen = 0;
69 NAPI_CALL(env, napi_get_value_string_utf8(env, argv[PARAM1], str, STR_MAX_SIZE - 1, &strLen));
70 paras.label = str;
71 } else {
72 napi_create_reference(env, argv[PARAM1], 1, ¶s.callback);
73 }
74 }
75
76 // argv[2]: callback
77 if (argc >= CANCEL_MAX_PARA) {
78 NAPI_CALL(env, napi_typeof(env, argv[PARAM2], &valuetype));
79 if (valuetype != napi_function) {
80 ANS_LOGW("Callback is not function excute promise.");
81 return Common::NapiGetNull(env);
82 }
83 napi_create_reference(env, argv[PARAM2], 1, ¶s.callback);
84 }
85
86 return Common::NapiGetNull(env);
87 }
88
ParseParameters(const napi_env & env,const napi_callback_info & info,ParametersInfoCancelGroup & paras)89 napi_value ParseParameters(const napi_env &env, const napi_callback_info &info, ParametersInfoCancelGroup ¶s)
90 {
91 ANS_LOGI("enter");
92
93 size_t argc = CANCEL_GROUP_MAX_PARA;
94 napi_value argv[CANCEL_GROUP_MAX_PARA] = {nullptr};
95 napi_value thisVar = nullptr;
96 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
97 if (argc < CANCEL_GROUP_MIN_PARA) {
98 ANS_LOGW("Wrong number of arguments");
99 return nullptr;
100 }
101
102 napi_valuetype valuetype = napi_undefined;
103 // argv[0]: groupName: string
104 NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &valuetype));
105 if (valuetype != napi_string && valuetype != napi_number && valuetype != napi_boolean) {
106 ANS_LOGW("Wrong argument type. String number boolean expected.");
107 return nullptr;
108 }
109 if (valuetype == napi_string) {
110 char str[STR_MAX_SIZE] = {0};
111 size_t strLen = 0;
112 NAPI_CALL(env, napi_get_value_string_utf8(env, argv[PARAM0], str, STR_MAX_SIZE - 1, &strLen));
113 paras.groupName = str;
114 } else if (valuetype == napi_number) {
115 int64_t number = 0;
116 NAPI_CALL(env, napi_get_value_int64(env, argv[PARAM0], &number));
117 paras.groupName = std::to_string(number);
118 } else {
119 bool result = false;
120 NAPI_CALL(env, napi_get_value_bool(env, argv[PARAM0], &result));
121 paras.groupName = std::to_string(result);
122 }
123
124 // argv[1]: callback
125 if (argc >= CANCEL_GROUP_MAX_PARA) {
126 NAPI_CALL(env, napi_typeof(env, argv[PARAM1], &valuetype));
127 if (valuetype != napi_function) {
128 ANS_LOGW("Callback is not function excute promise.");
129 return Common::NapiGetNull(env);
130 }
131 napi_create_reference(env, argv[PARAM1], 1, ¶s.callback);
132 }
133
134 return Common::NapiGetNull(env);
135 }
136
Cancel(napi_env env,napi_callback_info info)137 napi_value Cancel(napi_env env, napi_callback_info info)
138 {
139 ANS_LOGI("enter");
140
141 ParametersInfoCancel paras;
142 if (ParseParameters(env, info, paras) == nullptr) {
143 return Common::NapiGetUndefined(env);
144 }
145
146 AsyncCallbackInfoCancel *asynccallbackinfo = new (std::nothrow)
147 AsyncCallbackInfoCancel {.env = env, .asyncWork = nullptr, .id = paras.id, .label = paras.label};
148 if (!asynccallbackinfo) {
149 return Common::JSParaError(env, paras.callback);
150 }
151 napi_value promise = nullptr;
152 Common::PaddingCallbackPromiseInfo(env, paras.callback, asynccallbackinfo->info, promise);
153
154 napi_value resourceName = nullptr;
155 napi_create_string_latin1(env, "cancel", NAPI_AUTO_LENGTH, &resourceName);
156 // Asynchronous function call
157 napi_create_async_work(env,
158 nullptr,
159 resourceName,
160 [](napi_env env, void *data) {
161 ANS_LOGI("Cancel napi_create_async_work start");
162 AsyncCallbackInfoCancel *asynccallbackinfo = static_cast<AsyncCallbackInfoCancel *>(data);
163
164 if (asynccallbackinfo) {
165 asynccallbackinfo->info.errorCode =
166 NotificationHelper::CancelNotification(asynccallbackinfo->label, asynccallbackinfo->id);
167 }
168 },
169 [](napi_env env, napi_status status, void *data) {
170 ANS_LOGI("Cancel napi_create_async_work end");
171 AsyncCallbackInfoCancel *asynccallbackinfo = static_cast<AsyncCallbackInfoCancel *>(data);
172 if (asynccallbackinfo) {
173 Common::ReturnCallbackPromise(env, asynccallbackinfo->info, Common::NapiGetNull(env));
174 if (asynccallbackinfo->info.callback != nullptr) {
175 napi_delete_reference(env, asynccallbackinfo->info.callback);
176 }
177 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
178 delete asynccallbackinfo;
179 asynccallbackinfo = nullptr;
180 }
181 },
182 (void *)asynccallbackinfo,
183 &asynccallbackinfo->asyncWork);
184
185 napi_status status = napi_queue_async_work_with_qos(env, asynccallbackinfo->asyncWork, napi_qos_user_initiated);
186 if (status != napi_ok) {
187 ANS_LOGE("napi_queue_async_work failed return: %{public}d", status);
188 if (asynccallbackinfo->info.callback != nullptr) {
189 napi_delete_reference(env, asynccallbackinfo->info.callback);
190 }
191 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
192 delete asynccallbackinfo;
193 asynccallbackinfo = nullptr;
194 return Common::JSParaError(env, paras.callback);
195 }
196
197 if (asynccallbackinfo->info.isCallback) {
198 return Common::NapiGetNull(env);
199 } else {
200 return promise;
201 }
202 }
203
CancelAll(napi_env env,napi_callback_info info)204 napi_value CancelAll(napi_env env, napi_callback_info info)
205 {
206 ANS_LOGI("enter");
207
208 napi_ref callback = nullptr;
209 if (Common::ParseParaOnlyCallback(env, info, callback) == nullptr) {
210 return Common::NapiGetUndefined(env);
211 }
212
213 auto asynccallbackinfo = new (std::nothrow) AsyncCallbackInfoCancel {.env = env, .asyncWork = nullptr};
214 if (!asynccallbackinfo) {
215 return Common::JSParaError(env, callback);
216 }
217 napi_value promise = nullptr;
218 Common::PaddingCallbackPromiseInfo(env, callback, asynccallbackinfo->info, promise);
219
220 napi_value resourceName = nullptr;
221 napi_create_string_latin1(env, "cancelAll", NAPI_AUTO_LENGTH, &resourceName);
222 // Asynchronous function call
223 napi_create_async_work(env,
224 nullptr,
225 resourceName,
226 [](napi_env env, void *data) {
227 ANS_LOGI("CancelAll napi_create_async_work start");
228 AsyncCallbackInfoCancel *asynccallbackinfo = static_cast<AsyncCallbackInfoCancel *>(data);
229 if (asynccallbackinfo) {
230 asynccallbackinfo->info.errorCode = NotificationHelper::CancelAllNotifications();
231 }
232 },
233 [](napi_env env, napi_status status, void *data) {
234 ANS_LOGI("CancelAll napi_create_async_work end");
235 AsyncCallbackInfoCancel *asynccallbackinfo = static_cast<AsyncCallbackInfoCancel *>(data);
236 if (asynccallbackinfo) {
237 Common::ReturnCallbackPromise(env, asynccallbackinfo->info, Common::NapiGetNull(env));
238 if (asynccallbackinfo->info.callback != nullptr) {
239 napi_delete_reference(env, asynccallbackinfo->info.callback);
240 }
241 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
242 delete asynccallbackinfo;
243 asynccallbackinfo = nullptr;
244 }
245 },
246 (void *)asynccallbackinfo,
247 &asynccallbackinfo->asyncWork);
248
249 napi_status status = napi_queue_async_work_with_qos(env, asynccallbackinfo->asyncWork, napi_qos_user_initiated);
250 if (status != napi_ok) {
251 ANS_LOGE("napi_queue_async_work failed return: %{public}d", status);
252 if (asynccallbackinfo->info.callback != nullptr) {
253 napi_delete_reference(env, asynccallbackinfo->info.callback);
254 }
255 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
256 delete asynccallbackinfo;
257 asynccallbackinfo = nullptr;
258 return Common::JSParaError(env, callback);
259 }
260
261 if (asynccallbackinfo->info.isCallback) {
262 return Common::NapiGetNull(env);
263 } else {
264 return promise;
265 }
266 }
267
CancelGroup(napi_env env,napi_callback_info info)268 napi_value CancelGroup(napi_env env, napi_callback_info info)
269 {
270 ANS_LOGI("enter");
271
272 ParametersInfoCancelGroup params {};
273 if (ParseParameters(env, info, params) == nullptr) {
274 return Common::NapiGetUndefined(env);
275 }
276
277 AsyncCallbackInfoCancelGroup *asynccallbackinfo = new (std::nothrow)
278 AsyncCallbackInfoCancelGroup {.env = env, .asyncWork = nullptr, .params = params};
279 if (!asynccallbackinfo) {
280 return Common::JSParaError(env, params.callback);
281 }
282 napi_value promise = nullptr;
283 Common::PaddingCallbackPromiseInfo(env, params.callback, asynccallbackinfo->info, promise);
284
285 napi_value resourceName = nullptr;
286 napi_create_string_latin1(env, "cancelGroup", NAPI_AUTO_LENGTH, &resourceName);
287 // Asynchronous function call
288 napi_create_async_work(env,
289 nullptr,
290 resourceName,
291 [](napi_env env, void *data) {
292 ANS_LOGI("CancelGroup napi_create_async_work start");
293 AsyncCallbackInfoCancelGroup *asynccallbackinfo = static_cast<AsyncCallbackInfoCancelGroup *>(data);
294 if (asynccallbackinfo) {
295 ANS_LOGI("asynccallbackinfo->params.groupName = %{public}s",
296 asynccallbackinfo->params.groupName.c_str());
297 asynccallbackinfo->info.errorCode =
298 NotificationHelper::CancelGroup(asynccallbackinfo->params.groupName);
299 }
300 },
301 [](napi_env env, napi_status status, void *data) {
302 ANS_LOGI("CancelGroup napi_create_async_work end");
303 AsyncCallbackInfoCancelGroup *asynccallbackinfo = static_cast<AsyncCallbackInfoCancelGroup *>(data);
304 if (asynccallbackinfo) {
305 Common::ReturnCallbackPromise(env, asynccallbackinfo->info, Common::NapiGetNull(env));
306 if (asynccallbackinfo->info.callback != nullptr) {
307 napi_delete_reference(env, asynccallbackinfo->info.callback);
308 }
309 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
310 delete asynccallbackinfo;
311 asynccallbackinfo = nullptr;
312 }
313 },
314 (void *)asynccallbackinfo,
315 &asynccallbackinfo->asyncWork);
316
317 napi_status status = napi_queue_async_work_with_qos(env, asynccallbackinfo->asyncWork, napi_qos_user_initiated);
318 if (status != napi_ok) {
319 ANS_LOGE("napi_queue_async_work failed return: %{public}d", status);
320 if (asynccallbackinfo->info.callback != nullptr) {
321 napi_delete_reference(env, asynccallbackinfo->info.callback);
322 }
323 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
324 delete asynccallbackinfo;
325 asynccallbackinfo = nullptr;
326 return Common::JSParaError(env, params.callback);
327 }
328
329 if (asynccallbackinfo->info.isCallback) {
330 return Common::NapiGetNull(env);
331 } else {
332 return promise;
333 }
334 }
335
ParseParameters(const napi_env & env,const napi_callback_info & info,ParametersInfoCancelAsBundle & paras)336 napi_value ParseParameters(const napi_env &env, const napi_callback_info &info, ParametersInfoCancelAsBundle ¶s)
337 {
338 ANS_LOGI("enter");
339
340 size_t argc = CANCEL_AS_BUNDLE_MAX_PARA;
341 napi_value argv[CANCEL_AS_BUNDLE_MAX_PARA] = {nullptr};
342 napi_value thisVar = nullptr;
343 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
344 if (argc < 1) {
345 ANS_LOGW("Wrong number of arguments");
346 return nullptr;
347 }
348
349 napi_valuetype valuetype = napi_undefined;
350 // argv[0]: id: number
351 NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &valuetype));
352 if (valuetype != napi_number) {
353 ANS_LOGW("Wrong argument type. Number expected.");
354 return nullptr;
355 }
356 NAPI_CALL(env, napi_get_value_int32(env, argv[PARAM0], ¶s.id));
357
358 // argv[1]: representativeBundle: string
359 NAPI_CALL(env, napi_typeof(env, argv[PARAM1], &valuetype));
360 if (valuetype != napi_string && valuetype != napi_number && valuetype != napi_boolean) {
361 ANS_LOGW("Wrong argument type. String number boolean expected.");
362 return nullptr;
363 }
364
365 if (valuetype == napi_string) {
366 char str[STR_MAX_SIZE] = {0};
367 size_t strLen = 0;
368 napi_get_value_string_utf8(env, argv[PARAM1], str, STR_MAX_SIZE - 1, &strLen);
369 paras.representativeBundle = str;
370 } else if (valuetype == napi_number) {
371 int64_t number = 0;
372 NAPI_CALL(env, napi_get_value_int64(env, argv[PARAM1], &number));
373 paras.representativeBundle = std::to_string(number);
374 } else {
375 bool result = false;
376 NAPI_CALL(env, napi_get_value_bool(env, argv[PARAM1], &result));
377 paras.representativeBundle = std::to_string(result);
378 }
379
380 // argv[2] : userId
381 NAPI_CALL(env, napi_typeof(env, argv[PARAM2], &valuetype));
382 if (valuetype != napi_number) {
383 ANS_LOGW("Wrong argument type. Number expected.");
384 return nullptr;
385 }
386 napi_get_value_int32(env, argv[PARAM2], ¶s.userId);
387
388 // argv[3]: callback
389 if (argc >= CANCEL_AS_BUNDLE_MAX_PARA) {
390 NAPI_CALL(env, napi_typeof(env, argv[PARAM3], &valuetype));
391 if (valuetype != napi_function) {
392 ANS_LOGW("Callback is not function excute promise.");
393 return Common::NapiGetNull(env);
394 }
395 napi_create_reference(env, argv[PARAM3], 1, ¶s.callback);
396 }
397
398 return Common::NapiGetNull(env);
399 }
400
CancelAsBundle(napi_env env,napi_callback_info info)401 napi_value CancelAsBundle(napi_env env, napi_callback_info info)
402 {
403 ANS_LOGI("enter");
404
405 ParametersInfoCancelAsBundle paras;
406 if (ParseParameters(env, info, paras) == nullptr) {
407 return Common::NapiGetUndefined(env);
408 }
409
410 AsyncCallbackInfoCancelAsBundle *asynccallbackinfo = new (std::nothrow) AsyncCallbackInfoCancelAsBundle {
411 .env = env, .asyncWork = nullptr,
412 .id = paras.id,
413 .representativeBundle = paras.representativeBundle,
414 .userId = paras.userId
415 };
416 if (!asynccallbackinfo) {
417 return Common::JSParaError(env, paras.callback);
418 }
419 napi_value promise = nullptr;
420 Common::PaddingCallbackPromiseInfo(env, paras.callback, asynccallbackinfo->info, promise);
421
422 napi_value resourceName = nullptr;
423 napi_create_string_latin1(env, "cancelasbundle", NAPI_AUTO_LENGTH, &resourceName);
424 // Asynchronous function call
425 napi_create_async_work(env,
426 nullptr,
427 resourceName,
428 [](napi_env env, void *data) {
429 ANS_LOGI("Cancel napi_create_async_work start");
430 AsyncCallbackInfoCancelAsBundle *asynccallbackinfo = static_cast<AsyncCallbackInfoCancelAsBundle *>(data);
431
432 if (asynccallbackinfo) {
433 asynccallbackinfo->info.errorCode = NotificationHelper::CancelAsBundle(
434 asynccallbackinfo->id, asynccallbackinfo->representativeBundle, asynccallbackinfo->userId);
435 }
436 },
437 [](napi_env env, napi_status status, void *data) {
438 ANS_LOGI("Cancel napi_create_async_work end");
439 AsyncCallbackInfoCancelAsBundle *asynccallbackinfo = static_cast<AsyncCallbackInfoCancelAsBundle *>(data);
440 if (asynccallbackinfo) {
441 Common::ReturnCallbackPromise(env, asynccallbackinfo->info, Common::NapiGetNull(env));
442 if (asynccallbackinfo->info.callback != nullptr) {
443 napi_delete_reference(env, asynccallbackinfo->info.callback);
444 }
445 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
446 delete asynccallbackinfo;
447 asynccallbackinfo = nullptr;
448 }
449 },
450 (void *)asynccallbackinfo,
451 &asynccallbackinfo->asyncWork);
452
453 napi_status status = napi_queue_async_work_with_qos(env, asynccallbackinfo->asyncWork, napi_qos_user_initiated);
454 if (status != napi_ok) {
455 ANS_LOGE("napi_queue_async_work failed return: %{public}d", status);
456 if (asynccallbackinfo->info.callback != nullptr) {
457 napi_delete_reference(env, asynccallbackinfo->info.callback);
458 }
459 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
460 delete asynccallbackinfo;
461 asynccallbackinfo = nullptr;
462 return Common::JSParaError(env, paras.callback);
463 }
464
465 if (asynccallbackinfo->info.isCallback) {
466 return Common::NapiGetNull(env);
467 } else {
468 return promise;
469 }
470 }
471 } // namespace NotificationNapi
472 } // namespace OHOS