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_LOGI("enter");
27 napi_ref callback = nullptr;
28 SubscriberInstance *objectInfo = nullptr;
29 NotificationSubscribeInfo subscriberInfo;
30 if (ParseParameters(env, info, subscriberInfo, objectInfo, callback) == nullptr) {
31 if (objectInfo) {
32 delete objectInfo;
33 objectInfo = nullptr;
34 }
35 Common::NapiThrow(env, ERROR_PARAM_INVALID);
36 return Common::NapiGetUndefined(env);
37 }
38
39 AsyncCallbackInfoSubscribe *asynccallbackinfo = new (std::nothrow) AsyncCallbackInfoSubscribe {
40 .env = env, .asyncWork = nullptr, .objectInfo = objectInfo, .subscriberInfo = subscriberInfo
41 };
42 if (!asynccallbackinfo) {
43 if (objectInfo) {
44 delete objectInfo;
45 objectInfo = nullptr;
46 }
47 return Common::JSParaError(env, callback);
48 }
49 napi_value promise = nullptr;
50 Common::PaddingCallbackPromiseInfo(env, callback, asynccallbackinfo->info, promise);
51
52 napi_value resourceName = nullptr;
53 napi_create_string_latin1(env, "subscribeNotification", NAPI_AUTO_LENGTH, &resourceName);
54 // Asynchronous function call
55 napi_create_async_work(env,
56 nullptr,
57 resourceName,
58 [](napi_env env, void *data) {
59 ANS_LOGI("Subscribe napi_create_async_work start");
60 if (!data) {
61 ANS_LOGE("Invalid asynccallbackinfo!");
62 return;
63 }
64 auto asynccallbackinfo = reinterpret_cast<AsyncCallbackInfoSubscribe *>(data);
65 if (asynccallbackinfo) {
66 if (asynccallbackinfo->subscriberInfo.hasSubscribeInfo) {
67 ANS_LOGI("Subscribe with NotificationSubscribeInfo");
68 OHOS::Notification::NotificationSubscribeInfo subscribeInfo;
69 subscribeInfo.AddAppNames(asynccallbackinfo->subscriberInfo.bundleNames);
70 subscribeInfo.AddAppUserId(asynccallbackinfo->subscriberInfo.userId);
71 asynccallbackinfo->info.errorCode =
72 NotificationHelper::SubscribeNotification(*(asynccallbackinfo->objectInfo), subscribeInfo);
73 } else {
74 asynccallbackinfo->info.errorCode =
75 NotificationHelper::SubscribeNotification(*(asynccallbackinfo->objectInfo));
76 }
77 }
78 },
79 [](napi_env env, napi_status status, void *data) {
80 ANS_LOGI("Subscribe napi_create_async_work end");
81 if (!data) {
82 ANS_LOGE("Invalid asynccallbackinfo!");
83 return;
84 }
85 auto asynccallbackinfo = reinterpret_cast<AsyncCallbackInfoSubscribe *>(data);
86 if (asynccallbackinfo) {
87 Common::CreateReturnValue(env, asynccallbackinfo->info, Common::NapiGetNull(env));
88
89 if (asynccallbackinfo->info.callback != nullptr) {
90 napi_delete_reference(env, asynccallbackinfo->info.callback);
91 }
92 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
93
94 delete asynccallbackinfo;
95 asynccallbackinfo = nullptr;
96 }
97 },
98 (void *)asynccallbackinfo,
99 &asynccallbackinfo->asyncWork);
100
101 bool isCallback = asynccallbackinfo->info.isCallback;
102 napi_status status = napi_queue_async_work(env, asynccallbackinfo->asyncWork);
103 if (status != napi_ok) {
104 ANS_LOGE("napi_queue_async_work failed return: %{public}d", status);
105 asynccallbackinfo->info.errorCode = ERROR_INTERNAL_ERROR;
106 Common::CreateReturnValue(env, asynccallbackinfo->info, Common::NapiGetNull(env));
107 if (asynccallbackinfo->info.callback != nullptr) {
108 napi_delete_reference(env, asynccallbackinfo->info.callback);
109 }
110 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
111 delete asynccallbackinfo;
112 asynccallbackinfo = nullptr;
113 }
114
115 if (isCallback) {
116 return Common::NapiGetNull(env);
117 } else {
118 return promise;
119 }
120 }
121
NapiUnsubscribe(napi_env env,napi_callback_info info)122 napi_value NapiUnsubscribe(napi_env env, napi_callback_info info)
123 {
124 ANS_LOGI("Unsubscribe start");
125 ParametersInfoUnsubscribe paras;
126 if (ParseParameters(env, info, paras) == nullptr) {
127 Common::NapiThrow(env, ERROR_PARAM_INVALID);
128 return Common::NapiGetUndefined(env);
129 }
130
131 AsyncCallbackInfoUnsubscribe *asynccallbackinfo = new (std::nothrow)
132 AsyncCallbackInfoUnsubscribe {.env = env, .asyncWork = nullptr, .objectInfo = paras.objectInfo};
133 if (!asynccallbackinfo) {
134 return Common::JSParaError(env, paras.callback);
135 }
136 napi_value promise = nullptr;
137 Common::PaddingCallbackPromiseInfo(env, paras.callback, asynccallbackinfo->info, promise);
138
139 napi_value resourceName = nullptr;
140 napi_create_string_latin1(env, "unsubscribe", NAPI_AUTO_LENGTH, &resourceName);
141
142 // Asynchronous function call
143 napi_create_async_work(env,
144 nullptr,
145 resourceName,
146 [](napi_env env, void *data) {
147 ANS_LOGI("Unsubscribe napi_create_async_work start");
148 auto asynccallbackinfo = reinterpret_cast<AsyncCallbackInfoUnsubscribe *>(data);
149 if (asynccallbackinfo) {
150 if (asynccallbackinfo->objectInfo == nullptr) {
151 ANS_LOGE("invalid object info");
152 asynccallbackinfo->info.errorCode = ERR_ANS_INVALID_PARAM;
153 return;
154 }
155
156 bool ret = AddDeletingSubscriber(asynccallbackinfo->objectInfo);
157 if (ret) {
158 asynccallbackinfo->info.errorCode =
159 NotificationHelper::UnSubscribeNotification(*(asynccallbackinfo->objectInfo));
160 if (asynccallbackinfo->info.errorCode != ERR_OK) {
161 DelDeletingSubscriber(asynccallbackinfo->objectInfo);
162 }
163 } else {
164 asynccallbackinfo->info.errorCode = ERR_ANS_SUBSCRIBER_IS_DELETING;
165 }
166 }
167 },
168 [](napi_env env, napi_status status, void *data) {
169 ANS_LOGI("Unsubscribe napi_create_async_work end");
170 AsyncCallbackInfoUnsubscribe *asynccallbackinfo = static_cast<AsyncCallbackInfoUnsubscribe *>(data);
171 if (asynccallbackinfo) {
172 Common::CreateReturnValue(env, asynccallbackinfo->info, Common::NapiGetNull(env));
173 if (asynccallbackinfo->info.callback != nullptr) {
174 napi_delete_reference(env, asynccallbackinfo->info.callback);
175 }
176 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
177 delete asynccallbackinfo;
178 asynccallbackinfo = nullptr;
179 }
180 },
181 (void *)asynccallbackinfo,
182 &asynccallbackinfo->asyncWork);
183
184 bool isCallback = asynccallbackinfo->info.isCallback;
185 napi_status status = napi_queue_async_work(env, asynccallbackinfo->asyncWork);
186 if (status != napi_ok) {
187 ANS_LOGE("napi_queue_async_work failed return: %{public}d", status);
188 asynccallbackinfo->info.errorCode = ERROR_INTERNAL_ERROR;
189 Common::CreateReturnValue(env, asynccallbackinfo->info, Common::NapiGetNull(env));
190 if (asynccallbackinfo->info.callback != nullptr) {
191 napi_delete_reference(env, asynccallbackinfo->info.callback);
192 }
193 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
194 delete asynccallbackinfo;
195 asynccallbackinfo = nullptr;
196 }
197
198 if (isCallback) {
199 return Common::NapiGetNull(env);
200 } else {
201 return promise;
202 }
203 }
204 } // namespace NotificationNapi
205 } // namespace OHOS