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("called");
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("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("called");
79 napi_ref callback = nullptr;
80 if (Common::ParseParaOnlyCallback(env, info, callback) == nullptr) {
81 ANS_LOGD("null ParseParaOnlyCallback");
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("null asynccallbackinfo");
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("null isCallback");
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_LOGD("called");
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("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("called");
177 napi_ref callback = nullptr;
178 if (Common::ParseParaOnlyCallback(env, info, callback) == nullptr) {
179 ANS_LOGD("null ParseParaOnlyCallback");
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 std::string instanceKey = Common::GetAppInstanceKey();
205 asynccallbackinfo->info.errorCode =
206 NotificationHelper::GetActiveNotifications(
207 asynccallbackinfo->requests, instanceKey);
208 }
209 },
210 AsyncCompleteCallbackNapiGetActiveNotifications,
211 (void *)asynccallbackinfo,
212 &asynccallbackinfo->asyncWork);
213
214 bool isCallback = asynccallbackinfo->info.isCallback;
215 napi_queue_async_work_with_qos(env, asynccallbackinfo->asyncWork, napi_qos_user_initiated);
216
217 if (isCallback) {
218 ANS_LOGD("null isCallback");
219 return Common::NapiGetNull(env);
220 } else {
221 return promise;
222 }
223 }
224
AsyncCompleteCallbackNapiGetActiveNotificationCount(napi_env env,napi_status status,void * data)225 void AsyncCompleteCallbackNapiGetActiveNotificationCount(napi_env env, napi_status status, void *data)
226 {
227 ANS_LOGD("called");
228 if (!data) {
229 ANS_LOGE("Async callback ineffective data.");
230 return;
231 }
232
233 auto asynccallbackinfo = static_cast<AsyncCallbackInfoActive *>(data);
234 if (asynccallbackinfo) {
235 napi_value result = nullptr;
236 if (asynccallbackinfo->info.errorCode != ERR_OK) {
237 result = Common::NapiGetNull(env);
238 } else {
239 napi_create_uint32(env, asynccallbackinfo->num, &result);
240 }
241 Common::CreateReturnValue(env, asynccallbackinfo->info, result);
242 if (asynccallbackinfo->info.callback != nullptr) {
243 ANS_LOGD("Delete napiGetActiveNotificationCount callback reference.");
244 napi_delete_reference(env, asynccallbackinfo->info.callback);
245 }
246 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
247 delete asynccallbackinfo;
248 asynccallbackinfo = nullptr;
249 }
250 }
251
NapiGetActiveNotificationCount(napi_env env,napi_callback_info info)252 napi_value NapiGetActiveNotificationCount(napi_env env, napi_callback_info info)
253 {
254 ANS_LOGD("called");
255 napi_ref callback = nullptr;
256 if (Common::ParseParaOnlyCallback(env, info, callback) == nullptr) {
257 Common::NapiThrow(env, ERROR_PARAM_INVALID);
258 return Common::NapiGetUndefined(env);
259 }
260
261 auto asynccallbackinfo = new (std::nothrow) AsyncCallbackInfoActive {.env = env, .asyncWork = nullptr};
262 if (!asynccallbackinfo) {
263 return Common::JSParaError(env, callback);
264 }
265 napi_value promise = nullptr;
266 Common::PaddingCallbackPromiseInfo(env, callback, asynccallbackinfo->info, promise);
267
268 napi_value resourceName = nullptr;
269 napi_create_string_latin1(env, "getActiveNotificationCount", NAPI_AUTO_LENGTH, &resourceName);
270 // Asynchronous function call
271 napi_create_async_work(
272 env,
273 nullptr,
274 resourceName,
275 [](napi_env env, void *data) {
276 ANS_LOGD("NapiGetActiveNotificationCount work excute.");
277 auto asynccallbackinfo = static_cast<AsyncCallbackInfoActive *>(data);
278 if (asynccallbackinfo) {
279 asynccallbackinfo->info.errorCode =
280 NotificationHelper::GetActiveNotificationNums(asynccallbackinfo->num);
281 ANS_LOGI("count=%{public}" PRIu64 "", asynccallbackinfo->num);
282 }
283 },
284 AsyncCompleteCallbackNapiGetActiveNotificationCount,
285 (void *)asynccallbackinfo,
286 &asynccallbackinfo->asyncWork);
287
288 bool isCallback = asynccallbackinfo->info.isCallback;
289 napi_queue_async_work_with_qos(env, asynccallbackinfo->asyncWork, napi_qos_user_initiated);
290
291 if (isCallback) {
292 ANS_LOGD("null isCallback");
293 return Common::NapiGetNull(env);
294 } else {
295 return promise;
296 }
297 }
298
ParseGetLiveViewFilter(const napi_env & env,const napi_value & obj,LiveViewFilter & filter)299 napi_value ParseGetLiveViewFilter(const napi_env &env, const napi_value &obj, LiveViewFilter &filter)
300 {
301 // bundle
302 napi_value result = AppExecFwk::GetPropertyValueByPropertyName(env, obj, "bundle", napi_object);
303 if (result == nullptr) {
304 ANS_LOGE("null result");
305 return nullptr;
306 }
307 auto retValue = Common::GetBundleOption(env, result, filter.bundle);
308 if (retValue == nullptr) {
309 ANS_LOGE("null retValue");
310 return nullptr;
311 }
312
313 // notificationKey
314 result = AppExecFwk::GetPropertyValueByPropertyName(env, obj, "notificationKey", napi_object);
315 if (result == nullptr) {
316 ANS_LOGE("null result");
317 return nullptr;
318 }
319 retValue = Common::GetNotificationKey(env, result, filter.notificationKey);
320 if (retValue == nullptr) {
321 ANS_LOGE("null retValue");
322 return nullptr;
323 }
324
325 // extraInfoKeys
326 if (AppExecFwk::IsExistsByPropertyName(env, obj, "extraInfoKeys") == false) {
327 ANS_LOGW("No extraInfoKeys in filter");
328 return Common::NapiGetNull(env);
329 }
330
331 if (!AppExecFwk::UnwrapStringArrayByPropertyName(env, obj, "extraInfoKeys", filter.extraInfoKeys)) {
332 ANS_LOGE("GetExtraInfoKeys failed.");
333 return nullptr;
334 }
335
336 return Common::NapiGetNull(env);
337 }
338
ParseGetLiveViewParams(const napi_env & env,const napi_callback_info & info,LiveViewFilter & filter,napi_ref & callback)339 napi_value ParseGetLiveViewParams(const napi_env &env, const napi_callback_info &info,
340 LiveViewFilter &filter, napi_ref &callback)
341 {
342 ANS_LOGD("start");
343
344 size_t argc = ARGS_TWO;
345 napi_value argv[ARGS_TWO] = {nullptr};
346 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
347 if (argc < ARGS_ONE) {
348 ANS_LOGE("Wrong number of arguments");
349 Common::NapiThrow(env, ERROR_PARAM_INVALID, MANDATORY_PARAMETER_ARE_LEFT_UNSPECIFIED);
350 return nullptr;
351 }
352
353 // argv[0] : filter
354 if (!AppExecFwk::IsTypeForNapiValue(env, argv[0], napi_object)) {
355 ANS_LOGE("Wrong filter type. Object expected.");
356 std::string msg = "Incorrect parameter types.The type of param must be object.";
357 Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
358 return nullptr;
359 }
360 if (ParseGetLiveViewFilter(env, argv[0], filter) == nullptr) {
361 ANS_LOGE("Parse filter from param failed.");
362 Common::NapiThrow(env, ERROR_PARAM_INVALID, PARAMETER_VERIFICATION_FAILED);
363 return nullptr;
364 }
365
366 // argv[1] : callback
367 if (argc > ARGS_ONE) {
368 if (!AppExecFwk::IsTypeForNapiValue(env, argv[1], napi_function)) {
369 ANS_LOGE("Callback is not function excute promise.");
370 return Common::NapiGetNull(env);
371 }
372 napi_create_reference(env, argv[1], 1, &callback);
373 }
374
375 ANS_LOGD("end");
376 return Common::NapiGetNull(env);
377 }
378
AsyncGetLiveViewExecute(napi_env env,void * data)379 void AsyncGetLiveViewExecute(napi_env env, void *data)
380 {
381 ANS_LOGD("called");
382
383 auto asyncLiveViewCallBackInfo = static_cast<AsyncLiveViewCallBackInfo *>(data);
384 if (asyncLiveViewCallBackInfo) {
385 asyncLiveViewCallBackInfo->info.errorCode = NotificationHelper::GetActiveNotificationByFilter(
386 asyncLiveViewCallBackInfo->filter, asyncLiveViewCallBackInfo->notificationRequest);
387 }
388 }
389
AsyncGetLiveViewComplete(napi_env env,napi_status status,void * data)390 void AsyncGetLiveViewComplete(napi_env env, napi_status status, void *data)
391 {
392 ANS_LOGD("called");
393
394 auto asyncCallbackinfo = static_cast<AsyncLiveViewCallBackInfo *>(data);
395 if (asyncCallbackinfo == nullptr) {
396 ANS_LOGE("null asyncCallbackinfo");
397 return;
398 }
399
400 ANS_LOGD("Conversion data is success.");
401 napi_value result = nullptr;
402 if (asyncCallbackinfo->info.errorCode != ERR_OK) {
403 result = Common::NapiGetNull(env);
404 } else {
405 if (asyncCallbackinfo->notificationRequest == nullptr) {
406 result = Common::NapiGetNull(env);
407 } else {
408 napi_create_object(env, &result);
409 if (!Common::SetNotificationRequest(env, asyncCallbackinfo->notificationRequest, result)) {
410 result = Common::NapiGetNull(env);
411 }
412 }
413 }
414
415 Common::CreateReturnValue(env, asyncCallbackinfo->info, result);
416 if (asyncCallbackinfo->info.callback != nullptr) {
417 ANS_LOGD("Delete NapiGetActiveNotificationByFilter callback reference.");
418 napi_delete_reference(env, asyncCallbackinfo->info.callback);
419 }
420 napi_delete_async_work(env, asyncCallbackinfo->asyncWork);
421 delete asyncCallbackinfo;
422 asyncCallbackinfo = nullptr;
423 }
424
NapiGetActiveNotificationByFilter(napi_env env,napi_callback_info info)425 napi_value NapiGetActiveNotificationByFilter(napi_env env, napi_callback_info info)
426 {
427 ANS_LOGD("called");
428
429 auto asyncLiveViewCallBackInfo = new (std::nothrow) AsyncLiveViewCallBackInfo {.env = env, .asyncWork = nullptr};
430 if (asyncLiveViewCallBackInfo == nullptr) {
431 ANS_LOGE("null asyncLiveViewCallBackInfo");
432 Common::NapiThrow(env, ERROR_PARAM_INVALID);
433 return Common::NapiGetUndefined(env);
434 }
435 napi_ref callback = nullptr;
436 if (ParseGetLiveViewParams(env, info, asyncLiveViewCallBackInfo->filter, callback) == nullptr) {
437 ANS_LOGE("null ParseGetLiveViewParams");
438 delete asyncLiveViewCallBackInfo;
439 asyncLiveViewCallBackInfo = nullptr;
440 Common::NapiThrow(env, ERROR_PARAM_INVALID);
441 return Common::NapiGetUndefined(env);
442 }
443 napi_value promise = nullptr;
444 Common::PaddingCallbackPromiseInfo(env, callback, asyncLiveViewCallBackInfo->info, promise);
445
446 napi_value resourceName = nullptr;
447 napi_create_string_latin1(env, "getActiveNotificationByFilter", NAPI_AUTO_LENGTH, &resourceName);
448 napi_create_async_work(env, nullptr, resourceName,
449 AsyncGetLiveViewExecute, AsyncGetLiveViewComplete,
450 (void *)asyncLiveViewCallBackInfo, &asyncLiveViewCallBackInfo->asyncWork);
451
452 bool isCallback = asyncLiveViewCallBackInfo->info.isCallback;
453 napi_queue_async_work_with_qos(env, asyncLiveViewCallBackInfo->asyncWork, napi_qos_user_initiated);
454
455 if (isCallback) {
456 ANS_LOGD("null isCallback");
457 return Common::NapiGetNull(env);
458 }
459
460 return promise;
461 }
462 } // namespace NotificationNapi
463 } // namespace OHOS
464