• 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 "enable_notification.h"
17 
18 #include "ability_manager_client.h"
19 #include <uv.h>
20 
21 namespace OHOS {
22 namespace NotificationNapi {
23 const int ENABLE_NOTIFICATION_MAX_PARA = 3;
24 const int ENABLE_NOTIFICATION_MIN_PARA = 2;
25 const int IS_NOTIFICATION_ENABLE_MAX_PARA = 2;
26 
ParseParameters(const napi_env & env,const napi_callback_info & info,EnableParams & params)27 napi_value ParseParameters(const napi_env &env, const napi_callback_info &info, EnableParams &params)
28 {
29     ANS_LOGI("enter");
30 
31     size_t argc = ENABLE_NOTIFICATION_MAX_PARA;
32     napi_value argv[ENABLE_NOTIFICATION_MAX_PARA] = {nullptr};
33     napi_value thisVar = nullptr;
34     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
35     if (argc < ENABLE_NOTIFICATION_MIN_PARA) {
36         ANS_LOGW("Wrong number of arguments.");
37         return nullptr;
38     }
39 
40     // argv[0]: bundle
41     napi_valuetype valuetype = napi_undefined;
42     NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &valuetype));
43     if (valuetype != napi_object) {
44         ANS_LOGW("Wrong argument type. Object expected.");
45         return nullptr;
46     }
47     auto retValue = Common::GetBundleOption(env, argv[PARAM0], params.option);
48     if (retValue == nullptr) {
49         ANS_LOGE("GetBundleOption failed.");
50         return nullptr;
51     }
52 
53     // argv[1]: enable
54     NAPI_CALL(env, napi_typeof(env, argv[PARAM1], &valuetype));
55     if (valuetype != napi_boolean) {
56         ANS_LOGW("Wrong argument type. Bool expected.");
57         return nullptr;
58     }
59     napi_get_value_bool(env, argv[PARAM1], &params.enable);
60 
61     // argv[2]:callback
62     if (argc >= ENABLE_NOTIFICATION_MAX_PARA) {
63         NAPI_CALL(env, napi_typeof(env, argv[PARAM2], &valuetype));
64         if (valuetype != napi_function) {
65             ANS_LOGW("Wrong argument type. Function expected.");
66             return nullptr;
67         }
68         napi_create_reference(env, argv[PARAM2], 1, &params.callback);
69     }
70 
71     return Common::NapiGetNull(env);
72 }
73 
ParseParameters(const napi_env & env,const napi_callback_info & info,IsEnableParams & params)74 napi_value ParseParameters(const napi_env &env, const napi_callback_info &info, IsEnableParams &params)
75 {
76     ANS_LOGI("enter");
77 
78     size_t argc = IS_NOTIFICATION_ENABLE_MAX_PARA;
79     napi_value argv[IS_NOTIFICATION_ENABLE_MAX_PARA] = {nullptr};
80     napi_value thisVar = nullptr;
81     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
82 
83     if (argc == 0) {
84         return Common::NapiGetNull(env);
85     }
86 
87     // argv[0]: bundle / userId / callback
88     napi_valuetype valuetype = napi_undefined;
89     NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &valuetype));
90     if ((valuetype != napi_object) && (valuetype != napi_number) && (valuetype != napi_function)) {
91         ANS_LOGW("Wrong argument type. Function or object expected.");
92         return nullptr;
93     }
94     if (valuetype == napi_object) {
95         auto retValue = Common::GetBundleOption(env, argv[PARAM0], params.option);
96         if (retValue == nullptr) {
97             ANS_LOGE("GetBundleOption failed.");
98             return nullptr;
99         }
100         params.hasBundleOption = true;
101     } else if (valuetype == napi_number) {
102         NAPI_CALL(env, napi_get_value_int32(env, argv[PARAM0], &params.userId));
103         params.hasUserId = true;
104     } else {
105         napi_create_reference(env, argv[PARAM0], 1, &params.callback);
106     }
107 
108     // argv[1]:callback
109     if (argc >= IS_NOTIFICATION_ENABLE_MAX_PARA) {
110         NAPI_CALL(env, napi_typeof(env, argv[PARAM1], &valuetype));
111         if (valuetype != napi_function) {
112             ANS_LOGW("Wrong argument type. Function expected.");
113             return nullptr;
114         }
115         napi_create_reference(env, argv[PARAM1], 1, &params.callback);
116     }
117 
118     return Common::NapiGetNull(env);
119 }
120 
AsyncCompleteCallbackEnableNotification(napi_env env,napi_status status,void * data)121 void AsyncCompleteCallbackEnableNotification(napi_env env, napi_status status, void *data)
122 {
123     ANS_LOGI("enter");
124     if (!data) {
125         ANS_LOGE("Invalid async callback data");
126         return;
127     }
128     AsyncCallbackInfoEnable *asynccallbackinfo = static_cast<AsyncCallbackInfoEnable *>(data);
129     if (asynccallbackinfo) {
130         Common::ReturnCallbackPromise(env, asynccallbackinfo->info, Common::NapiGetNull(env));
131         if (asynccallbackinfo->info.callback != nullptr) {
132             napi_delete_reference(env, asynccallbackinfo->info.callback);
133         }
134         napi_delete_async_work(env, asynccallbackinfo->asyncWork);
135         delete asynccallbackinfo;
136         asynccallbackinfo = nullptr;
137     }
138 }
139 
EnableNotification(napi_env env,napi_callback_info info)140 napi_value EnableNotification(napi_env env, napi_callback_info info)
141 {
142     ANS_LOGI("enter");
143 
144     EnableParams params {};
145     if (ParseParameters(env, info, params) == nullptr) {
146         return Common::NapiGetUndefined(env);
147     }
148 
149     AsyncCallbackInfoEnable *asynccallbackinfo =
150         new (std::nothrow) AsyncCallbackInfoEnable {.env = env, .asyncWork = nullptr, .params = params};
151     if (!asynccallbackinfo) {
152         return Common::JSParaError(env, params.callback);
153     }
154     napi_value promise = nullptr;
155     Common::PaddingCallbackPromiseInfo(env, params.callback, asynccallbackinfo->info, promise);
156 
157     napi_value resourceName = nullptr;
158     napi_create_string_latin1(env, "enableNotification", NAPI_AUTO_LENGTH, &resourceName);
159     // Asynchronous function call
160     napi_create_async_work(env,
161         nullptr,
162         resourceName,
163         [](napi_env env, void *data) {
164             ANS_LOGI("EnableNotification napi_create_async_work start");
165             AsyncCallbackInfoEnable *asynccallbackinfo = static_cast<AsyncCallbackInfoEnable *>(data);
166             std::string deviceId {""};
167             if (asynccallbackinfo) {
168                 asynccallbackinfo->info.errorCode = NotificationHelper::SetNotificationsEnabledForSpecifiedBundle(
169                     asynccallbackinfo->params.option, deviceId, asynccallbackinfo->params.enable);
170                 ANS_LOGI("asynccallbackinfo->info.errorCode = %{public}d", asynccallbackinfo->info.errorCode);
171             }
172         },
173         AsyncCompleteCallbackEnableNotification,
174         (void *)asynccallbackinfo,
175         &asynccallbackinfo->asyncWork);
176 
177     NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork));
178 
179     if (asynccallbackinfo->info.isCallback) {
180         return Common::NapiGetNull(env);
181     } else {
182         return promise;
183     }
184 }
185 
AsyncCompleteCallbackIsNotificationEnabled(napi_env env,napi_status status,void * data)186 void AsyncCompleteCallbackIsNotificationEnabled(napi_env env, napi_status status, void *data)
187 {
188     ANS_LOGI("enter");
189     if (!data) {
190         ANS_LOGE("Invalid async callback data");
191         return;
192     }
193     AsyncCallbackInfoIsEnable *asynccallbackinfo = static_cast<AsyncCallbackInfoIsEnable *>(data);
194     if (asynccallbackinfo) {
195         napi_value result = nullptr;
196         napi_get_boolean(env, asynccallbackinfo->allowed, &result);
197         if (asynccallbackinfo->newInterface) {
198             Common::CreateReturnValue(env, asynccallbackinfo->info, result);
199         } else {
200             Common::ReturnCallbackPromise(env, asynccallbackinfo->info, result);
201         }
202         if (asynccallbackinfo->info.callback != nullptr) {
203             napi_delete_reference(env, asynccallbackinfo->info.callback);
204         }
205         napi_delete_async_work(env, asynccallbackinfo->asyncWork);
206         delete asynccallbackinfo;
207         asynccallbackinfo = nullptr;
208     }
209 }
210 
IsNotificationEnabled(napi_env env,napi_callback_info info)211 napi_value IsNotificationEnabled(napi_env env, napi_callback_info info)
212 {
213     ANS_LOGI("enter");
214 
215     IsEnableParams params {};
216     if (ParseParameters(env, info, params) == nullptr) {
217         return Common::NapiGetUndefined(env);
218     }
219 
220     AsyncCallbackInfoIsEnable *asynccallbackinfo =
221         new (std::nothrow) AsyncCallbackInfoIsEnable {.env = env, .asyncWork = nullptr, .params = params};
222     if (!asynccallbackinfo) {
223         return Common::JSParaError(env, params.callback);
224     }
225     napi_value promise = nullptr;
226     Common::PaddingCallbackPromiseInfo(env, params.callback, asynccallbackinfo->info, promise);
227 
228     napi_value resourceName = nullptr;
229     napi_create_string_latin1(env, "isNotificationEnabled", NAPI_AUTO_LENGTH, &resourceName);
230     // Asynchronous function call
231     napi_create_async_work(env,
232         nullptr,
233         resourceName,
234         [](napi_env env, void *data) {
235             ANS_LOGI("IsNotificationEnabled napi_create_async_work start");
236             AsyncCallbackInfoIsEnable *asynccallbackinfo = static_cast<AsyncCallbackInfoIsEnable *>(data);
237             if (asynccallbackinfo) {
238                 if (asynccallbackinfo->params.hasBundleOption) {
239                     ANS_LOGI("option.bundle = %{public}s option.uid = %{public}d",
240                         asynccallbackinfo->params.option.GetBundleName().c_str(),
241                         asynccallbackinfo->params.option.GetUid());
242                     asynccallbackinfo->info.errorCode = NotificationHelper::IsAllowedNotify(
243                         asynccallbackinfo->params.option, asynccallbackinfo->allowed);
244                 } else if (asynccallbackinfo->params.hasUserId) {
245                     ANS_LOGI("userId = %{public}d", asynccallbackinfo->params.userId);
246                     asynccallbackinfo->info.errorCode = NotificationHelper::IsAllowedNotify(
247                         asynccallbackinfo->params.userId, asynccallbackinfo->allowed);
248                 } else {
249                     asynccallbackinfo->info.errorCode = NotificationHelper::IsAllowedNotify(
250                         asynccallbackinfo->allowed);
251                 }
252                 ANS_LOGI("asynccallbackinfo->info.errorCode = %{public}d, allowed = %{public}d",
253                     asynccallbackinfo->info.errorCode, asynccallbackinfo->allowed);
254             }
255         },
256         AsyncCompleteCallbackIsNotificationEnabled,
257         (void *)asynccallbackinfo,
258         &asynccallbackinfo->asyncWork);
259 
260     NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork));
261 
262     if (asynccallbackinfo->info.isCallback) {
263         return Common::NapiGetNull(env);
264     } else {
265         return promise;
266     }
267 }
268 
IsNotificationEnabledSelf(napi_env env,napi_callback_info info)269 napi_value IsNotificationEnabledSelf(napi_env env, napi_callback_info info)
270 {
271     ANS_LOGI("enter");
272 
273     IsEnableParams params {};
274     if (ParseParameters(env, info, params) == nullptr) {
275         return Common::NapiGetUndefined(env);
276     }
277 
278     AsyncCallbackInfoIsEnable *asynccallbackinfo =
279         new (std::nothrow) AsyncCallbackInfoIsEnable {.env = env, .asyncWork = nullptr, .params = params};
280     if (!asynccallbackinfo) {
281         return Common::JSParaError(env, params.callback);
282     }
283     napi_value promise = nullptr;
284     Common::PaddingCallbackPromiseInfo(env, params.callback, asynccallbackinfo->info, promise);
285 
286     napi_value resourceName = nullptr;
287     napi_create_string_latin1(env, "IsNotificationEnabledSelf", NAPI_AUTO_LENGTH, &resourceName);
288     // Asynchronous function call
289     napi_create_async_work(env,
290         nullptr,
291         resourceName,
292         [](napi_env env, void *data) {
293             ANS_LOGI("IsNotificationEnabledSelf napi_create_async_work start");
294             AsyncCallbackInfoIsEnable *asynccallbackinfo = static_cast<AsyncCallbackInfoIsEnable *>(data);
295             if (asynccallbackinfo) {
296                 if (asynccallbackinfo->params.hasBundleOption) {
297                     ANS_LOGE("Not allowed to query another application");
298                 } else {
299                     asynccallbackinfo->info.errorCode = NotificationHelper::IsAllowedNotifySelf(
300                         asynccallbackinfo->allowed);
301                 }
302                 ANS_LOGI("asynccallbackinfo->info.errorCode = %{public}d, allowed = %{public}d",
303                     asynccallbackinfo->info.errorCode, asynccallbackinfo->allowed);
304             }
305         },
306         AsyncCompleteCallbackIsNotificationEnabled,
307         (void *)asynccallbackinfo,
308         &asynccallbackinfo->asyncWork);
309 
310     NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork));
311 
312     if (asynccallbackinfo->info.isCallback) {
313         return Common::NapiGetNull(env);
314     } else {
315         return promise;
316     }
317 }
318 
RequestEnableNotification(napi_env env,napi_callback_info info)319 napi_value RequestEnableNotification(napi_env env, napi_callback_info info)
320 {
321     ANS_LOGI("enter");
322 
323     IsEnableParams params {};
324     if (ParseParameters(env, info, params) == nullptr) {
325         return Common::NapiGetUndefined(env);
326     }
327 
328     AsyncCallbackInfoIsEnable *asynccallbackinfo =
329         new (std::nothrow) AsyncCallbackInfoIsEnable {.env = env, .asyncWork = nullptr, .params = params};
330 
331     if (!asynccallbackinfo) {
332         return Common::JSParaError(env, params.callback);
333     }
334     napi_value promise = nullptr;
335     Common::PaddingCallbackPromiseInfo(env, params.callback, asynccallbackinfo->info, promise);
336 
337     napi_value resourceName = nullptr;
338     napi_create_string_latin1(env, "RequestEnableNotification", NAPI_AUTO_LENGTH, &resourceName);
339     // Asynchronous function call
340     napi_create_async_work(env,
341         nullptr,
342         resourceName,
343         [](napi_env env, void *data) {
344             AsyncCallbackInfoIsEnable *asynccallbackinfo = static_cast<AsyncCallbackInfoIsEnable *>(data);
345             if (asynccallbackinfo) {
346                 std::string deviceId {""};
347                 asynccallbackinfo->info.errorCode =
348                     NotificationHelper::RequestEnableNotification(deviceId);
349             }
350         },
351         [](napi_env env, napi_status status, void *data) {
352             AsyncCallbackInfoIsEnable *asynccallbackinfo = static_cast<AsyncCallbackInfoIsEnable *>(data);
353             if (asynccallbackinfo) {
354                 AsyncCompleteCallbackIsNotificationEnabled(env, status, data);
355             }
356         },
357         (void *)asynccallbackinfo,
358         &asynccallbackinfo->asyncWork);
359 
360     NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork));
361 
362     if (asynccallbackinfo->info.isCallback) {
363         return Common::NapiGetNull(env);
364     } else {
365         return promise;
366     }
367 }
368 }  // namespace NotificationNapi
369 }  // namespace OHOS