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