1 /*
2 * Copyright (c) 2022-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 "napi_get_active.h"
17
18 #include "ans_inner_errors.h"
19 #include "get_active.h"
20 #include "napi_common_util.h"
21 #include "napi_common_want.h"
22 #include <memory>
23
24 namespace OHOS {
25 namespace NotificationNapi {
AsyncCompleteCallbackNapiGetAllActiveNotifications(napi_env env,napi_status status,void * data)26 void AsyncCompleteCallbackNapiGetAllActiveNotifications(napi_env env, napi_status status, void *data)
27 {
28 ANS_LOGD("enter");
29 if (!data) {
30 ANS_LOGE("Invalid async callback data.");
31 return;
32 }
33
34 auto asynccallbackinfo = static_cast<AsyncCallbackInfoActive *>(data);
35 if (asynccallbackinfo) {
36 ANS_LOGD("Conversion data is success.");
37 napi_value result = nullptr;
38 if (asynccallbackinfo->info.errorCode != ERR_OK) {
39 result = Common::NapiGetNull(env);
40 } else {
41 napi_value arr = nullptr;
42 int32_t count = 0;
43 napi_create_array(env, &arr);
44 for (auto vec : asynccallbackinfo->notifications) {
45 if (!vec) {
46 ANS_LOGW("Invalid Notification object ptr");
47 continue;
48 }
49 napi_value notificationResult = nullptr;
50 napi_create_object(env, ¬ificationResult);
51 if (!Common::SetNotification(env, vec.GetRefPtr(), notificationResult)) {
52 ANS_LOGW("Set Notification object failed");
53 continue;
54 }
55 napi_set_element(env, arr, count, notificationResult);
56 count++;
57 }
58 ANS_LOGI("Get all active notifications by napi. count = %{public}d", count);
59 result = arr;
60 if ((count == 0) && (asynccallbackinfo->notifications.size() > 0)) {
61 asynccallbackinfo->info.errorCode = ERROR;
62 result = Common::NapiGetNull(env);
63 }
64 }
65 Common::CreateReturnValue(env, asynccallbackinfo->info, result);
66 if (asynccallbackinfo->info.callback != nullptr) {
67 ANS_LOGD("Delete NapiGetAllActiveNotifications callback reference.");
68 napi_delete_reference(env, asynccallbackinfo->info.callback);
69 }
70 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
71 delete asynccallbackinfo;
72 asynccallbackinfo = nullptr;
73 }
74 }
75
NapiGetAllActiveNotifications(napi_env env,napi_callback_info info)76 napi_value NapiGetAllActiveNotifications(napi_env env, napi_callback_info info)
77 {
78 ANS_LOGD("enter");
79 napi_ref callback = nullptr;
80 if (Common::ParseParaOnlyCallback(env, info, callback) == nullptr) {
81 ANS_LOGD("ParseParaOnlyCallback is nullptr.");
82 Common::NapiThrow(env, ERROR_PARAM_INVALID);
83 return Common::NapiGetUndefined(env);
84 }
85
86 auto asynccallbackinfo = new (std::nothrow) AsyncCallbackInfoActive {.env = env, .asyncWork = nullptr};
87 if (!asynccallbackinfo) {
88 ANS_LOGD("Asynccallbackinfo is nullptr.");
89 Common::NapiThrow(env, ERROR_INTERNAL_ERROR);
90 return Common::JSParaError(env, callback);
91 }
92 napi_value promise = nullptr;
93 Common::PaddingCallbackPromiseInfo(env, callback, asynccallbackinfo->info, promise);
94
95 napi_value resourceName = nullptr;
96 napi_create_string_latin1(env, "getAllActiveNotifications", NAPI_AUTO_LENGTH, &resourceName);
97 // Asynchronous function call
98 napi_create_async_work(
99 env,
100 nullptr,
101 resourceName,
102 [](napi_env env, void *data) {
103 ANS_LOGD("NapiGetAllActiveNotifications work excute.");
104 auto asynccallbackinfo = static_cast<AsyncCallbackInfoActive *>(data);
105 if (asynccallbackinfo) {
106 asynccallbackinfo->info.errorCode =
107 NotificationHelper::GetAllActiveNotifications(asynccallbackinfo->notifications);
108 }
109 },
110 AsyncCompleteCallbackNapiGetAllActiveNotifications,
111 (void *)asynccallbackinfo,
112 &asynccallbackinfo->asyncWork);
113
114 bool isCallback = asynccallbackinfo->info.isCallback;
115 napi_queue_async_work_with_qos(env, asynccallbackinfo->asyncWork, napi_qos_user_initiated);
116
117 if (isCallback) {
118 ANS_LOGD("napiGetAllActiveNotifications callback is nullptr.");
119 return Common::NapiGetNull(env);
120 } else {
121 return promise;
122 }
123 }
124
AsyncCompleteCallbackNapiGetActiveNotifications(napi_env env,napi_status status,void * data)125 void AsyncCompleteCallbackNapiGetActiveNotifications(napi_env env, napi_status status, void *data)
126 {
127 ANS_LOGI("callback");
128 if (!data) {
129 ANS_LOGE("Ineffective async callback data.");
130 return;
131 }
132
133 auto asynccallbackinfo = static_cast<AsyncCallbackInfoActive *>(data);
134 if (asynccallbackinfo) {
135 napi_value result = nullptr;
136 if (asynccallbackinfo->info.errorCode != ERR_OK) {
137 result = Common::NapiGetNull(env);
138 } else {
139 napi_value arr = nullptr;
140 int32_t count = 0;
141 napi_create_array(env, &arr);
142 for (auto vec : asynccallbackinfo->requests) {
143 if (!vec) {
144 ANS_LOGW("Invalid NotificationRequest object ptr");
145 continue;
146 }
147 napi_value requestResult = nullptr;
148 napi_create_object(env, &requestResult);
149 if (!Common::SetNotificationRequest(env, vec.GetRefPtr(), requestResult)) {
150 ANS_LOGW("Set NotificationRequest object failed");
151 continue;
152 }
153 napi_set_element(env, arr, count, requestResult);
154 count++;
155 }
156 ANS_LOGI("GetActiveNotifications count = %{public}d", count);
157 result = arr;
158 if ((count == 0) && (asynccallbackinfo->requests.size() > 0)) {
159 asynccallbackinfo->info.errorCode = ERROR;
160 result = Common::NapiGetNull(env);
161 }
162 }
163 Common::CreateReturnValue(env, asynccallbackinfo->info, result);
164 if (asynccallbackinfo->info.callback != nullptr) {
165 ANS_LOGD("Delete napiGetActiveNotifications callback reference.");
166 napi_delete_reference(env, asynccallbackinfo->info.callback);
167 }
168 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
169 delete asynccallbackinfo;
170 asynccallbackinfo = nullptr;
171 }
172 }
173
NapiGetActiveNotifications(napi_env env,napi_callback_info info)174 napi_value NapiGetActiveNotifications(napi_env env, napi_callback_info info)
175 {
176 ANS_LOGD("enter");
177 napi_ref callback = nullptr;
178 if (Common::ParseParaOnlyCallback(env, info, callback) == nullptr) {
179 ANS_LOGD("Callback is nullptr.");
180 Common::NapiThrow(env, ERROR_PARAM_INVALID);
181 return Common::NapiGetUndefined(env);
182 }
183
184 auto asynccallbackinfo = new (std::nothrow) AsyncCallbackInfoActive {.env = env, .asyncWork = nullptr};
185 if (!asynccallbackinfo) {
186 ANS_LOGD("Create asynccallbackinfo failed.");
187 Common::NapiThrow(env, ERROR_INTERNAL_ERROR);
188 return Common::JSParaError(env, callback);
189 }
190 napi_value promise = nullptr;
191 Common::PaddingCallbackPromiseInfo(env, callback, asynccallbackinfo->info, promise);
192
193 napi_value resourceName = nullptr;
194 napi_create_string_latin1(env, "getActiveNotifications", NAPI_AUTO_LENGTH, &resourceName);
195 // Asynchronous function call
196 napi_create_async_work(
197 env,
198 nullptr,
199 resourceName,
200 [](napi_env env, void *data) {
201 ANS_LOGD("NapiGetActiveNotifications work excute.");
202 auto asynccallbackinfo = static_cast<AsyncCallbackInfoActive *>(data);
203 if (asynccallbackinfo) {
204 asynccallbackinfo->info.errorCode =
205 NotificationHelper::GetActiveNotifications(asynccallbackinfo->requests);
206 }
207 },
208 AsyncCompleteCallbackNapiGetActiveNotifications,
209 (void *)asynccallbackinfo,
210 &asynccallbackinfo->asyncWork);
211
212 bool isCallback = asynccallbackinfo->info.isCallback;
213 napi_queue_async_work_with_qos(env, asynccallbackinfo->asyncWork, napi_qos_user_initiated);
214
215 if (isCallback) {
216 ANS_LOGD("napiGetActiveNotifications callback is nullptr.");
217 return Common::NapiGetNull(env);
218 } else {
219 return promise;
220 }
221 }
222
AsyncCompleteCallbackNapiGetActiveNotificationCount(napi_env env,napi_status status,void * data)223 void AsyncCompleteCallbackNapiGetActiveNotificationCount(napi_env env, napi_status status, void *data)
224 {
225 ANS_LOGI("callback");
226 if (!data) {
227 ANS_LOGE("Async callback ineffective data.");
228 return;
229 }
230
231 auto asynccallbackinfo = static_cast<AsyncCallbackInfoActive *>(data);
232 if (asynccallbackinfo) {
233 napi_value result = nullptr;
234 if (asynccallbackinfo->info.errorCode != ERR_OK) {
235 result = Common::NapiGetNull(env);
236 } else {
237 napi_create_uint32(env, asynccallbackinfo->num, &result);
238 }
239 Common::CreateReturnValue(env, asynccallbackinfo->info, result);
240 if (asynccallbackinfo->info.callback != nullptr) {
241 ANS_LOGD("Delete napiGetActiveNotificationCount callback reference.");
242 napi_delete_reference(env, asynccallbackinfo->info.callback);
243 }
244 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
245 delete asynccallbackinfo;
246 asynccallbackinfo = nullptr;
247 }
248 }
249
NapiGetActiveNotificationCount(napi_env env,napi_callback_info info)250 napi_value NapiGetActiveNotificationCount(napi_env env, napi_callback_info info)
251 {
252 ANS_LOGD("enter");
253 napi_ref callback = nullptr;
254 if (Common::ParseParaOnlyCallback(env, info, callback) == nullptr) {
255 Common::NapiThrow(env, ERROR_PARAM_INVALID);
256 return Common::NapiGetUndefined(env);
257 }
258
259 auto asynccallbackinfo = new (std::nothrow) AsyncCallbackInfoActive {.env = env, .asyncWork = nullptr};
260 if (!asynccallbackinfo) {
261 return Common::JSParaError(env, callback);
262 }
263 napi_value promise = nullptr;
264 Common::PaddingCallbackPromiseInfo(env, callback, asynccallbackinfo->info, promise);
265
266 napi_value resourceName = nullptr;
267 napi_create_string_latin1(env, "getActiveNotificationCount", NAPI_AUTO_LENGTH, &resourceName);
268 // Asynchronous function call
269 napi_create_async_work(
270 env,
271 nullptr,
272 resourceName,
273 [](napi_env env, void *data) {
274 ANS_LOGD("NapiGetActiveNotificationCount work excute.");
275 auto asynccallbackinfo = static_cast<AsyncCallbackInfoActive *>(data);
276 if (asynccallbackinfo) {
277 asynccallbackinfo->info.errorCode =
278 NotificationHelper::GetActiveNotificationNums(asynccallbackinfo->num);
279 ANS_LOGI("count = %{public}" PRIu64 "", asynccallbackinfo->num);
280 }
281 },
282 AsyncCompleteCallbackNapiGetActiveNotificationCount,
283 (void *)asynccallbackinfo,
284 &asynccallbackinfo->asyncWork);
285
286 bool isCallback = asynccallbackinfo->info.isCallback;
287 napi_queue_async_work_with_qos(env, asynccallbackinfo->asyncWork, napi_qos_user_initiated);
288
289 if (isCallback) {
290 ANS_LOGD("napiGetActiveNotificationCount callback is nullptr.");
291 return Common::NapiGetNull(env);
292 } else {
293 return promise;
294 }
295 }
296
ParseGetLiveViewFilter(const napi_env & env,const napi_value & obj,LiveViewFilter & filter)297 napi_value ParseGetLiveViewFilter(const napi_env &env, const napi_value &obj, LiveViewFilter &filter)
298 {
299 // bundle
300 napi_value result = AppExecFwk::GetPropertyValueByPropertyName(env, obj, "bundle", napi_object);
301 if (result == nullptr) {
302 ANS_LOGW("Failed to get bundle from params.");
303 return nullptr;
304 }
305 auto retValue = Common::GetBundleOption(env, result, filter.bundle);
306 if (retValue == nullptr) {
307 ANS_LOGE("GetBundleOption failed");
308 return nullptr;
309 }
310
311 // notificationKey
312 result = AppExecFwk::GetPropertyValueByPropertyName(env, obj, "notificationKey", napi_object);
313 if (result == nullptr) {
314 ANS_LOGW("Failed to get notificationKeys from params.");
315 return nullptr;
316 }
317 retValue = Common::GetNotificationKey(env, result, filter.notificationKey);
318 if (retValue == nullptr) {
319 ANS_LOGE("GetNotificationKey failed");
320 return nullptr;
321 }
322
323 // extraInfoKeys
324 if (AppExecFwk::IsExistsByPropertyName(env, obj, "extraInfoKeys") == false) {
325 ANS_LOGI("No extraInfoKeys in filter");
326 return Common::NapiGetNull(env);
327 }
328
329 if (!AppExecFwk::UnwrapStringArrayByPropertyName(env, obj, "extraInfoKeys", filter.extraInfoKeys)) {
330 ANS_LOGE("GetExtraInfoKeys failed.");
331 return nullptr;
332 }
333
334 return Common::NapiGetNull(env);
335 }
336
ParseGetLiveViewParams(const napi_env & env,const napi_callback_info & info,LiveViewFilter & filter,napi_ref & callback)337 napi_value ParseGetLiveViewParams(const napi_env &env, const napi_callback_info &info,
338 LiveViewFilter &filter, napi_ref &callback)
339 {
340 ANS_LOGD("enter");
341
342 size_t argc = ARGS_TWO;
343 napi_value argv[ARGS_TWO] = {nullptr};
344 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
345 if (argc < ARGS_ONE) {
346 ANS_LOGE("Wrong number of arguments");
347 Common::NapiThrow(env, ERROR_PARAM_INVALID, MANDATORY_PARAMETER_ARE_LEFT_UNSPECIFIED);
348 return nullptr;
349 }
350
351 // argv[0] : filter
352 if (!AppExecFwk::IsTypeForNapiValue(env, argv[0], napi_object)) {
353 ANS_LOGE("Wrong filter type. Object expected.");
354 std::string msg = "Incorrect parameter types.The type of param must be object.";
355 Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
356 return nullptr;
357 }
358 if (ParseGetLiveViewFilter(env, argv[0], filter) == nullptr) {
359 ANS_LOGE("Parse filter from param failed.");
360 Common::NapiThrow(env, ERROR_PARAM_INVALID, PARAMETER_VERIFICATION_FAILED);
361 return nullptr;
362 }
363
364 // argv[1] : callback
365 if (argc > ARGS_ONE) {
366 if (!AppExecFwk::IsTypeForNapiValue(env, argv[1], napi_function)) {
367 ANS_LOGE("Callback is not function excute promise.");
368 return Common::NapiGetNull(env);
369 }
370 napi_create_reference(env, argv[1], 1, &callback);
371 }
372
373 ANS_LOGD("end");
374 return Common::NapiGetNull(env);
375 }
376
AsyncGetLiveViewExecute(napi_env env,void * data)377 void AsyncGetLiveViewExecute(napi_env env, void *data)
378 {
379 ANS_LOGD("NapiGetActiveNotificationByFilter work excute.");
380
381 auto asyncLiveViewCallBackInfo = static_cast<AsyncLiveViewCallBackInfo *>(data);
382 if (asyncLiveViewCallBackInfo) {
383 asyncLiveViewCallBackInfo->info.errorCode = NotificationHelper::GetActiveNotificationByFilter(
384 asyncLiveViewCallBackInfo->filter, asyncLiveViewCallBackInfo->notificationRequest);
385 }
386 }
387
AsyncGetLiveViewComplete(napi_env env,napi_status status,void * data)388 void AsyncGetLiveViewComplete(napi_env env, napi_status status, void *data)
389 {
390 ANS_LOGD("enter");
391
392 auto asyncCallbackinfo = static_cast<AsyncLiveViewCallBackInfo *>(data);
393 if (asyncCallbackinfo == nullptr) {
394 ANS_LOGE("Invalid async live view callback data.");
395 return;
396 }
397
398 ANS_LOGD("Conversion data is success.");
399 napi_value result = nullptr;
400 if (asyncCallbackinfo->info.errorCode != ERR_OK) {
401 result = Common::NapiGetNull(env);
402 } else {
403 if (asyncCallbackinfo->notificationRequest == nullptr) {
404 result = Common::NapiGetNull(env);
405 } else {
406 napi_create_object(env, &result);
407 if (!Common::SetNotificationRequest(env, asyncCallbackinfo->notificationRequest, result)) {
408 result = Common::NapiGetNull(env);
409 }
410 }
411 }
412
413 Common::CreateReturnValue(env, asyncCallbackinfo->info, result);
414 if (asyncCallbackinfo->info.callback != nullptr) {
415 ANS_LOGD("Delete NapiGetActiveNotificationByFilter callback reference.");
416 napi_delete_reference(env, asyncCallbackinfo->info.callback);
417 }
418 napi_delete_async_work(env, asyncCallbackinfo->asyncWork);
419 delete asyncCallbackinfo;
420 asyncCallbackinfo = nullptr;
421 }
422
NapiGetActiveNotificationByFilter(napi_env env,napi_callback_info info)423 napi_value NapiGetActiveNotificationByFilter(napi_env env, napi_callback_info info)
424 {
425 ANS_LOGD("enter");
426
427 auto asyncLiveViewCallBackInfo = new (std::nothrow) AsyncLiveViewCallBackInfo {.env = env, .asyncWork = nullptr};
428 napi_ref callback = nullptr;
429 if (ParseGetLiveViewParams(env, info, asyncLiveViewCallBackInfo->filter, callback) == nullptr) {
430 ANS_LOGD("ParseGetLiveViewParams is nullptr.");
431 Common::NapiThrow(env, ERROR_PARAM_INVALID);
432 return Common::NapiGetUndefined(env);
433 }
434 napi_value promise = nullptr;
435 Common::PaddingCallbackPromiseInfo(env, callback, asyncLiveViewCallBackInfo->info, promise);
436
437 napi_value resourceName = nullptr;
438 napi_create_string_latin1(env, "getActiveNotificationByFilter", NAPI_AUTO_LENGTH, &resourceName);
439 napi_create_async_work(env, nullptr, resourceName,
440 AsyncGetLiveViewExecute, AsyncGetLiveViewComplete,
441 (void *)asyncLiveViewCallBackInfo, &asyncLiveViewCallBackInfo->asyncWork);
442
443 bool isCallback = asyncLiveViewCallBackInfo->info.isCallback;
444 napi_queue_async_work_with_qos(env, asyncLiveViewCallBackInfo->asyncWork, napi_qos_user_initiated);
445
446 if (isCallback) {
447 ANS_LOGD("NapiGetActiveNotificationByFilter callback is nullptr.");
448 return Common::NapiGetNull(env);
449 }
450
451 return promise;
452 }
453 } // namespace NotificationNapi
454 } // namespace OHOS
455