1 /*
2 * Copyright (c) 2021-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 "unsubscribe.h"
17
18 #include "ans_inner_errors.h"
19
20 namespace OHOS {
21 namespace NotificationNapi {
22 const int UNSUBSCRIBE_MAX_PARA = 2;
23
ParseParameters(const napi_env & env,const napi_callback_info & info,ParametersInfoUnsubscribe & paras)24 napi_value ParseParameters(const napi_env &env, const napi_callback_info &info, ParametersInfoUnsubscribe ¶s)
25 {
26 ANS_LOGD("enter");
27
28 size_t argc = UNSUBSCRIBE_MAX_PARA;
29 napi_value argv[UNSUBSCRIBE_MAX_PARA] = {nullptr};
30 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
31 if (argc < 1) {
32 ANS_LOGE("Wrong number of arguments");
33 Common::NapiThrow(env, ERROR_PARAM_INVALID, MANDATORY_PARAMETER_ARE_LEFT_UNSPECIFIED);
34 return nullptr;
35 }
36
37 napi_valuetype valuetype = napi_undefined;
38 // argv[0]:subscriber
39 NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &valuetype));
40 if (valuetype != napi_object) {
41 ANS_LOGE("Wrong argument type. Object expected.");
42 std::string msg = "Incorrect parameter types.The type of param must be object.";
43 Common::NapiThrow(env, ERROR_PARAM_INVALID, msg);
44 return nullptr;
45 }
46
47 SubscriberInstancesInfo subscriberInstancesInfo;
48 if (!HasNotificationSubscriber(env, argv[PARAM0], subscriberInstancesInfo)) {
49 ANS_LOGW("Subscriber not found");
50 }
51 paras.objectInfo = subscriberInstancesInfo.subscriber;
52
53 // argv[1]:callback
54 if (argc >= UNSUBSCRIBE_MAX_PARA) {
55 NAPI_CALL(env, napi_typeof(env, argv[PARAM1], &valuetype));
56 if (valuetype != napi_function) {
57 ANS_LOGE("Callback is not function excute promise.");
58 return Common::NapiGetNull(env);
59 }
60 napi_create_reference(env, argv[PARAM1], 1, ¶s.callback);
61 }
62
63 return Common::NapiGetNull(env);
64 }
65
Unsubscribe(napi_env env,napi_callback_info info)66 napi_value Unsubscribe(napi_env env, napi_callback_info info)
67 {
68 ANS_LOGI("Unsubscribe start");
69
70 ParametersInfoUnsubscribe paras;
71 if (ParseParameters(env, info, paras) == nullptr) {
72 return Common::NapiGetUndefined(env);
73 }
74
75 AsyncCallbackInfoUnsubscribe *asynccallbackinfo = new (std::nothrow)
76 AsyncCallbackInfoUnsubscribe {.env = env, .asyncWork = nullptr, .objectInfo = paras.objectInfo};
77 if (!asynccallbackinfo) {
78 ANS_LOGD("Asynccallbackinfo is nullptr.");
79 return Common::JSParaError(env, paras.callback);
80 }
81 napi_value promise = nullptr;
82 Common::PaddingCallbackPromiseInfo(env, paras.callback, asynccallbackinfo->info, promise);
83
84 ANS_LOGD("Create unsubscribe string.");
85 napi_value resourceName = nullptr;
86 napi_create_string_latin1(env, "unsubscribe", NAPI_AUTO_LENGTH, &resourceName);
87
88 // Asynchronous function call
89 napi_create_async_work(env,
90 nullptr,
91 resourceName,
92 [](napi_env env, void *data) {
93 ANS_LOGD("Unsubscribe work excute.");
94 auto asynccallbackinfo = reinterpret_cast<AsyncCallbackInfoUnsubscribe *>(data);
95
96 if (asynccallbackinfo->objectInfo == nullptr) {
97 ANS_LOGE("invalidated object info");
98 asynccallbackinfo->info.errorCode = ERR_ANS_INVALID_PARAM;
99 return;
100 }
101
102 bool ret = AddDeletingSubscriber(asynccallbackinfo->objectInfo);
103 if (ret) {
104 asynccallbackinfo->info.errorCode =
105 NotificationHelper::UnSubscribeNotification(*(asynccallbackinfo->objectInfo));
106 if (asynccallbackinfo->info.errorCode != ERR_OK) {
107 ANS_LOGD("errorCode is not ERR_OK.");
108 DelDeletingSubscriber(asynccallbackinfo->objectInfo);
109 }
110 } else {
111 asynccallbackinfo->info.errorCode = ERR_ANS_SUBSCRIBER_IS_DELETING;
112 }
113 },
114 [](napi_env env, napi_status status, void *data) {
115 ANS_LOGD("Unsubscribe work complete.");
116 AsyncCallbackInfoUnsubscribe *asynccallbackinfo = static_cast<AsyncCallbackInfoUnsubscribe *>(data);
117 if (asynccallbackinfo) {
118 Common::ReturnCallbackPromise(env, asynccallbackinfo->info, Common::NapiGetNull(env));
119 if (asynccallbackinfo->info.callback != nullptr) {
120 ANS_LOGD("Delete unsubscribe callback reference.");
121 napi_delete_reference(env, asynccallbackinfo->info.callback);
122 }
123 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
124 delete asynccallbackinfo;
125 asynccallbackinfo = nullptr;
126 }
127 ANS_LOGD("Unsubscribe work complete end.");
128 },
129 (void *)asynccallbackinfo,
130 &asynccallbackinfo->asyncWork);
131
132 napi_queue_async_work_with_qos(env, asynccallbackinfo->asyncWork, napi_qos_user_initiated);
133
134 if (asynccallbackinfo->info.isCallback) {
135 ANS_LOGD("Unsubscribe callback is nullptr.");
136 return Common::NapiGetNull(env);
137 } else {
138 return promise;
139 }
140 }
141 } // namespace NotificationNapi
142 } // namespace OHOS
143