1 /*
2 * Copyright (c) 2021-2022 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 "disturb_mode.h"
17
18 namespace OHOS {
19 namespace NotificationNapi {
20 const int SET_DISTURB_MAX_PARA = 3;
21 const int SET_DISTURB_MIN_PARA = 1;
22 const int GET_DISTURB_MAX_PARA = 2;
23
24 struct SetDoNotDisturbDateParams {
25 NotificationDoNotDisturbDate date;
26 bool hasUserId = false;
27 int32_t userId = SUBSCRIBE_USER_INIT;
28 napi_ref callback = nullptr;
29 };
30
31 struct GetDoNotDisturbDateParams {
32 bool hasUserId = false;
33 int32_t userId = SUBSCRIBE_USER_INIT;
34 napi_ref callback = nullptr;
35 };
36
37 struct AsyncCallbackInfoSetDoNotDisturb {
38 napi_env env = nullptr;
39 napi_async_work asyncWork = nullptr;
40 SetDoNotDisturbDateParams params;
41 CallbackPromiseInfo info;
42 };
43
44 struct AsyncCallbackInfoGetDoNotDisturb {
45 napi_env env = nullptr;
46 napi_async_work asyncWork = nullptr;
47 GetDoNotDisturbDateParams params;
48 NotificationDoNotDisturbDate date;
49 CallbackPromiseInfo info;
50 };
51
52 struct AsyncCallbackInfoSupportDoNotDisturb {
53 napi_env env = nullptr;
54 napi_async_work asyncWork = nullptr;
55 napi_ref callback = nullptr;
56 bool isSupported = false;
57 CallbackPromiseInfo info;
58 };
59
GetDoNotDisturbDate(const napi_env & env,const napi_value & argv,SetDoNotDisturbDateParams & params)60 napi_value GetDoNotDisturbDate(const napi_env &env, const napi_value &argv, SetDoNotDisturbDateParams ¶ms)
61 {
62 ANS_LOGI("enter");
63 napi_value value = nullptr;
64 bool hasProperty = false;
65 napi_valuetype valuetype = napi_undefined;
66 // argv[0]: date:type
67 NAPI_CALL(env, napi_has_named_property(env, argv, "type", &hasProperty));
68 if (!hasProperty) {
69 ANS_LOGW("Wrong argument type. Property type expected.");
70 return nullptr;
71 }
72 napi_get_named_property(env, argv, "type", &value);
73 NAPI_CALL(env, napi_typeof(env, value, &valuetype));
74 if (valuetype != napi_number) {
75 ANS_LOGW("Wrong argument type. Number expected.");
76 return nullptr;
77 }
78 int type = 0;
79 NotificationConstant::DoNotDisturbType outType = NotificationConstant::DoNotDisturbType::NONE;
80 napi_get_value_int32(env, value, &type);
81 ANS_LOGI("type is: %{public}d", type);
82 if (!Common::DoNotDisturbTypeJSToC(DoNotDisturbType(type), outType)) {
83 return nullptr;
84 }
85 params.date.SetDoNotDisturbType(outType);
86
87 // argv[0]: date:begin
88 NAPI_CALL(env, napi_has_named_property(env, argv, "begin", &hasProperty));
89 if (!hasProperty) {
90 ANS_LOGW("Wrong argument type. Property type expected.");
91 return nullptr;
92 }
93 double begin = 0;
94 napi_get_named_property(env, argv, "begin", &value);
95 bool isDate = false;
96 napi_is_date(env, value, &isDate);
97 if (!isDate) {
98 ANS_LOGE("Wrong argument type. Date expected.");
99 return nullptr;
100 }
101 napi_get_date_value(env, value, &begin);
102 params.date.SetBeginDate(int64_t(begin));
103
104 // argv[0]: date:end
105 NAPI_CALL(env, napi_has_named_property(env, argv, "end", &hasProperty));
106 if (!hasProperty) {
107 ANS_LOGW("Wrong argument type. Property type expected.");
108 return nullptr;
109 }
110 double end = 0;
111 napi_get_named_property(env, argv, "end", &value);
112 isDate = false;
113 napi_is_date(env, value, &isDate);
114 if (!isDate) {
115 ANS_LOGE("Wrong argument type. Date expected.");
116 return nullptr;
117 }
118 napi_get_date_value(env, value, &end);
119 params.date.SetEndDate(int64_t(end));
120
121 return Common::NapiGetNull(env);
122 }
123
ParseParameters(const napi_env & env,const napi_callback_info & info,SetDoNotDisturbDateParams & params)124 napi_value ParseParameters(const napi_env &env, const napi_callback_info &info, SetDoNotDisturbDateParams ¶ms)
125 {
126 ANS_LOGI("enter");
127
128 size_t argc = SET_DISTURB_MAX_PARA;
129 napi_value argv[SET_DISTURB_MAX_PARA] = {nullptr};
130 napi_value thisVar = nullptr;
131 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
132 if (argc < SET_DISTURB_MIN_PARA) {
133 ANS_LOGW("Wrong argument type. Property type expected.");
134 return nullptr;
135 }
136
137 // argv[0]: date
138 napi_valuetype valuetype = napi_undefined;
139 NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &valuetype));
140 if (valuetype != napi_object) {
141 ANS_LOGW("Wrong argument type. Property type expected.");
142 return nullptr;
143 }
144 if (GetDoNotDisturbDate(env, argv[PARAM0], params) == nullptr) {
145 return nullptr;
146 }
147
148 // argv[1] : userId / callback
149 if (argc >= SET_DISTURB_MAX_PARA - 1) {
150 NAPI_CALL(env, napi_typeof(env, argv[PARAM1], &valuetype));
151 if ((valuetype != napi_number) && (valuetype != napi_function)) {
152 ANS_LOGW("Wrong argument type. Function or object expected.");
153 return nullptr;
154 }
155
156 if (valuetype == napi_number) {
157 params.hasUserId = true;
158 NAPI_CALL(env, napi_get_value_int32(env, argv[PARAM1], ¶ms.userId));
159 } else {
160 napi_create_reference(env, argv[PARAM1], 1, ¶ms.callback);
161 }
162 }
163
164 // argv[2]:callback
165 if (argc >= SET_DISTURB_MAX_PARA) {
166 NAPI_CALL(env, napi_typeof(env, argv[PARAM2], &valuetype));
167 if (valuetype != napi_function) {
168 ANS_LOGW("Wrong argument type. Function expected.");
169 return nullptr;
170 }
171 napi_create_reference(env, argv[PARAM2], 1, ¶ms.callback);
172 }
173
174 return Common::NapiGetNull(env);
175 }
176
SetDoNotDisturbDate(napi_env env,napi_callback_info info)177 napi_value SetDoNotDisturbDate(napi_env env, napi_callback_info info)
178 {
179 ANS_LOGI("enter");
180
181 SetDoNotDisturbDateParams params {};
182 if (ParseParameters(env, info, params) == nullptr) {
183 return Common::NapiGetUndefined(env);
184 }
185
186 AsyncCallbackInfoSetDoNotDisturb *asynccallbackinfo =
187 new (std::nothrow) AsyncCallbackInfoSetDoNotDisturb {.env = env, .asyncWork = nullptr, .params = params};
188 if (!asynccallbackinfo) {
189 return Common::JSParaError(env, params.callback);
190 }
191 napi_value promise = nullptr;
192 Common::PaddingCallbackPromiseInfo(env, params.callback, asynccallbackinfo->info, promise);
193
194 napi_value resourceName = nullptr;
195 napi_create_string_latin1(env, "setDoNotDisturbDate", NAPI_AUTO_LENGTH, &resourceName);
196 // Asynchronous function call
197 napi_create_async_work(env,
198 nullptr, resourceName, [](napi_env env, void *data) {
199 ANS_LOGI("SetDoNotDisturbDate napi_create_async_work start");
200 AsyncCallbackInfoSetDoNotDisturb *asynccallbackinfo = (AsyncCallbackInfoSetDoNotDisturb *)data;
201 if (asynccallbackinfo->params.hasUserId) {
202 asynccallbackinfo->info.errorCode = NotificationHelper::SetDoNotDisturbDate(
203 asynccallbackinfo->params.userId, asynccallbackinfo->params.date);
204 } else {
205 asynccallbackinfo->info.errorCode = NotificationHelper::SetDoNotDisturbDate(
206 asynccallbackinfo->params.date);
207 }
208
209 ANS_LOGI("SetDoNotDisturbDate date=%{public}s errorCode=%{public}d, hasUserId=%{public}d",
210 asynccallbackinfo->params.date.Dump().c_str(), asynccallbackinfo->info.errorCode,
211 asynccallbackinfo->params.hasUserId);
212 },
213 [](napi_env env, napi_status status, void *data) {
214 ANS_LOGI("SetDoNotDisturbDate napi_create_async_work end");
215 AsyncCallbackInfoSetDoNotDisturb *asynccallbackinfo = (AsyncCallbackInfoSetDoNotDisturb *)data;
216 if (asynccallbackinfo) {
217 Common::ReturnCallbackPromise(env, asynccallbackinfo->info, Common::NapiGetNull(env));
218 if (asynccallbackinfo->info.callback != nullptr) {
219 napi_delete_reference(env, asynccallbackinfo->info.callback);
220 }
221 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
222 delete asynccallbackinfo;
223 asynccallbackinfo = nullptr;
224 }
225 },
226 (void *)asynccallbackinfo, &asynccallbackinfo->asyncWork);
227
228 NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork));
229
230 if (asynccallbackinfo->info.isCallback) {
231 return Common::NapiGetNull(env);
232 } else {
233 return promise;
234 }
235 }
236
AsyncCompleteCallbackGetDoNotDisturbDate(napi_env env,napi_status status,void * data)237 void AsyncCompleteCallbackGetDoNotDisturbDate(napi_env env, napi_status status, void *data)
238 {
239 ANS_LOGI("enter");
240 if (!data) {
241 ANS_LOGE("Invalid async callback data");
242 return;
243 }
244 AsyncCallbackInfoGetDoNotDisturb *asynccallbackinfo = (AsyncCallbackInfoGetDoNotDisturb *)data;
245 if (asynccallbackinfo) {
246 napi_value result = Common::NapiGetNull(env);
247 if (asynccallbackinfo->info.errorCode == ERR_OK) {
248 napi_create_object(env, &result);
249 if (!Common::SetDoNotDisturbDate(env, asynccallbackinfo->date, result)) {
250 asynccallbackinfo->info.errorCode = ERROR;
251 }
252 }
253 Common::ReturnCallbackPromise(env, asynccallbackinfo->info, result);
254 if (asynccallbackinfo->info.callback != nullptr) {
255 napi_delete_reference(env, asynccallbackinfo->info.callback);
256 }
257 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
258 delete asynccallbackinfo;
259 asynccallbackinfo = nullptr;
260 }
261 }
262
ParseParameters(const napi_env & env,const napi_callback_info & info,GetDoNotDisturbDateParams & params)263 napi_value ParseParameters(const napi_env &env, const napi_callback_info &info, GetDoNotDisturbDateParams ¶ms)
264 {
265 ANS_LOGI("enter");
266
267 size_t argc = GET_DISTURB_MAX_PARA;
268 napi_value argv[GET_DISTURB_MAX_PARA] = {nullptr};
269 napi_value thisVar = nullptr;
270 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, NULL));
271
272 napi_valuetype valuetype = napi_undefined;
273 // argv[0]: userId / callback
274 if (argc >= GET_DISTURB_MAX_PARA - 1) {
275 NAPI_CALL(env, napi_typeof(env, argv[PARAM0], &valuetype));
276 if ((valuetype != napi_number) && (valuetype != napi_function)) {
277 ANS_LOGW("Wrong argument type. Function or object expected.");
278 return nullptr;
279 }
280 if (valuetype == napi_number) {
281 params.hasUserId = true;
282 NAPI_CALL(env, napi_get_value_int32(env, argv[PARAM0], ¶ms.userId));
283 } else {
284 napi_create_reference(env, argv[PARAM0], 1, ¶ms.callback);
285 }
286 }
287
288 // argv[1]:callback
289 if (argc >= GET_DISTURB_MAX_PARA) {
290 NAPI_CALL(env, napi_typeof(env, argv[PARAM1], &valuetype));
291 if (valuetype != napi_function) {
292 ANS_LOGW("Wrong argument type. Function expected.");
293 return nullptr;
294 }
295 napi_create_reference(env, argv[PARAM1], 1, ¶ms.callback);
296 }
297
298 return Common::NapiGetNull(env);
299 }
300
GetDoNotDisturbDate(napi_env env,napi_callback_info info)301 napi_value GetDoNotDisturbDate(napi_env env, napi_callback_info info)
302 {
303 ANS_LOGI("enter");
304
305 GetDoNotDisturbDateParams params {};
306 if (ParseParameters(env, info, params) == nullptr) {
307 return Common::NapiGetUndefined(env);
308 }
309
310 AsyncCallbackInfoGetDoNotDisturb *asynccallbackinfo =
311 new (std::nothrow) AsyncCallbackInfoGetDoNotDisturb {.env = env, .asyncWork = nullptr, .params = params};
312 if (!asynccallbackinfo) {
313 return Common::JSParaError(env, params.callback);
314 }
315 napi_value promise = nullptr;
316 Common::PaddingCallbackPromiseInfo(env, params.callback, asynccallbackinfo->info, promise);
317
318 napi_value resourceName = nullptr;
319 napi_create_string_latin1(env, "getDoNotDisturbDate", NAPI_AUTO_LENGTH, &resourceName);
320 // Asynchronous function call
321 napi_create_async_work(env,
322 nullptr,
323 resourceName,
324 [](napi_env env, void *data) {
325 ANS_LOGI("GetDoNotDisturbDate napi_create_async_work start");
326 AsyncCallbackInfoGetDoNotDisturb *asynccallbackinfo = (AsyncCallbackInfoGetDoNotDisturb *)data;
327 if (asynccallbackinfo->params.hasUserId) {
328 asynccallbackinfo->info.errorCode = NotificationHelper::GetDoNotDisturbDate(
329 asynccallbackinfo->params.userId, asynccallbackinfo->date);
330 } else {
331 asynccallbackinfo->info.errorCode = NotificationHelper::GetDoNotDisturbDate(asynccallbackinfo->date);
332 }
333
334 ANS_LOGI("GetDoNotDisturbDate errorCode=%{public}d date=%{public}s, hasUserId=%{public}d",
335 asynccallbackinfo->info.errorCode, asynccallbackinfo->date.Dump().c_str(),
336 asynccallbackinfo->params.hasUserId);
337 },
338 AsyncCompleteCallbackGetDoNotDisturbDate,
339 (void *)asynccallbackinfo,
340 &asynccallbackinfo->asyncWork);
341
342 NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork));
343
344 if (asynccallbackinfo->info.isCallback) {
345 return Common::NapiGetNull(env);
346 } else {
347 return promise;
348 }
349 }
350
SupportDoNotDisturbMode(napi_env env,napi_callback_info info)351 napi_value SupportDoNotDisturbMode(napi_env env, napi_callback_info info)
352 {
353 ANS_LOGI("enter");
354
355 napi_ref callback = nullptr;
356 if (Common::ParseParaOnlyCallback(env, info, callback) == nullptr) {
357 return Common::NapiGetUndefined(env);
358 }
359
360 AsyncCallbackInfoSupportDoNotDisturb *asynccallbackinfo =
361 new (std::nothrow) AsyncCallbackInfoSupportDoNotDisturb {
362 .env = env, .asyncWork = nullptr, .callback = callback};
363
364 if (!asynccallbackinfo) {
365 return Common::JSParaError(env, callback);
366 }
367 napi_value promise = nullptr;
368 Common::PaddingCallbackPromiseInfo(env, callback, asynccallbackinfo->info, promise);
369
370 napi_value resourceName = nullptr;
371 napi_create_string_latin1(env, "supportDoNotDisturbMode", NAPI_AUTO_LENGTH, &resourceName);
372 // Asynchronous function call
373 napi_create_async_work(env,
374 nullptr,
375 resourceName,
376 [](napi_env env, void *data) {
377 ANS_LOGI("SupportDoNotDisturbMode napi_create_async_work start");
378 AsyncCallbackInfoSupportDoNotDisturb *asynccallbackinfo = (AsyncCallbackInfoSupportDoNotDisturb *)data;
379 asynccallbackinfo->info.errorCode =
380 NotificationHelper::DoesSupportDoNotDisturbMode(asynccallbackinfo->isSupported);
381 ANS_LOGI("SupportDoNotDisturbMode errorCode=%{public}d isSupported=%{public}d",
382 asynccallbackinfo->info.errorCode, asynccallbackinfo->isSupported);
383 },
384 [](napi_env env, napi_status status, void *data) {
385 ANS_LOGI("SupportDoNotDisturbMode napi_create_async_work end");
386 AsyncCallbackInfoSupportDoNotDisturb *asynccallbackinfo = (AsyncCallbackInfoSupportDoNotDisturb *)data;
387 if (asynccallbackinfo) {
388 napi_value result = nullptr;
389 napi_get_boolean(env, asynccallbackinfo->isSupported, &result);
390 Common::ReturnCallbackPromise(env, asynccallbackinfo->info, result);
391 if (asynccallbackinfo->info.callback != nullptr) {
392 napi_delete_reference(env, asynccallbackinfo->info.callback);
393 }
394 napi_delete_async_work(env, asynccallbackinfo->asyncWork);
395 delete asynccallbackinfo;
396 asynccallbackinfo = nullptr;
397 }
398 },
399 (void *)asynccallbackinfo,
400 &asynccallbackinfo->asyncWork);
401
402 NAPI_CALL(env, napi_queue_async_work(env, asynccallbackinfo->asyncWork));
403
404 if (asynccallbackinfo->info.isCallback) {
405 return Common::NapiGetNull(env);
406 } else {
407 return promise;
408 }
409 }
410 } // namespace NotificationNapi
411 } // namespace OHOS