• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 <optional>
17 #include "remove.h"
18 
19 namespace OHOS {
20 namespace NotificationNapi {
21 const int REMOVE_MIN_PARA = 2;
22 const int REMOVE_OR_BUNDLE_MAX_PARA = 3;
23 
24 const int REMOVE_ALL_MAX_PARA = 2;
25 
26 const int REMOVE_BY_BUNDLE_AND_KEY_MIN_PARA = 3;
27 const int REMOVE_BY_BUNDLE_AND_KEY_MAX_PARA = 4;
28 
29 const int REMOVE_GROUP_BY_BUNDLE_MIN_PARA = 2;
30 const int REMOVE_GROUP_BY_BUNDLE_MAX_PARA = 3;
31 
ParseRemoveReason(const napi_env & env,const napi_value & value,RemoveParams & params)32 bool ParseRemoveReason(const napi_env &env, const napi_value &value, RemoveParams &params)
33 {
34     napi_valuetype valueType = napi_undefined;
35     NAPI_CALL_BASE(env, napi_typeof(env, value, &valueType), false);
36     if (valueType != napi_number) {
37         ANS_LOGW("RemoveReason valueType unexpected.");
38         return false;
39     }
40     int32_t removeReason = 0;
41     napi_get_value_int32(env, value, &removeReason);
42     if (!Common::IsValidRemoveReason(removeReason)) {
43         ANS_LOGW("RemoveReason value unexpected.");
44         return false;
45     }
46     params.removeReason = removeReason;
47     return true;
48 }
49 
ParseCallbackFunc(const napi_env & env,const napi_value & value,RemoveParams & params)50 bool ParseCallbackFunc(const napi_env &env, const napi_value &value,
51     RemoveParams &params)
52 {
53     napi_valuetype valueType = napi_undefined;
54     NAPI_CALL_BASE(env, napi_typeof(env, value, &valueType), false);
55     if (valueType != napi_function) {
56         ANS_LOGW("Wrong argument type. Function expected.");
57         return false;
58     }
59     napi_create_reference(env, value, 1, &params.callback);
60     return true;
61 }
62 
ParseHashcodeTypeParams(const napi_env & env,napi_value * argv,size_t argc,RemoveParams & params)63 bool ParseHashcodeTypeParams(const napi_env &env, napi_value* argv, size_t argc, RemoveParams &params)
64 {
65     // argv[0]: hashCode
66     size_t strLen = 0;
67     char str[STR_MAX_SIZE] = {0};
68     NAPI_CALL_BASE(env, napi_get_value_string_utf8(env, argv[PARAM0], str, STR_MAX_SIZE - 1, &strLen), false);
69     params.hashcode = str;
70     // argv[1]:removeReason
71     if (!ParseRemoveReason(env, argv[PARAM1], params)) {
72         return false;
73     }
74     // argv[2]:callback
75     if (argc >= REMOVE_OR_BUNDLE_MAX_PARA) {
76         if (!ParseCallbackFunc(env, argv[PARAM2], params)) {
77             return false;
78         }
79     }
80     return true;
81 }
82 
ParseBundleOptionTypeParams(const napi_env & env,napi_value * argv,size_t argc,RemoveParams & params)83 bool ParseBundleOptionTypeParams(const napi_env &env, napi_value* argv, size_t argc, RemoveParams &params)
84 {
85     if (argc < REMOVE_BY_BUNDLE_AND_KEY_MIN_PARA) {
86         ANS_LOGW("Wrong number of arguments.");
87         return false;
88     }
89     BundleAndKeyInfo bundleInfo {};
90     // argv[0]: BundleOption  argv[1]: NotificationKey
91     if (Common::GetBundleOption(env, argv[PARAM0], bundleInfo.option) == nullptr ||
92         Common::GetNotificationKey(env, argv[PARAM1], bundleInfo.key) == nullptr) {
93         ANS_LOGE("GetBundleOption failed.");
94         return false;
95     }
96     params.bundleAndKeyInfo = bundleInfo;
97     // argv[2]:removeReason
98     if (!ParseRemoveReason(env, argv[PARAM2], params)) {
99         return false;
100     }
101     // argv[3]:callback
102     if (argc >= REMOVE_BY_BUNDLE_AND_KEY_MAX_PARA) {
103         if (!ParseCallbackFunc(env, argv[PARAM3], params)) {
104             return false;
105         }
106     }
107     return true;
108 }
109 
ParseParameters(const napi_env & env,const napi_callback_info & info,RemoveParams & params)110 bool ParseParameters(const napi_env &env, const napi_callback_info &info, RemoveParams &params)
111 {
112     ANS_LOGI("enter");
113     size_t argc = REMOVE_BY_BUNDLE_AND_KEY_MAX_PARA;
114     napi_value argv[REMOVE_BY_BUNDLE_AND_KEY_MAX_PARA] = {nullptr};
115     napi_value thisVar = nullptr;
116     NAPI_CALL_BASE(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL), false);
117     if (argc < REMOVE_MIN_PARA) {
118         ANS_LOGW("Wrong number of arguments.");
119         return false;
120     }
121     napi_valuetype valueType = napi_undefined;
122     NAPI_CALL_BASE(env, napi_typeof(env, argv[PARAM0], &valueType), false);
123     if ((valueType != napi_string) && (valueType != napi_object)) {
124         ANS_LOGW("Wrong argument type. String or object expected.");
125         return false;
126     }
127     if (valueType == napi_string) {
128         return ParseHashcodeTypeParams(env, argv, argc, params);
129     }
130     return ParseBundleOptionTypeParams(env, argv, argc, params);
131 }
132 
ParseParametersByRemoveAll(const napi_env & env,const napi_callback_info & info,RemoveParams & params)133 napi_value ParseParametersByRemoveAll(const napi_env &env, const napi_callback_info &info, RemoveParams &params)
134 {
135     ANS_LOGI("enter");
136 
137     size_t argc = REMOVE_ALL_MAX_PARA;
138     napi_value argv[REMOVE_ALL_MAX_PARA] = {nullptr};
139     napi_value thisVar = nullptr;
140     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
141 
142     if (argc == 0) {
143         return Common::NapiGetNull(env);
144     }
145 
146     // argv[0]: bundle / userId / callback
147     napi_valuetype valuetype = napi_undefined;
148     NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &valuetype));
149     if ((valuetype != napi_object) && (valuetype != napi_number) && (valuetype != napi_function)) {
150         ANS_LOGW("Wrong argument type. Function or object expected.");
151         return nullptr;
152     }
153     if (valuetype == napi_object) {
154         BundleAndKeyInfo bundleandKeyInfo {};
155         auto retValue = Common::GetBundleOption(env, argv[PARAM0], bundleandKeyInfo.option);
156         if (retValue == nullptr) {
157             ANS_LOGW("GetBundleOption failed.");
158             return nullptr;
159         }
160         params.bundleAndKeyInfo = bundleandKeyInfo;
161     } else if (valuetype == napi_number) {
162         NAPI_CALL(env, napi_get_value_int32(env, argv[PARAM0], &params.userId));
163         params.hasUserId = true;
164     } else {
165         napi_create_reference(env, argv[PARAM0], 1, &params.callback);
166     }
167 
168     // argv[1]:callback
169     if (argc >= REMOVE_ALL_MAX_PARA) {
170         NAPI_CALL(env, napi_typeof(env, argv[PARAM1], &valuetype));
171         if (valuetype != napi_function) {
172             ANS_LOGW("Wrong argument type. Function expected.");
173             return nullptr;
174         }
175         napi_create_reference(env, argv[PARAM1], 1, &params.callback);
176     }
177 
178     return Common::NapiGetNull(env);
179 }
180 
ParseParameters(const napi_env & env,const napi_callback_info & info,RemoveParamsGroupByBundle & params)181 napi_value ParseParameters(
182     const napi_env &env, const napi_callback_info &info, RemoveParamsGroupByBundle &params)
183 {
184     ANS_LOGI("enter");
185 
186     size_t argc = REMOVE_GROUP_BY_BUNDLE_MAX_PARA;
187     napi_value argv[REMOVE_GROUP_BY_BUNDLE_MAX_PARA] = {nullptr};
188     napi_value thisVar = nullptr;
189     napi_valuetype valuetype = napi_undefined;
190     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
191     if (argc < REMOVE_GROUP_BY_BUNDLE_MIN_PARA) {
192         ANS_LOGW("Wrong number of arguments.");
193         return nullptr;
194     }
195 
196     // argv[0]: bundle
197     NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &valuetype));
198     if (valuetype != napi_object) {
199         ANS_LOGW("Wrong argument type. Object expected.");
200         return nullptr;
201     }
202     auto retValue = Common::GetBundleOption(env, argv[PARAM0], params.option);
203     if (retValue == nullptr) {
204         ANS_LOGE("GetBundleOption failed.");
205         return nullptr;
206     }
207 
208     // argv[1]: groupName: string
209     NAPI_CALL(env, napi_typeof(env, argv[PARAM1], &valuetype));
210     if (valuetype != napi_string) {
211         ANS_LOGW("Wrong argument type. String expected.");
212         return nullptr;
213     }
214     char str[STR_MAX_SIZE] = {0};
215     size_t strLen = 0;
216     NAPI_CALL(env, napi_get_value_string_utf8(env, argv[PARAM1], str, STR_MAX_SIZE - 1, &strLen));
217     params.groupName = str;
218     // argv[2]:callback
219     if (argc >= REMOVE_GROUP_BY_BUNDLE_MAX_PARA) {
220         NAPI_CALL(env, napi_typeof(env, argv[PARAM2], &valuetype));
221         if (valuetype != napi_function) {
222             ANS_LOGW("Wrong argument type. Function expected.");
223             return nullptr;
224         }
225         napi_create_reference(env, argv[PARAM2], 1, &params.callback);
226     }
227     return Common::NapiGetNull(env);
228 }
229 
RemoveExecuteCallback(napi_env env,void * data)230 void RemoveExecuteCallback(napi_env env, void *data)
231 {
232     ANS_LOGI("Remove napi_create_async_work start");
233     if (!data) {
234         ANS_LOGE("Invalid async callback data");
235         return;
236     }
237     auto removeInfo = static_cast<AsyncCallbackInfoRemove *>(data);
238     if (removeInfo) {
239         if (removeInfo->params.hashcode.has_value()) {
240             removeInfo->info.errorCode = NotificationHelper::RemoveNotification(removeInfo->params.hashcode.value(),
241                 removeInfo->params.removeReason);
242         } else if (removeInfo->params.bundleAndKeyInfo.has_value()) {
243             auto &infos = removeInfo->params.bundleAndKeyInfo.value();
244             removeInfo->info.errorCode = NotificationHelper::RemoveNotification(infos.option,
245                 infos.key.id, infos.key.label, removeInfo->params.removeReason);
246         }
247     }
248 }
249 
RemoveCompleteCallback(napi_env env,napi_status status,void * data)250 void RemoveCompleteCallback(napi_env env, napi_status status, void *data)
251 {
252     ANS_LOGI("Remove napi_create_async_work end");
253     if (!data) {
254         ANS_LOGE("Invalid async callback data");
255         return;
256     }
257     auto removeInfo = static_cast<AsyncCallbackInfoRemove *>(data);
258     if (removeInfo) {
259         Common::ReturnCallbackPromise(env, removeInfo->info, Common::NapiGetNull(env));
260         if (removeInfo->info.callback != nullptr) {
261             napi_delete_reference(env, removeInfo->info.callback);
262         }
263         napi_delete_async_work(env, removeInfo->asyncWork);
264         delete removeInfo;
265         removeInfo = nullptr;
266     }
267 }
268 
Remove(napi_env env,napi_callback_info info)269 napi_value Remove(napi_env env, napi_callback_info info)
270 {
271     ANS_LOGI("enter");
272     RemoveParams params {};
273     if (!ParseParameters(env, info, params)) {
274         return Common::NapiGetUndefined(env);
275     }
276     auto removeInfo = new (std::nothrow) AsyncCallbackInfoRemove {.env = env, .asyncWork = nullptr, .params = params};
277     if (!removeInfo) {
278         return Common::JSParaError(env, params.callback);
279     }
280     napi_value promise = nullptr;
281     Common::PaddingCallbackPromiseInfo(env, params.callback, removeInfo->info, promise);
282 
283     napi_value resourceName = nullptr;
284     napi_create_string_latin1(env, "remove", NAPI_AUTO_LENGTH, &resourceName);
285     // Asynchronous function call
286     napi_create_async_work(env, nullptr, resourceName, RemoveExecuteCallback, RemoveCompleteCallback,
287         (void *)removeInfo, &removeInfo->asyncWork);
288     NAPI_CALL(env, napi_queue_async_work(env, removeInfo->asyncWork));
289     if (removeInfo->info.isCallback) {
290         return Common::NapiGetNull(env);
291     } else {
292         return promise;
293     }
294 }
295 
RemoveAll(napi_env env,napi_callback_info info)296 napi_value RemoveAll(napi_env env, napi_callback_info info)
297 {
298     ANS_LOGI("enter");
299 
300     RemoveParams params {};
301     if (ParseParametersByRemoveAll(env, info, params) == nullptr) {
302         return Common::NapiGetUndefined(env);
303     }
304 
305     AsyncCallbackInfoRemove *asynccallbackinfo =
306         new (std::nothrow) AsyncCallbackInfoRemove {.env = env, .asyncWork = nullptr, .params = params};
307     if (!asynccallbackinfo) {
308         return Common::JSParaError(env, params.callback);
309     }
310     napi_value promise = nullptr;
311     Common::PaddingCallbackPromiseInfo(env, params.callback, asynccallbackinfo->info, promise);
312 
313     napi_value resourceName = nullptr;
314     napi_create_string_latin1(env, "removeAll", NAPI_AUTO_LENGTH, &resourceName);
315     // Asynchronous function call
316     napi_create_async_work(env,
317         nullptr,
318         resourceName,
319         [](napi_env env, void *data) {
320             ANS_LOGI("RemoveAll napi_create_async_work start");
321             AsyncCallbackInfoRemove *asynccallbackinfo = static_cast<AsyncCallbackInfoRemove *>(data);
322             if (asynccallbackinfo) {
323                 if (asynccallbackinfo->params.bundleAndKeyInfo.has_value()) {
324                     auto &infos = asynccallbackinfo->params.bundleAndKeyInfo.value();
325 
326                     asynccallbackinfo->info.errorCode = NotificationHelper::RemoveAllNotifications(infos.option);
327                 } else if (asynccallbackinfo->params.hasUserId) {
328                     asynccallbackinfo->info.errorCode = NotificationHelper::RemoveNotifications(
329                         asynccallbackinfo->params.userId);
330                 } else {
331                     asynccallbackinfo->info.errorCode = NotificationHelper::RemoveNotifications();
332                 }
333             }
334         },
335         [](napi_env env, napi_status status, void *data) {
336             ANS_LOGI("RemoveAll napi_create_async_work end");
337             AsyncCallbackInfoRemove *asynccallbackinfo = static_cast<AsyncCallbackInfoRemove *>(data);
338             if (asynccallbackinfo) {
339                 Common::ReturnCallbackPromise(env, asynccallbackinfo->info, Common::NapiGetNull(env));
340                 if (asynccallbackinfo->info.callback != nullptr) {
341                     napi_delete_reference(env, asynccallbackinfo->info.callback);
342                 }
343                 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
344                 delete asynccallbackinfo;
345                 asynccallbackinfo = nullptr;
346             }
347         },
348         (void *)asynccallbackinfo,
349         &asynccallbackinfo->asyncWork);
350 
351     NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork));
352 
353     if (asynccallbackinfo->info.isCallback) {
354         return Common::NapiGetNull(env);
355     } else {
356         return promise;
357     }
358 }
359 
AsyncCompleteCallbackRemoveGroupByBundle(napi_env env,napi_status status,void * data)360 void AsyncCompleteCallbackRemoveGroupByBundle(napi_env env, napi_status status, void *data)
361 {
362     ANS_LOGI("enter");
363     if (!data) {
364         ANS_LOGE("Invalid async callback data");
365         return;
366     }
367     AsyncCallbackInfoRemoveGroupByBundle *asynccallbackinfo = static_cast<AsyncCallbackInfoRemoveGroupByBundle *>(data);
368     if (asynccallbackinfo) {
369         Common::ReturnCallbackPromise(env, asynccallbackinfo->info, Common::NapiGetNull(env));
370         if (asynccallbackinfo->info.callback != nullptr) {
371             napi_delete_reference(env, asynccallbackinfo->info.callback);
372         }
373         napi_delete_async_work(env, asynccallbackinfo->asyncWork);
374         delete asynccallbackinfo;
375         asynccallbackinfo = nullptr;
376     }
377 }
378 
RemoveGroupByBundle(napi_env env,napi_callback_info info)379 napi_value RemoveGroupByBundle(napi_env env, napi_callback_info info)
380 {
381     ANS_LOGI("enter");
382 
383     RemoveParamsGroupByBundle params {};
384     if (ParseParameters(env, info, params) == nullptr) {
385         return Common::NapiGetUndefined(env);
386     }
387 
388     AsyncCallbackInfoRemoveGroupByBundle *asynccallbackinfo =
389         new (std::nothrow) AsyncCallbackInfoRemoveGroupByBundle {.env = env, .asyncWork = nullptr, .params = params};
390     if (!asynccallbackinfo) {
391         return Common::JSParaError(env, params.callback);
392     }
393     napi_value promise = nullptr;
394     Common::PaddingCallbackPromiseInfo(env, params.callback, asynccallbackinfo->info, promise);
395 
396     napi_value resourceName = nullptr;
397     napi_create_string_latin1(env, "removeGroupByBundle", NAPI_AUTO_LENGTH, &resourceName);
398     // Asynchronous function call
399     napi_create_async_work(env,
400         nullptr,
401         resourceName,
402         [](napi_env env, void *data) {
403             ANS_LOGI("RemoveGroupByBundle napi_create_async_work start");
404             AsyncCallbackInfoRemoveGroupByBundle *asynccallbackinfo =
405                 static_cast<AsyncCallbackInfoRemoveGroupByBundle *>(data);
406             if (asynccallbackinfo) {
407                 ANS_LOGI("option.bundle = %{public}s, option.uid = %{public}d, groupName = %{public}s",
408                     asynccallbackinfo->params.option.GetBundleName().c_str(),
409                     asynccallbackinfo->params.option.GetUid(),
410                     asynccallbackinfo->params.groupName.c_str());
411                 asynccallbackinfo->info.errorCode = NotificationHelper::RemoveGroupByBundle(
412                     asynccallbackinfo->params.option, asynccallbackinfo->params.groupName);
413             }
414         },
415         AsyncCompleteCallbackRemoveGroupByBundle,
416         (void *)asynccallbackinfo,
417         &asynccallbackinfo->asyncWork);
418 
419     NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork));
420 
421     if (asynccallbackinfo->info.isCallback) {
422         return Common::NapiGetNull(env);
423     } else {
424         return promise;
425     }
426 }
427 }  // namespace NotificationNapi
428 }  // namespace OHOS