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_subscribe.h"
17
18 #include "ans_inner_errors.h"
19 #include "subscribe.h"
20 #include "unsubscribe.h"
21
22 namespace OHOS {
23 namespace NotificationNapi {
NapiSubscribe(napi_env env,napi_callback_info info)24 napi_value NapiSubscribe(napi_env env, napi_callback_info info)
25 {
26 ANS_LOGD("enter");
27 napi_ref callback = nullptr;
28 std::shared_ptr<SubscriberInstance> objectInfo = nullptr;
29 NotificationSubscribeInfo subscriberInfo;
30 if (ParseParameters(env, info, subscriberInfo, objectInfo, callback) == nullptr) {
31 Common::NapiThrow(env, ERROR_PARAM_INVALID);
32 return Common::NapiGetUndefined(env);
33 }
34
35 AsyncCallbackInfoSubscribe *asynccallbackinfo = new (std::nothrow) AsyncCallbackInfoSubscribe {
36 .env = env, .asyncWork = nullptr, .objectInfo = objectInfo, .subscriberInfo = subscriberInfo
37 };
38 if (!asynccallbackinfo) {
39 Common::NapiThrow(env, ERROR_INTERNAL_ERROR);
40 return Common::JSParaError(env, callback);
41 }
42 napi_value promise = nullptr;
43 Common::PaddingCallbackPromiseInfo(env, callback, asynccallbackinfo->info, promise);
44
45 napi_value resourceName = nullptr;
46 napi_create_string_latin1(env, "subscribeNotification", NAPI_AUTO_LENGTH, &resourceName);
47 // Asynchronous function call
48 napi_create_async_work(env,
49 nullptr,
50 resourceName,
51 [](napi_env env, void *data) {
52 ANS_LOGD("NapiSubscribe work excute.");
53 if (!data) {
54 ANS_LOGE("Invalid asynccallbackinfo!");
55 return;
56 }
57 auto asynccallbackinfo = reinterpret_cast<AsyncCallbackInfoSubscribe *>(data);
58 if (asynccallbackinfo) {
59 if (asynccallbackinfo->subscriberInfo.hasSubscribeInfo) {
60 ANS_LOGI("Subscribe with NotificationSubscribeInfo");
61 OHOS::Notification::NotificationSubscribeInfo subscribeInfo;
62 subscribeInfo.AddAppNames(asynccallbackinfo->subscriberInfo.bundleNames);
63 subscribeInfo.AddAppUserId(asynccallbackinfo->subscriberInfo.userId);
64 subscribeInfo.AddDeviceType(asynccallbackinfo->subscriberInfo.deviceType);
65 asynccallbackinfo->info.errorCode =
66 NotificationHelper::SubscribeNotification(*(asynccallbackinfo->objectInfo), subscribeInfo);
67 } else {
68 asynccallbackinfo->info.errorCode =
69 NotificationHelper::SubscribeNotification(*(asynccallbackinfo->objectInfo));
70 }
71 if (asynccallbackinfo->info.errorCode == ERR_OK) {
72 DelDeletingSubscriber(asynccallbackinfo->objectInfo);
73 }
74 }
75 },
76 [](napi_env env, napi_status status, void *data) {
77 ANS_LOGD("NapiSubscribe work complete.");
78 if (!data) {
79 ANS_LOGE("Invalid asynccallbackinfo!");
80 return;
81 }
82 auto asynccallbackinfo = reinterpret_cast<AsyncCallbackInfoSubscribe *>(data);
83 if (asynccallbackinfo) {
84 Common::CreateReturnValue(env, asynccallbackinfo->info, Common::NapiGetNull(env));
85 if (asynccallbackinfo->info.callback != nullptr) {
86 ANS_LOGD("Delete napiSubscribe callback reference.");
87 napi_delete_reference(env, asynccallbackinfo->info.callback);
88 }
89 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
90 delete asynccallbackinfo;
91 asynccallbackinfo = nullptr;
92 }
93 ANS_LOGD("NapiSubscribe work complete end.");
94 },
95 (void *)asynccallbackinfo,
96 &asynccallbackinfo->asyncWork);
97
98 bool isCallback = asynccallbackinfo->info.isCallback;
99 napi_queue_async_work_with_qos(env, asynccallbackinfo->asyncWork, napi_qos_user_initiated);
100
101 if (isCallback) {
102 ANS_LOGD("napiSubscribe callback is nullptr.");
103 return Common::NapiGetNull(env);
104 } else {
105 return promise;
106 }
107 }
108
NapiSubscribeSelf(napi_env env,napi_callback_info info)109 napi_value NapiSubscribeSelf(napi_env env, napi_callback_info info)
110 {
111 ANS_LOGD("enter");
112 napi_ref callback = nullptr;
113 std::shared_ptr<SubscriberInstance> objectInfo = nullptr;
114 NotificationSubscribeInfo subscriberInfo;
115 if (ParseParameters(env, info, subscriberInfo, objectInfo, callback) == nullptr) {
116 Common::NapiThrow(env, ERROR_PARAM_INVALID);
117 return Common::NapiGetUndefined(env);
118 }
119
120 AsyncCallbackInfoSubscribe *asynccallbackinfo = new (std::nothrow) AsyncCallbackInfoSubscribe {
121 .env = env, .asyncWork = nullptr, .objectInfo = objectInfo, .subscriberInfo = subscriberInfo
122 };
123 if (!asynccallbackinfo) {
124 Common::NapiThrow(env, ERROR_INTERNAL_ERROR);
125 return Common::JSParaError(env, callback);
126 }
127 napi_value promise = nullptr;
128 Common::PaddingCallbackPromiseInfo(env, callback, asynccallbackinfo->info, promise);
129
130 napi_value resourceName = nullptr;
131 napi_create_string_latin1(env, "subscribeNotificationSelf", NAPI_AUTO_LENGTH, &resourceName);
132 // Asynchronous function call
133 napi_create_async_work(env,
134 nullptr,
135 resourceName,
136 [](napi_env env, void *data) {
137 ANS_LOGD("NapiSubscribeSelf work excute.");
138 if (!data) {
139 ANS_LOGE("Invalid asynccallbackinfo!");
140 return;
141 }
142 auto asynccallbackinfo = reinterpret_cast<AsyncCallbackInfoSubscribe *>(data);
143 if (asynccallbackinfo) {
144 asynccallbackinfo->info.errorCode =
145 NotificationHelper::SubscribeNotificationSelf(*(asynccallbackinfo->objectInfo));
146 if (asynccallbackinfo->info.errorCode == ERR_OK) {
147 DelDeletingSubscriber(asynccallbackinfo->objectInfo);
148 }
149 }
150 },
151 [](napi_env env, napi_status status, void *data) {
152 ANS_LOGD("NapiSubscribeSelf work complete.");
153 if (!data) {
154 ANS_LOGE("Invalid asynccallbackinfo!");
155 return;
156 }
157 auto asynccallbackinfo = reinterpret_cast<AsyncCallbackInfoSubscribe *>(data);
158 if (asynccallbackinfo) {
159 Common::CreateReturnValue(env, asynccallbackinfo->info, Common::NapiGetNull(env));
160 if (asynccallbackinfo->info.callback != nullptr) {
161 ANS_LOGD("Delete napiSubscribeSelf callback reference.");
162 napi_delete_reference(env, asynccallbackinfo->info.callback);
163 }
164 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
165 delete asynccallbackinfo;
166 asynccallbackinfo = nullptr;
167 }
168 ANS_LOGD("NapiSubscribeSelf work complete end.");
169 },
170 (void *)asynccallbackinfo,
171 &asynccallbackinfo->asyncWork);
172
173 bool isCallback = asynccallbackinfo->info.isCallback;
174 napi_queue_async_work_with_qos(env, asynccallbackinfo->asyncWork, napi_qos_user_initiated);
175
176 if (isCallback) {
177 ANS_LOGD("NapiSubscribeSelf callback is nullptr.");
178 return Common::NapiGetNull(env);
179 } else {
180 return promise;
181 }
182 }
183
NapiUnsubscribe(napi_env env,napi_callback_info info)184 napi_value NapiUnsubscribe(napi_env env, napi_callback_info info)
185 {
186 ANS_LOGI("Unsubscribe start");
187 ParametersInfoUnsubscribe paras;
188 if (ParseParameters(env, info, paras) == nullptr) {
189 Common::NapiThrow(env, ERROR_PARAM_INVALID);
190 return Common::NapiGetUndefined(env);
191 }
192
193 AsyncCallbackInfoUnsubscribe *asynccallbackinfo = new (std::nothrow)
194 AsyncCallbackInfoUnsubscribe {.env = env, .asyncWork = nullptr, .objectInfo = paras.objectInfo};
195 if (!asynccallbackinfo) {
196 Common::NapiThrow(env, ERROR_INTERNAL_ERROR);
197 return Common::JSParaError(env, paras.callback);
198 }
199 napi_value promise = nullptr;
200 Common::PaddingCallbackPromiseInfo(env, paras.callback, asynccallbackinfo->info, promise);
201
202 napi_value resourceName = nullptr;
203 napi_create_string_latin1(env, "unsubscribe", NAPI_AUTO_LENGTH, &resourceName);
204
205 // Asynchronous function call
206 napi_create_async_work(env,
207 nullptr,
208 resourceName,
209 [](napi_env env, void *data) {
210 ANS_LOGD("NapiUnsubscribe work excute.");
211 auto asynccallbackinfo = reinterpret_cast<AsyncCallbackInfoUnsubscribe *>(data);
212 if (asynccallbackinfo) {
213 if (asynccallbackinfo->objectInfo == nullptr) {
214 ANS_LOGE("invalid object info");
215 asynccallbackinfo->info.errorCode = ERR_ANS_INVALID_PARAM;
216 return;
217 }
218
219 bool ret = AddDeletingSubscriber(asynccallbackinfo->objectInfo);
220 if (ret) {
221 asynccallbackinfo->info.errorCode =
222 NotificationHelper::UnSubscribeNotification(*(asynccallbackinfo->objectInfo));
223 if (asynccallbackinfo->info.errorCode != ERR_OK) {
224 DelDeletingSubscriber(asynccallbackinfo->objectInfo);
225 }
226 } else {
227 asynccallbackinfo->info.errorCode = ERR_ANS_SUBSCRIBER_IS_DELETING;
228 }
229 }
230 },
231 [](napi_env env, napi_status status, void *data) {
232 ANS_LOGD("NapiUnsubscribe work complete.");
233 AsyncCallbackInfoUnsubscribe *asynccallbackinfo = static_cast<AsyncCallbackInfoUnsubscribe *>(data);
234 if (asynccallbackinfo) {
235 Common::CreateReturnValue(env, asynccallbackinfo->info, Common::NapiGetNull(env));
236 if (asynccallbackinfo->info.callback != nullptr) {
237 ANS_LOGD("Delete napiUnsubscribe callback reference.");
238 napi_delete_reference(env, asynccallbackinfo->info.callback);
239 }
240 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
241 delete asynccallbackinfo;
242 asynccallbackinfo = nullptr;
243 }
244 ANS_LOGD("NapiUnsubscribe work complete end.");
245 },
246 (void *)asynccallbackinfo,
247 &asynccallbackinfo->asyncWork);
248
249 bool isCallback = asynccallbackinfo->info.isCallback;
250 napi_queue_async_work_with_qos(env, asynccallbackinfo->asyncWork, napi_qos_user_initiated);
251
252 if (isCallback) {
253 ANS_LOGD("napiUnsubscribe callback is nullptr.");
254 return Common::NapiGetNull(env);
255 } else {
256 return promise;
257 }
258 }
259 } // namespace NotificationNapi
260 } // namespace OHOS
261