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 #include <memory>
22 #include <new>
23
24 namespace OHOS {
25 namespace NotificationNapi {
NapiSubscribe(napi_env env,napi_callback_info info)26 napi_value NapiSubscribe(napi_env env, napi_callback_info info)
27 {
28 ANS_LOGD("enter");
29 napi_ref callback = nullptr;
30 std::shared_ptr<SubscriberInstance> objectInfo = nullptr;
31 NotificationSubscribeInfo subscriberInfo;
32 if (ParseParameters(env, info, subscriberInfo, objectInfo, callback) == nullptr) {
33 Common::NapiThrow(env, ERROR_PARAM_INVALID);
34 return Common::NapiGetUndefined(env);
35 }
36
37 AsyncCallbackInfoSubscribe *asynccallbackinfo = new (std::nothrow) AsyncCallbackInfoSubscribe {
38 .env = env, .asyncWork = nullptr, .objectInfo = objectInfo, .subscriberInfo = subscriberInfo
39 };
40 if (!asynccallbackinfo) {
41 Common::NapiThrow(env, ERROR_INTERNAL_ERROR);
42 return Common::JSParaError(env, callback);
43 }
44 napi_value promise = nullptr;
45 Common::PaddingCallbackPromiseInfo(env, callback, asynccallbackinfo->info, promise);
46
47 napi_value resourceName = nullptr;
48 napi_create_string_latin1(env, "subscribeNotification", NAPI_AUTO_LENGTH, &resourceName);
49 // Asynchronous function call
50 napi_create_async_work(env,
51 nullptr,
52 resourceName,
53 [](napi_env env, void *data) {
54 ANS_LOGD("NapiSubscribe work excute.");
55 if (!data) {
56 ANS_LOGE("Invalid asynccallbackinfo!");
57 return;
58 }
59 auto asynccallbackinfo = reinterpret_cast<AsyncCallbackInfoSubscribe *>(data);
60 if (asynccallbackinfo) {
61 if (asynccallbackinfo->subscriberInfo.hasSubscribeInfo) {
62 ANS_LOGI("Subscribe with NotificationSubscribeInfo");
63 sptr<OHOS::Notification::NotificationSubscribeInfo> subscribeInfo =
64 new (std::nothrow) OHOS::Notification::NotificationSubscribeInfo();
65 subscribeInfo->AddAppNames(asynccallbackinfo->subscriberInfo.bundleNames);
66 subscribeInfo->AddAppUserId(asynccallbackinfo->subscriberInfo.userId);
67 subscribeInfo->AddDeviceType(asynccallbackinfo->subscriberInfo.deviceType);
68 asynccallbackinfo->info.errorCode =
69 NotificationHelper::SubscribeNotification(asynccallbackinfo->objectInfo, subscribeInfo);
70 } else {
71 asynccallbackinfo->info.errorCode =
72 NotificationHelper::SubscribeNotification(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 }
147 },
148 [](napi_env env, napi_status status, void *data) {
149 ANS_LOGD("NapiSubscribeSelf work complete.");
150 if (!data) {
151 ANS_LOGE("Invalid asynccallbackinfo!");
152 return;
153 }
154 auto asynccallbackinfo = reinterpret_cast<AsyncCallbackInfoSubscribe *>(data);
155 if (asynccallbackinfo) {
156 Common::CreateReturnValue(env, asynccallbackinfo->info, Common::NapiGetNull(env));
157 if (asynccallbackinfo->info.callback != nullptr) {
158 ANS_LOGD("Delete napiSubscribeSelf callback reference.");
159 napi_delete_reference(env, asynccallbackinfo->info.callback);
160 }
161 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
162 delete asynccallbackinfo;
163 asynccallbackinfo = nullptr;
164 }
165 ANS_LOGD("NapiSubscribeSelf work complete end.");
166 },
167 (void *)asynccallbackinfo,
168 &asynccallbackinfo->asyncWork);
169
170 bool isCallback = asynccallbackinfo->info.isCallback;
171 napi_queue_async_work_with_qos(env, asynccallbackinfo->asyncWork, napi_qos_user_initiated);
172
173 if (isCallback) {
174 ANS_LOGD("NapiSubscribeSelf callback is nullptr.");
175 return Common::NapiGetNull(env);
176 } else {
177 return promise;
178 }
179 }
180
NapiUnsubscribe(napi_env env,napi_callback_info info)181 napi_value NapiUnsubscribe(napi_env env, napi_callback_info info)
182 {
183 ANS_LOGI("Unsubscribe start");
184 ParametersInfoUnsubscribe paras;
185 if (ParseParameters(env, info, paras) == nullptr) {
186 Common::NapiThrow(env, ERROR_PARAM_INVALID);
187 return Common::NapiGetUndefined(env);
188 }
189
190 AsyncCallbackInfoUnsubscribe *asynccallbackinfo = new (std::nothrow)
191 AsyncCallbackInfoUnsubscribe {.env = env, .asyncWork = nullptr, .objectInfo = paras.objectInfo};
192 if (!asynccallbackinfo) {
193 Common::NapiThrow(env, ERROR_INTERNAL_ERROR);
194 return Common::JSParaError(env, paras.callback);
195 }
196 napi_value promise = nullptr;
197 Common::PaddingCallbackPromiseInfo(env, paras.callback, asynccallbackinfo->info, promise);
198
199 napi_value resourceName = nullptr;
200 napi_create_string_latin1(env, "unsubscribe", NAPI_AUTO_LENGTH, &resourceName);
201
202 // Asynchronous function call
203 napi_create_async_work(env,
204 nullptr,
205 resourceName,
206 [](napi_env env, void *data) {
207 ANS_LOGD("NapiUnsubscribe work excute.");
208 auto asynccallbackinfo = reinterpret_cast<AsyncCallbackInfoUnsubscribe *>(data);
209 if (asynccallbackinfo) {
210 if (asynccallbackinfo->objectInfo == nullptr) {
211 ANS_LOGE("invalid object info");
212 asynccallbackinfo->info.errorCode = ERR_ANS_INVALID_PARAM;
213 return;
214 }
215
216 bool ret = AddDeletingSubscriber(asynccallbackinfo->objectInfo);
217 if (ret) {
218 asynccallbackinfo->info.errorCode =
219 NotificationHelper::UnSubscribeNotification(asynccallbackinfo->objectInfo);
220 if (asynccallbackinfo->info.errorCode != ERR_OK) {
221 DelDeletingSubscriber(asynccallbackinfo->objectInfo);
222 }
223 } else {
224 asynccallbackinfo->info.errorCode = ERR_ANS_SUBSCRIBER_IS_DELETING;
225 }
226 }
227 },
228 [](napi_env env, napi_status status, void *data) {
229 ANS_LOGD("NapiUnsubscribe work complete.");
230 AsyncCallbackInfoUnsubscribe *asynccallbackinfo = static_cast<AsyncCallbackInfoUnsubscribe *>(data);
231 if (asynccallbackinfo) {
232 Common::CreateReturnValue(env, asynccallbackinfo->info, Common::NapiGetNull(env));
233 if (asynccallbackinfo->info.callback != nullptr) {
234 ANS_LOGD("Delete napiUnsubscribe callback reference.");
235 napi_delete_reference(env, asynccallbackinfo->info.callback);
236 }
237 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
238 delete asynccallbackinfo;
239 asynccallbackinfo = nullptr;
240 }
241 ANS_LOGD("NapiUnsubscribe work complete end.");
242 },
243 (void *)asynccallbackinfo,
244 &asynccallbackinfo->asyncWork);
245
246 bool isCallback = asynccallbackinfo->info.isCallback;
247 napi_queue_async_work_with_qos(env, asynccallbackinfo->asyncWork, napi_qos_user_initiated);
248
249 if (isCallback) {
250 ANS_LOGD("napiUnsubscribe callback is nullptr.");
251 return Common::NapiGetNull(env);
252 } else {
253 return promise;
254 }
255 }
256 } // namespace NotificationNapi
257 } // namespace OHOS
258