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 "display_badge.h"
17
18 namespace OHOS {
19 namespace NotificationNapi {
20 const int ENABLE_BADGE_DISPLAYED_MAX_PARA = 3;
21 const int ENABLE_BADGE_DISPLAYED_MIN_PARA = 2;
22 const int IS_DISPLAY_BADGE_MAX_PARA = 2;
23 const int IS_DISPLAY_BADGE_MIN_PARA = 1;
24
ParseParameters(const napi_env & env,const napi_callback_info & info,EnableBadgeParams & params)25 napi_value ParseParameters(const napi_env &env, const napi_callback_info &info, EnableBadgeParams ¶ms)
26 {
27 ANS_LOGI("enter");
28
29 size_t argc = ENABLE_BADGE_DISPLAYED_MAX_PARA;
30 napi_value argv[ENABLE_BADGE_DISPLAYED_MAX_PARA] = {nullptr};
31 napi_value thisVar = nullptr;
32 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
33 if (argc < ENABLE_BADGE_DISPLAYED_MIN_PARA) {
34 ANS_LOGW("Wrong number of arguments.");
35 return nullptr;
36 }
37
38 // argv[0]: bundle
39 napi_valuetype valuetype = napi_undefined;
40 NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &valuetype));
41 if (valuetype != napi_object) {
42 ANS_LOGW("Wrong argument type. Object expected.");
43 return nullptr;
44 }
45
46 auto retValue = Common::GetBundleOption(env, argv[PARAM0], params.option);
47 if (retValue == nullptr) {
48 ANS_LOGE("GetBundleOption failed.");
49 return nullptr;
50 }
51
52 // argv[1]: enable
53 NAPI_CALL(env, napi_typeof(env, argv[PARAM1], &valuetype));
54 if (valuetype != napi_boolean) {
55 ANS_LOGW("Wrong argument type. Bool expected.");
56 return nullptr;
57 }
58 napi_get_value_bool(env, argv[PARAM1], ¶ms.enable);
59
60 // argv[2]:callback
61 if (argc >= ENABLE_BADGE_DISPLAYED_MAX_PARA) {
62 NAPI_CALL(env, napi_typeof(env, argv[PARAM2], &valuetype));
63 if (valuetype != napi_function) {
64 ANS_LOGW("Callback is not function excute promise.");
65 return Common::NapiGetNull(env);
66 }
67 napi_create_reference(env, argv[PARAM2], 1, ¶ms.callback);
68 }
69
70 return Common::NapiGetNull(env);
71 }
72
ParseParameters(const napi_env & env,const napi_callback_info & info,IsDisplayBadgeParams & params)73 napi_value ParseParameters(const napi_env &env, const napi_callback_info &info, IsDisplayBadgeParams ¶ms)
74 {
75 ANS_LOGI("enter");
76
77 size_t argc = IS_DISPLAY_BADGE_MAX_PARA;
78 napi_value argv[IS_DISPLAY_BADGE_MAX_PARA] = {nullptr};
79 napi_value thisVar = nullptr;
80 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
81
82 if (argc < IS_DISPLAY_BADGE_MIN_PARA) {
83 ANS_LOGW("Wrong number of arguments.");
84 return nullptr;
85 }
86
87 // argv[0]: bundle / callback
88 napi_valuetype valuetype = napi_undefined;
89 NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &valuetype));
90
91 if ((valuetype != napi_function) && (valuetype != napi_object)) {
92 ANS_LOGW("Wrong argument type. Function or object expected, %{public}d", valuetype);
93 return nullptr;
94 }
95
96 if (valuetype == napi_object) {
97 auto retValue = Common::GetBundleOption(env, argv[PARAM0], params.option);
98 if (retValue == nullptr) {
99 ANS_LOGE("GetBundleOption failed.");
100 return nullptr;
101 }
102 params.hasBundleOption = true;
103 } else {
104 napi_create_reference(env, argv[PARAM0], 1, ¶ms.callback);
105 }
106
107 // argv[1]:callback
108 if (argc >= IS_DISPLAY_BADGE_MAX_PARA) {
109 NAPI_CALL(env, napi_typeof(env, argv[PARAM1], &valuetype));
110 if (valuetype != napi_function) {
111 ANS_LOGW("Callback is not function excute promise.");
112 return Common::NapiGetNull(env);
113 }
114 napi_create_reference(env, argv[PARAM1], 1, ¶ms.callback);
115 }
116
117 return Common::NapiGetNull(env);
118 }
119
DisplayBadge(napi_env env,napi_callback_info info)120 napi_value DisplayBadge(napi_env env, napi_callback_info info)
121 {
122 ANS_LOGI("enter");
123
124 EnableBadgeParams params {};
125 if (ParseParameters(env, info, params) == nullptr) {
126 return Common::NapiGetUndefined(env);
127 }
128
129 AsyncCallbackInfoEnableBadge *asynccallbackinfo =
130 new (std::nothrow) AsyncCallbackInfoEnableBadge {.env = env, .asyncWork = nullptr, .params = params};
131 if (!asynccallbackinfo) {
132 return Common::JSParaError(env, params.callback);
133 }
134 napi_value promise = nullptr;
135 Common::PaddingCallbackPromiseInfo(env, params.callback, asynccallbackinfo->info, promise);
136
137 napi_value resourceName = nullptr;
138 napi_create_string_latin1(env, "DisplayBadge", NAPI_AUTO_LENGTH, &resourceName);
139 // Asynchronous function call
140 napi_create_async_work(env,
141 nullptr,
142 resourceName,
143 [](napi_env env, void *data) {
144 ANS_LOGI("DisplayBadge napi_create_async_work start");
145 AsyncCallbackInfoEnableBadge *asynccallbackinfo = static_cast<AsyncCallbackInfoEnableBadge *>(data);
146 if (asynccallbackinfo) {
147 ANS_LOGI("option.bundle = %{public}s option.uid = %{public}d enable = %{public}d",
148 asynccallbackinfo->params.option.GetBundleName().c_str(),
149 asynccallbackinfo->params.option.GetUid(),
150 asynccallbackinfo->params.enable);
151 asynccallbackinfo->info.errorCode = NotificationHelper::SetShowBadgeEnabledForBundle(
152 asynccallbackinfo->params.option, asynccallbackinfo->params.enable);
153 ANS_LOGI("asynccallbackinfo->info.errorCode = %{public}d", asynccallbackinfo->info.errorCode);
154 }
155 },
156 [](napi_env env, napi_status status, void *data) {
157 ANS_LOGI("DisplayBadge napi_create_async_work end");
158 AsyncCallbackInfoEnableBadge *asynccallbackinfo = static_cast<AsyncCallbackInfoEnableBadge *>(data);
159 if (asynccallbackinfo) {
160 Common::ReturnCallbackPromise(env, asynccallbackinfo->info, Common::NapiGetNull(env));
161 if (asynccallbackinfo->info.callback != nullptr) {
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 },
169 (void *)asynccallbackinfo,
170 &asynccallbackinfo->asyncWork);
171
172 napi_status status = napi_queue_async_work_with_qos(env, asynccallbackinfo->asyncWork, napi_qos_user_initiated);
173 if (status != napi_ok) {
174 ANS_LOGE("napi_queue_async_work failed return: %{public}d", status);
175 if (asynccallbackinfo->info.callback != nullptr) {
176 napi_delete_reference(env, asynccallbackinfo->info.callback);
177 }
178 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
179 delete asynccallbackinfo;
180 asynccallbackinfo = nullptr;
181 return Common::JSParaError(env, params.callback);
182 }
183
184 if (asynccallbackinfo->info.isCallback) {
185 return Common::NapiGetNull(env);
186 } else {
187 return promise;
188 }
189 }
190
AsyncCompleteCallbackIsBadgeDisplayed(napi_env env,napi_status status,void * data)191 void AsyncCompleteCallbackIsBadgeDisplayed(napi_env env, napi_status status, void *data)
192 {
193 ANS_LOGI("enter");
194 if (!data) {
195 ANS_LOGE("Invalid async callback data");
196 return;
197 }
198 AsyncCallbackInfoIsDisplayBadge *asynccallbackinfo = static_cast<AsyncCallbackInfoIsDisplayBadge *>(data);
199 if (asynccallbackinfo) {
200 napi_value result = nullptr;
201 napi_get_boolean(env, asynccallbackinfo->enabled, &result);
202 Common::ReturnCallbackPromise(env, asynccallbackinfo->info, result);
203 if (asynccallbackinfo->info.callback != nullptr) {
204 napi_delete_reference(env, asynccallbackinfo->info.callback);
205 }
206 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
207 delete asynccallbackinfo;
208 asynccallbackinfo = nullptr;
209 }
210 }
211
IsBadgeDisplayed(napi_env env,napi_callback_info info)212 napi_value IsBadgeDisplayed(napi_env env, napi_callback_info info)
213 {
214 ANS_LOGI("enter");
215
216 IsDisplayBadgeParams params {};
217 if (ParseParameters(env, info, params) == nullptr) {
218 ANS_LOGE("Failed to parse params!");
219 return Common::NapiGetUndefined(env);
220 }
221
222 AsyncCallbackInfoIsDisplayBadge *asynccallbackinfo =
223 new (std::nothrow) AsyncCallbackInfoIsDisplayBadge {.env = env, .asyncWork = nullptr, .params = params};
224 if (!asynccallbackinfo) {
225 return Common::JSParaError(env, params.callback);
226 }
227 napi_value promise = nullptr;
228 Common::PaddingCallbackPromiseInfo(env, params.callback, asynccallbackinfo->info, promise);
229
230 napi_value resourceName = nullptr;
231 napi_create_string_latin1(env, "IsBadgeDisplayed", NAPI_AUTO_LENGTH, &resourceName);
232 // Asynchronous function call
233 napi_create_async_work(env,
234 nullptr,
235 resourceName,
236 [](napi_env env, void *data) {
237 ANS_LOGI("IsBadgeDisplayed napi_create_async_work start");
238 AsyncCallbackInfoIsDisplayBadge *asynccallbackinfo = static_cast<AsyncCallbackInfoIsDisplayBadge *>(data);
239 if (asynccallbackinfo) {
240 if (asynccallbackinfo->params.hasBundleOption) {
241 ANS_LOGI("option.bundle = %{public}s option.uid = %{public}d",
242 asynccallbackinfo->params.option.GetBundleName().c_str(),
243 asynccallbackinfo->params.option.GetUid());
244 asynccallbackinfo->info.errorCode = NotificationHelper::GetShowBadgeEnabledForBundle(
245 asynccallbackinfo->params.option, asynccallbackinfo->enabled);
246 } else {
247 asynccallbackinfo->info.errorCode = NotificationHelper::GetShowBadgeEnabled(
248 asynccallbackinfo->enabled);
249 }
250 ANS_LOGI("asynccallbackinfo->info.errorCode = %{public}d, enabled = %{public}d",
251 asynccallbackinfo->info.errorCode, asynccallbackinfo->enabled);
252 }
253 },
254 AsyncCompleteCallbackIsBadgeDisplayed,
255 (void *)asynccallbackinfo,
256 &asynccallbackinfo->asyncWork);
257
258 napi_status status = napi_queue_async_work_with_qos(env, asynccallbackinfo->asyncWork, napi_qos_user_initiated);
259 if (status != napi_ok) {
260 ANS_LOGE("napi_queue_async_work failed return: %{public}d", status);
261 if (asynccallbackinfo->info.callback != nullptr) {
262 napi_delete_reference(env, asynccallbackinfo->info.callback);
263 }
264 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
265 delete asynccallbackinfo;
266 asynccallbackinfo = nullptr;
267 return Common::JSParaError(env, params.callback);
268 }
269
270 if (asynccallbackinfo->info.isCallback) {
271 return Common::NapiGetNull(env);
272 } else {
273 return promise;
274 }
275 }
276 } // namespace NotificationNapi
277 } // namespace OHOS