1 /*
2 * Copyright (c) 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 "napi_wallpaper_ability.h"
17
18 #include <map>
19 #include <pthread.h>
20 #include <string>
21 #include <unistd.h>
22 #include <uv.h>
23 #include <vector>
24
25 #include "hilog_wrapper.h"
26 #include "js_error.h"
27 #include "uv_queue.h"
28 #include "wallpaper_manager.h"
29 #include "wallpaper_manager_common_info.h"
30
31 using namespace OHOS::Media;
32 namespace OHOS {
33 namespace WallpaperNAPI {
34 const int32_t ONE = 1;
35 const int32_t TWO = 2;
36 const int32_t EVENTTYPESIZE = 64;
37 const int32_t BUFFERSIZE = 100;
38 constexpr const char *COLOR_CHANGE_EVENT = "colorChange";
39 constexpr const char *WALLPAPER_CHANGE_EVENT = "wallpaperChange";
40
41 struct WorkData {
42 napi_env env_;
43 napi_ref callback_;
WorkDataOHOS::WallpaperNAPI::WorkData44 WorkData(napi_env env, napi_ref callback) : env_(env), callback_(callback)
45 {
46 }
47 };
48
NAPI_GetColors(napi_env env,napi_callback_info info)49 napi_value NAPI_GetColors(napi_env env, napi_callback_info info)
50 {
51 HILOG_DEBUG("NAPI_GetColors in");
52 auto context = std::make_shared<GetContextInfo>();
53 ApiInfo apiInfo{ false, false };
54 NapiWallpaperAbility::GetColorsInner(context, apiInfo);
55 Call call(env, info, std::dynamic_pointer_cast<Call::Context>(context), 1, apiInfo.needException);
56 return call.AsyncCall(env, "getColors");
57 }
58
NAPI_GetColorsSync(napi_env env,napi_callback_info info)59 napi_value NAPI_GetColorsSync(napi_env env, napi_callback_info info)
60 {
61 HILOG_DEBUG("NAPI_GetColorsSync in");
62 auto context = std::make_shared<GetContextInfo>();
63 ApiInfo apiInfo{ true, true };
64 NapiWallpaperAbility::GetColorsInner(context, apiInfo);
65 Call call(env, info, context, 1, apiInfo.needException);
66 return call.SyncCall(env);
67 }
68
GetColorsInner(std::shared_ptr<GetContextInfo> context,const ApiInfo & apiInfo)69 void NapiWallpaperAbility::GetColorsInner(std::shared_ptr<GetContextInfo> context, const ApiInfo &apiInfo)
70 {
71 HILOG_DEBUG("GetColorsInner in");
72 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
73 if (!NapiWallpaperAbility::CheckValidArgWallpaperType(env, argc, argv[0], context)) {
74 return napi_invalid_arg;
75 }
76 napi_get_value_int32(env, argv[0], &context->wallpaperType);
77 HILOG_DEBUG("input wallpaperType : %{public}d", context->wallpaperType);
78 return napi_ok;
79 };
80 auto output = [context](napi_env env, napi_value *result) -> napi_status {
81 napi_value data = WallpaperJSUtil::Convert2JSRgbaArray(env, context->colors);
82 HILOG_DEBUG("output Convert2JSRgbaArray data != nullptr[%{public}d]", data != nullptr);
83 *result = data;
84 return napi_ok;
85 };
86 auto exec = [context, apiInfo](Call::Context *ctx) {
87 HILOG_DEBUG("exec GetColors");
88 ErrorCode wallpaperErrorCode =
89 WallpaperMgrService::WallpaperManagerkits::GetInstance().GetColors(context->wallpaperType, apiInfo,
90 context->colors);
91 if (wallpaperErrorCode == E_OK && !context->colors.empty()) {
92 context->status = napi_ok;
93 return;
94 }
95 if (apiInfo.needException) {
96 JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(wallpaperErrorCode);
97 if (jsErrorInfo.code != 0) {
98 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message);
99 }
100 }
101 HILOG_DEBUG("exec GetColors colors size : %{public}zu", context->colors.size());
102 };
103 context->SetAction(std::move(input), std::move(output));
104 context->SetExecution(std::move(exec));
105 }
106
NAPI_GetId(napi_env env,napi_callback_info info)107 napi_value NAPI_GetId(napi_env env, napi_callback_info info)
108 {
109 auto context = std::make_shared<GetContextInfo>();
110 NapiWallpaperAbility::GetIdInner(context);
111 Call call(env, info, context, 1, false);
112 return call.AsyncCall(env, "getId");
113 }
114
GetIdInner(std::shared_ptr<GetContextInfo> context)115 void NapiWallpaperAbility::GetIdInner(std::shared_ptr<GetContextInfo> context)
116 {
117 HILOG_DEBUG("GetIdInner in");
118 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
119 if (!NapiWallpaperAbility::CheckValidArgWallpaperType(env, argc, argv[0], context)) {
120 return napi_invalid_arg;
121 }
122 napi_get_value_int32(env, argv[0], &context->wallpaperType);
123 HILOG_DEBUG("input wallpaperType : %{public}d", context->wallpaperType);
124 return napi_ok;
125 };
126 auto output = [context](napi_env env, napi_value *result) -> napi_status {
127 napi_status status = napi_create_int32(env, context->wallpaperId, result);
128 HILOG_DEBUG("output napi_create_int32[%{public}d]", status);
129 return status;
130 };
131 auto exec = [context](Call::Context *ctx) {
132 HILOG_DEBUG("exec GetWallpaperId");
133 context->wallpaperId =
134 WallpaperMgrService::WallpaperManagerkits::GetInstance().GetWallpaperId(context->wallpaperType);
135 HILOG_DEBUG("exec GetWallpaperId wallpaperId : %{public}d", context->wallpaperId);
136 context->status = napi_ok;
137 };
138 context->SetAction(std::move(input), std::move(output));
139 context->SetExecution(std::move(exec));
140 }
141
NAPI_GetFile(napi_env env,napi_callback_info info)142 napi_value NAPI_GetFile(napi_env env, napi_callback_info info)
143 {
144 HILOG_DEBUG("NAPI_GetFile in");
145 auto context = std::make_shared<GetFileContextInfo>();
146 ApiInfo apiInfo{ false, false };
147 NapiWallpaperAbility::GetFileInner(context, apiInfo);
148 Call call(env, info, context, 1, apiInfo.needException);
149 return call.AsyncCall(env, "getFile");
150 }
151
GetFileInner(std::shared_ptr<GetFileContextInfo> context,const ApiInfo & apiInfo)152 void NapiWallpaperAbility::GetFileInner(std::shared_ptr<GetFileContextInfo> context, const ApiInfo &apiInfo)
153 {
154 HILOG_DEBUG("GetFileInner in");
155 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
156 if (!NapiWallpaperAbility::CheckValidArgWallpaperType(env, argc, argv[0], context)) {
157 return napi_invalid_arg;
158 }
159 napi_get_value_int32(env, argv[0], &context->wallpaperType);
160 HILOG_DEBUG("input wallpaperType : %{public}d", context->wallpaperType);
161 return napi_ok;
162 };
163
164 auto output = [context](napi_env env, napi_value *result) -> napi_status {
165 napi_value data = nullptr;
166 napi_create_int32(env, context->wallpaperFd, &data);
167 HILOG_DEBUG("output [%{public}d]", data != nullptr);
168 *result = data;
169 return napi_ok;
170 };
171 auto exec = [context, apiInfo](Call::Context *ctx) {
172 HILOG_DEBUG("exec GetFile");
173 ErrorCode wallpaperErrorCode =
174 WallpaperMgrService::WallpaperManagerkits::GetInstance().GetFile(context->wallpaperType,
175 context->wallpaperFd);
176 if (wallpaperErrorCode == E_OK && context->wallpaperFd >= 0) {
177 context->status = napi_ok;
178 return;
179 }
180 if (apiInfo.needException) {
181 JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(wallpaperErrorCode);
182 if (jsErrorInfo.code != 0) {
183 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message);
184 }
185 }
186
187 HILOG_DEBUG("exec GetFile fd: %{public}d", context->wallpaperFd);
188 };
189 context->SetAction(std::move(input), std::move(output));
190 context->SetExecution(std::move(exec));
191 }
192
NAPI_GetMinHeight(napi_env env,napi_callback_info info)193 napi_value NAPI_GetMinHeight(napi_env env, napi_callback_info info)
194 {
195 HILOG_DEBUG("NAPI_GetMinHeight in");
196 auto context = std::make_shared<GetMinContextInfo>();
197 ApiInfo apiInfo{ false, false };
198 NapiWallpaperAbility::GetMinHeightInner(context, apiInfo);
199 Call call(env, info, context, 0, apiInfo.needException);
200 return call.AsyncCall(env, "getMinHeight");
201 }
202
NAPI_GetMinHeightSync(napi_env env,napi_callback_info info)203 napi_value NAPI_GetMinHeightSync(napi_env env, napi_callback_info info)
204 {
205 HILOG_DEBUG("NAPI_GetMinHeightSync in");
206 auto context = std::make_shared<GetMinContextInfo>();
207 ApiInfo apiInfo{ true, true };
208 NapiWallpaperAbility::GetMinHeightInner(context, apiInfo);
209 Call call(env, info, context, 0, apiInfo.needException);
210 return call.SyncCall(env);
211 }
212
GetMinHeightInner(std::shared_ptr<GetMinContextInfo> context,const ApiInfo & apiInfo)213 void NapiWallpaperAbility::GetMinHeightInner(std::shared_ptr<GetMinContextInfo> context, const ApiInfo &apiInfo)
214 {
215 HILOG_DEBUG("GetMinHeightInner in");
216 auto output = [context](napi_env env, napi_value *result) -> napi_status {
217 napi_status status = napi_create_int32(env, context->minHeight, result);
218 HILOG_DEBUG("output napi_create_int32[%{public}d]", status);
219 return status;
220 };
221 auto exec = [context, apiInfo](Call::Context *ctx) {
222 HILOG_DEBUG("exec GetWallpaperMinHeight");
223 ErrorCode wallpaperErrorCode =
224 WallpaperMgrService::WallpaperManagerkits::GetInstance().GetWallpaperMinHeight(apiInfo, context->minHeight);
225 if (wallpaperErrorCode == E_OK && context->minHeight >= 0) {
226 context->status = napi_ok;
227 return;
228 }
229 if (apiInfo.needException) {
230 JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(wallpaperErrorCode);
231 if (jsErrorInfo.code != 0) {
232 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message);
233 }
234 }
235 };
236 context->SetAction(nullptr, std::move(output));
237 context->SetExecution(std::move(exec));
238 }
239
NAPI_GetMinWidth(napi_env env,napi_callback_info info)240 napi_value NAPI_GetMinWidth(napi_env env, napi_callback_info info)
241 {
242 HILOG_DEBUG("NAPI_GetMinWidth in");
243 auto context = std::make_shared<GetMinContextInfo>();
244 ApiInfo apiInfo{ false, false };
245 NapiWallpaperAbility::GetMinWidthInner(context, apiInfo);
246 Call call(env, info, context, 0, apiInfo.needException);
247 return call.AsyncCall(env, "getMinWidth");
248 }
249
NAPI_GetMinWidthSync(napi_env env,napi_callback_info info)250 napi_value NAPI_GetMinWidthSync(napi_env env, napi_callback_info info)
251 {
252 HILOG_DEBUG("NAPI_GetMinWidthSync in");
253 auto context = std::make_shared<GetMinContextInfo>();
254 ApiInfo apiInfo{ true, true };
255 NapiWallpaperAbility::GetMinWidthInner(context, apiInfo);
256 Call call(env, info, context, 0, apiInfo.needException);
257 return call.SyncCall(env);
258 }
259
GetMinWidthInner(std::shared_ptr<GetMinContextInfo> context,const ApiInfo & apiInfo)260 void NapiWallpaperAbility::GetMinWidthInner(std::shared_ptr<GetMinContextInfo> context, const ApiInfo &apiInfo)
261 {
262 HILOG_DEBUG("GetMinWidthInner in");
263 auto output = [context](napi_env env, napi_value *result) -> napi_status {
264 napi_status status = napi_create_int32(env, context->minWidth, result);
265 HILOG_DEBUG("output napi_create_int32[%{public}d]", status);
266 return status;
267 };
268 auto exec = [context, apiInfo](Call::Context *ctx) {
269 HILOG_DEBUG("exec GetWallpaperMinWidth");
270 ErrorCode wallpaperErrorCode =
271 WallpaperMgrService::WallpaperManagerkits::GetInstance().GetWallpaperMinWidth(apiInfo, context->minWidth);
272 if (wallpaperErrorCode == E_OK && context->minWidth >= 0) {
273 context->status = napi_ok;
274 }
275 if (apiInfo.needException) {
276 JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(wallpaperErrorCode);
277 if (jsErrorInfo.code != 0) {
278 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message);
279 }
280 }
281 };
282 context->SetAction(nullptr, std::move(output));
283 context->SetExecution(std::move(exec));
284 }
285
NAPI_IsChangePermitted(napi_env env,napi_callback_info info)286 napi_value NAPI_IsChangePermitted(napi_env env, napi_callback_info info)
287 {
288 HILOG_DEBUG("NAPI_IsChangePermitted in");
289 auto context = std::make_shared<PermissionContextInfo>();
290 NapiWallpaperAbility::IsChangeAllowedInner(context);
291 Call call(env, info, context, 0, false);
292 return call.AsyncCall(env, "isChangePermitted");
293 }
294
IsChangeAllowedInner(std::shared_ptr<PermissionContextInfo> context)295 void NapiWallpaperAbility::IsChangeAllowedInner(std::shared_ptr<PermissionContextInfo> context)
296 {
297 HILOG_DEBUG("IsChangeAllowedInner in");
298 auto output = [context](napi_env env, napi_value *result) -> napi_status {
299 napi_status status = napi_get_boolean(env, context->isChangePermitted, result);
300 HILOG_DEBUG("output napi_get_boolean[%{public}d]", status);
301 return status;
302 };
303 auto exec = [context](Call::Context *ctx) {
304 HILOG_DEBUG("exec IsChangePermitted");
305 context->isChangePermitted = WallpaperMgrService::WallpaperManagerkits::GetInstance().IsChangePermitted();
306 HILOG_DEBUG("exec IsChangePermitted : %{public}d", context->isChangePermitted);
307 context->status = napi_ok;
308 };
309 context->SetAction(nullptr, std::move(output));
310 context->SetExecution(std::move(exec));
311 }
312
NAPI_IsOperationAllowed(napi_env env,napi_callback_info info)313 napi_value NAPI_IsOperationAllowed(napi_env env, napi_callback_info info)
314 {
315 HILOG_DEBUG("NAPI_IsOperationAllowed in");
316 auto context = std::make_shared<PermissionContextInfo>();
317 NapiWallpaperAbility::IsUserChangeAllowedInner(context);
318 Call call(env, info, context, 0, false);
319 return call.AsyncCall(env, "isOperationAllowed");
320 }
321
IsUserChangeAllowedInner(std::shared_ptr<PermissionContextInfo> context)322 void NapiWallpaperAbility::IsUserChangeAllowedInner(std::shared_ptr<PermissionContextInfo> context)
323 {
324 HILOG_DEBUG("IsUserChangeAllowedInner in");
325 auto output = [context](napi_env env, napi_value *result) -> napi_status {
326 napi_status status = napi_get_boolean(env, context->isOperationAllowed, result);
327 HILOG_DEBUG("output napi_get_boolean[%{public}d]", status);
328 return status;
329 };
330 auto exec = [context](Call::Context *ctx) {
331 HILOG_DEBUG("exec IsOperationAllowed");
332 context->isOperationAllowed = WallpaperMgrService::WallpaperManagerkits::GetInstance().IsOperationAllowed();
333 HILOG_DEBUG("exec IsOperationAllowed[%{public}d]", context->isOperationAllowed);
334 context->status = napi_ok;
335 };
336 context->SetAction(nullptr, std::move(output));
337 context->SetExecution(std::move(exec));
338 }
339
NAPI_Reset(napi_env env,napi_callback_info info)340 napi_value NAPI_Reset(napi_env env, napi_callback_info info)
341 {
342 HILOG_DEBUG("NAPI_Reset in");
343 auto context = std::make_shared<SetContextInfo>();
344 ApiInfo apiInfo{ false, false };
345 NapiWallpaperAbility::RestoreInner(context, apiInfo);
346 Call call(env, info, context, 1, apiInfo.needException);
347 return call.AsyncCall(env, "reset");
348 }
349
NAPI_Restore(napi_env env,napi_callback_info info)350 napi_value NAPI_Restore(napi_env env, napi_callback_info info)
351 {
352 HILOG_DEBUG("NAPI_Restore in");
353 auto context = std::make_shared<SetContextInfo>();
354 ApiInfo apiInfo{ true, true };
355 NapiWallpaperAbility::RestoreInner(context, apiInfo);
356 Call call(env, info, context, 1, apiInfo.needException);
357 return call.AsyncCall(env, "restore");
358 }
359
RestoreInner(std::shared_ptr<SetContextInfo> context,const ApiInfo & apiInfo)360 void NapiWallpaperAbility::RestoreInner(std::shared_ptr<SetContextInfo> context, const ApiInfo &apiInfo)
361 {
362 HILOG_DEBUG("RestoreInner in");
363 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
364 if (!NapiWallpaperAbility::IsValidArgCount(argc, 1) ||
365 !NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_number)) {
366 HILOG_DEBUG("input argc : %{public}zu", argc);
367 context->SetErrInfo(ErrorThrowType::PARAMETER_ERROR, PARAMETERERRORMESSAGE);
368 return napi_invalid_arg;
369 }
370 napi_get_value_int32(env, argv[0], &context->wallpaperType);
371 HILOG_DEBUG("input wallpaperType : %{public}d", context->wallpaperType);
372 return napi_pending_exception;
373 };
374 auto exec = [context, apiInfo](Call::Context *ctx) {
375 HILOG_DEBUG("exec ResetWallpaper");
376 ErrorCode wallpaperErrorCode =
377 WallpaperMgrService::WallpaperManagerkits::GetInstance().ResetWallpaper(context->wallpaperType, apiInfo);
378 HILOG_DEBUG("exec ResetWallpaper[%{public}d]", wallpaperErrorCode);
379 if (wallpaperErrorCode == E_OK) {
380 context->status = napi_ok;
381 }
382 if (apiInfo.needException) {
383 JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(wallpaperErrorCode);
384 if (jsErrorInfo.code != 0) {
385 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message);
386 }
387 }
388 HILOG_DEBUG("exec status[%{public}d], context->status[%{public}d]", wallpaperErrorCode, context->status);
389 };
390 context->SetAction(std::move(input), nullptr);
391 context->SetExecution(std::move(exec));
392 }
393
NAPI_SetWallpaper(napi_env env,napi_callback_info info)394 napi_value NAPI_SetWallpaper(napi_env env, napi_callback_info info)
395 {
396 auto context = std::make_shared<SetContextInfo>();
397 ApiInfo apiInfo{ false, false };
398 NapiWallpaperAbility::SetImageInput(context);
399 NapiWallpaperAbility::SetImageExec(context, apiInfo);
400 Call call(env, info, context, TWO, apiInfo.needException);
401 return call.AsyncCall(env, "setWallpaper");
402 }
403
NAPI_SetImage(napi_env env,napi_callback_info info)404 napi_value NAPI_SetImage(napi_env env, napi_callback_info info)
405 {
406 auto context = std::make_shared<SetContextInfo>();
407 ApiInfo apiInfo{ true, true };
408 NapiWallpaperAbility::SetImageInput(context);
409 NapiWallpaperAbility::SetImageExec(context, apiInfo);
410 Call call(env, info, context, TWO, apiInfo.needException);
411 return call.AsyncCall(env, "setImage");
412 }
413
NAPI_SendEvent(napi_env env,napi_callback_info info)414 napi_value NAPI_SendEvent(napi_env env, napi_callback_info info)
415 {
416 auto context = std::make_shared<GetContextInfo>();
417 NapiWallpaperAbility::SendEventInner(context);
418 Call call(env, info, context, TWO, true);
419 return call.AsyncCall(env);
420 }
421
SendEventInner(std::shared_ptr<GetContextInfo> context)422 void NapiWallpaperAbility::SendEventInner(std::shared_ptr<GetContextInfo> context)
423 {
424 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
425 if (!NapiWallpaperAbility::IsValidArgCount(argc, TWO) ||
426 !NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_string) ||
427 !NapiWallpaperAbility::IsValidArgType(env, argv[1], napi_string)) {
428 HILOG_ERROR("Input argc: %{public}zu", argc);
429 context->SetErrInfo(ErrorThrowType::PARAMETER_ERROR, PARAMETERERRORMESSAGE);
430 return napi_invalid_arg;
431 }
432 char eventType[EVENTTYPESIZE] = { 0 };
433 size_t bufSize = BUFFERSIZE;
434 size_t len = 0;
435 napi_get_value_string_utf8(env, argv[0], eventType, bufSize, &len);
436 context->eventType = eventType;
437 HILOG_DEBUG("Input event type: %{public}s", context->eventType.c_str());
438 return napi_ok;
439 };
440
441 auto output = [context](napi_env env, napi_value *result) -> napi_status {
442 napi_status status = napi_get_boolean(env, context->result, result);
443 HILOG_DEBUG("Output status: %{public}d", status);
444 return status;
445 };
446
447 auto exec = [context](Call::Context *ctx) {
448 ErrorCode wallpaperErrorCode =
449 WallpaperMgrService::WallpaperManagerkits::GetInstance().SendEvent(context->eventType);
450 if (wallpaperErrorCode == E_OK) {
451 context->status = napi_ok;
452 context->result = true;
453 } else {
454 JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(wallpaperErrorCode);
455 if (jsErrorInfo.code != 0) {
456 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message);
457 }
458 }
459 HILOG_DEBUG("Exec context status: [%{public}d]", context->status);
460 };
461 context->SetAction(std::move(input), std::move(output));
462 context->SetExecution(std::move(exec));
463 }
464
NAPI_SetVideo(napi_env env,napi_callback_info info)465 napi_value NAPI_SetVideo(napi_env env, napi_callback_info info)
466 {
467 auto context = std::make_shared<SetContextInfo>();
468 NapiWallpaperAbility::SetVideoInner(context);
469 Call call(env, info, context, TWO, true);
470 return call.AsyncCall(env);
471 }
472
SetVideoInner(std::shared_ptr<SetContextInfo> context)473 void NapiWallpaperAbility::SetVideoInner(std::shared_ptr<SetContextInfo> context)
474 {
475 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
476 if (!NapiWallpaperAbility::IsValidArgCount(argc, TWO) ||
477 !NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_string) ||
478 !NapiWallpaperAbility::IsValidArgType(env, argv[1], napi_number)) {
479 HILOG_ERROR("Input argc: %{public}zu", argc);
480 context->SetErrInfo(ErrorThrowType::PARAMETER_ERROR, PARAMETERERRORMESSAGE);
481 return napi_invalid_arg;
482 }
483 context->uri = WallpaperJSUtil::Convert2String(env, argv[0]);
484 napi_get_value_int32(env, argv[1], &context->wallpaperType);
485 HILOG_DEBUG("Input wallpaperType: %{public}d", context->wallpaperType);
486 return napi_ok;
487 };
488
489 auto exec = [context](Call::Context *ctx) {
490 ErrorCode wallpaperErrorCode =
491 WallpaperMgrService::WallpaperManagerkits::GetInstance().SetVideo(context->uri, context->wallpaperType);
492 if (wallpaperErrorCode == E_OK) {
493 context->status = napi_ok;
494 } else {
495 JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(wallpaperErrorCode);
496 if (jsErrorInfo.code != 0) {
497 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message);
498 }
499 }
500 HILOG_DEBUG("Exec context status:[%{public}d]", context->status);
501 };
502 context->SetAction(std::move(input), nullptr);
503 context->SetExecution(std::move(exec));
504 }
505
SetImageInput(std::shared_ptr<SetContextInfo> context)506 void NapiWallpaperAbility::SetImageInput(std::shared_ptr<SetContextInfo> context)
507 {
508 HILOG_DEBUG("SetImageInput in");
509 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
510 if (!NapiWallpaperAbility::IsValidArgCount(argc, TWO) ||
511 (!NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_string) &&
512 !NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_object)) ||
513 !NapiWallpaperAbility::IsValidArgType(env, argv[1], napi_number)) {
514 HILOG_DEBUG("input argc : %{public}zu", argc);
515 context->SetErrInfo(ErrorThrowType::PARAMETER_ERROR, PARAMETERERRORMESSAGE);
516 return napi_invalid_arg;
517 }
518 napi_valuetype valueType = napi_undefined;
519 napi_typeof(env, argv[0], &valueType);
520 if (valueType == napi_string) {
521 context->uri = WallpaperJSUtil::Convert2String(env, argv[0]);
522 } else {
523 std::shared_ptr<PixelMap> pixelMap = PixelMapNapi::GetPixelMap(env, argv[0]);
524 if (pixelMap == nullptr) {
525 HILOG_ERROR("PixelMapNapi::GetPixelMap error");
526 context->isPixelEmp = true;
527 return napi_generic_failure;
528 } else {
529 context->isPixelEmp = false;
530 }
531 context->pixelMap = pixelMap;
532 }
533 napi_get_value_int32(env, argv[1], &context->wallpaperType);
534 HILOG_DEBUG("input wallpaperType : %{public}d", context->wallpaperType);
535 return napi_ok;
536 };
537 context->SetAction(std::move(input), nullptr);
538 }
539
SetImageExec(std::shared_ptr<SetContextInfo> context,const ApiInfo & apiInfo)540 void NapiWallpaperAbility::SetImageExec(std::shared_ptr<SetContextInfo> context, const ApiInfo &apiInfo)
541 {
542 HILOG_DEBUG("SetImageExec in");
543 auto exec = [context, apiInfo](Call::Context *ctx) {
544 ErrorCode wallpaperErrorCode = E_UNKNOWN;
545 if (context->uri.length() == 0) {
546 HILOG_DEBUG("exec setWallpaper by pixelMap");
547 if (!context->isPixelEmp) {
548 wallpaperErrorCode =
549 WallpaperMgrService::WallpaperManagerkits::GetInstance().SetWallpaper(context->pixelMap,
550 context->wallpaperType, apiInfo);
551 }
552 } else {
553 HILOG_DEBUG("exec setWallpaper by uri");
554 wallpaperErrorCode = WallpaperMgrService::WallpaperManagerkits::GetInstance().SetWallpaper(context->uri,
555 context->wallpaperType, apiInfo);
556 }
557 if (wallpaperErrorCode == E_OK) {
558 context->status = napi_ok;
559 }
560 if (apiInfo.needException) {
561 JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(wallpaperErrorCode);
562 if (jsErrorInfo.code != 0) {
563 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message);
564 }
565 }
566 HILOG_DEBUG("exec context->status[%{public}d]", context->status);
567 };
568 context->SetExecution(std::move(exec));
569 }
570
NAPI_GetPixelMap(napi_env env,napi_callback_info info)571 napi_value NAPI_GetPixelMap(napi_env env, napi_callback_info info)
572 {
573 HILOG_DEBUG("NAPI_GetPixelMap in");
574 auto context = std::make_shared<GetContextInfo>();
575 ApiInfo apiInfo{ false, false };
576 NapiWallpaperAbility::GetImageInner(context, apiInfo);
577 Call call(env, info, context, 1, apiInfo.needException);
578 return call.AsyncCall(env, "getPixelMap");
579 }
580
NAPI_GetImage(napi_env env,napi_callback_info info)581 napi_value NAPI_GetImage(napi_env env, napi_callback_info info)
582 {
583 HILOG_DEBUG("NAPI_GetImage in");
584 auto context = std::make_shared<GetContextInfo>();
585 ApiInfo apiInfo{ true, true };
586 NapiWallpaperAbility::GetImageInner(context, apiInfo);
587 Call call(env, info, context, 1, apiInfo.needException);
588 return call.AsyncCall(env, "getImage");
589 }
590
GetImageInner(std::shared_ptr<GetContextInfo> context,const ApiInfo & apiInfo)591 void NapiWallpaperAbility::GetImageInner(std::shared_ptr<GetContextInfo> context, const ApiInfo &apiInfo)
592 {
593 HILOG_DEBUG("GetImageInner in");
594 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
595 if (!NapiWallpaperAbility::IsValidArgCount(argc, 1) ||
596 !NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_number)) {
597 HILOG_DEBUG("input argc : %{public}zu", argc);
598 context->SetErrInfo(ErrorThrowType::PARAMETER_ERROR, PARAMETERERRORMESSAGE);
599 return napi_invalid_arg;
600 }
601 napi_get_value_int32(env, argv[0], &context->wallpaperType);
602 HILOG_DEBUG("input wallpaperType : %{public}d", context->wallpaperType);
603 return napi_ok;
604 };
605 auto output = [context](napi_env env, napi_value *result) -> napi_status {
606 napi_value pixelVal =
607 (context->pixelMap != nullptr ? PixelMapNapi::CreatePixelMap(env, std::move(context->pixelMap)) : nullptr);
608 HILOG_DEBUG("output PixelMapNapi::CreatePixelMap != nullptr[%{public}d]", pixelVal != nullptr);
609 *result = pixelVal;
610 return napi_ok;
611 };
612 auto exec = [context, apiInfo](Call::Context *ctx) {
613 HILOG_DEBUG("exec GetImageInner");
614 std::shared_ptr<OHOS::Media::PixelMap> pixelMap;
615 ErrorCode wallpaperErrorCode =
616 WallpaperMgrService::WallpaperManagerkits::GetInstance().GetPixelMap(context->wallpaperType, apiInfo,
617 pixelMap);
618 HILOG_DEBUG("exec wallpaperErrorCode[%{public}d]", wallpaperErrorCode);
619 if (wallpaperErrorCode == E_OK) {
620 context->status = napi_ok;
621 context->pixelMap = (pixelMap != nullptr ? std::move(pixelMap) : nullptr);
622 return;
623 }
624 if (apiInfo.needException) {
625 JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(wallpaperErrorCode);
626 if (jsErrorInfo.code != 0) {
627 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message);
628 }
629 }
630 };
631 context->SetAction(std::move(input), std::move(output));
632 context->SetExecution(std::move(exec));
633 }
634
NAPI_On(napi_env env,napi_callback_info info)635 napi_value NAPI_On(napi_env env, napi_callback_info info)
636 {
637 HILOG_DEBUG("NAPI_On in");
638 size_t argc = TWO;
639 napi_value argv[TWO] = { nullptr };
640 napi_value thisVar = nullptr;
641 void *data = nullptr;
642 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
643 if (!NapiWallpaperAbility::IsValidArgCount(argc, TWO) ||
644 !NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_string) ||
645 !NapiWallpaperAbility::IsValidArgType(env, argv[1], napi_function)) {
646 HILOG_DEBUG("input argc : %{public}zu", argc);
647 if (NapiWallpaperAbility::IsValidArgCount(argc, 1) && // 1: argument count
648 NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_string) &&
649 WallpaperJSUtil::Convert2String(env, argv[0]) == COLOR_CHANGE_EVENT) {
650 return nullptr;
651 }
652 JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(E_PARAMETERS_INVALID);
653 JsError::ThrowError(env, jsErrorInfo.code, jsErrorInfo.message);
654 return nullptr;
655 }
656
657 std::string type = WallpaperJSUtil::Convert2String(env, argv[0]);
658 HILOG_DEBUG("type : %{public}s", type.c_str());
659 if (type != COLOR_CHANGE_EVENT && type != WALLPAPER_CHANGE_EVENT) {
660 HILOG_ERROR("do not support event type: %{public}s", type.c_str());
661 JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(E_PARAMETERS_INVALID);
662 JsError::ThrowError(env, jsErrorInfo.code, jsErrorInfo.message);
663 return nullptr;
664 }
665 std::shared_ptr<WallpaperMgrService::WallpaperEventListener> listener =
666 std::make_shared<NapiWallpaperAbility>(env, argv[1]);
667 ErrorCode errorCode = WallpaperMgrService::WallpaperManagerkits::GetInstance().On(type, listener);
668 if (errorCode != E_OK) {
669 HILOG_ERROR("WallpaperMgrService::WallpaperManagerkits::GetInstance().On failed!");
670 if (type == COLOR_CHANGE_EVENT) {
671 return nullptr;
672 }
673 JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(errorCode);
674 JsError::ThrowError(env, jsErrorInfo.code, jsErrorInfo.message);
675 return nullptr;
676 }
677 napi_value result = nullptr;
678 napi_get_undefined(env, &result);
679 return result;
680 }
681
NAPI_Off(napi_env env,napi_callback_info info)682 napi_value NAPI_Off(napi_env env, napi_callback_info info)
683 {
684 HILOG_DEBUG("NAPI_Off in");
685 size_t argc = 2;
686 napi_value argv[2] = { nullptr };
687 napi_value thisVar = nullptr;
688 void *data = nullptr;
689 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
690 if (!NapiWallpaperAbility::IsValidArgCount(argc, 1) || // 1: argument count
691 !NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_string)) {
692 HILOG_DEBUG("input argc : %{public}zu", argc);
693 JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(E_PARAMETERS_INVALID);
694 JsError::ThrowError(env, jsErrorInfo.code, jsErrorInfo.message);
695 return nullptr;
696 }
697
698 std::string type = WallpaperJSUtil::Convert2String(env, argv[0]);
699 HILOG_DEBUG("type : %{public}s", type.c_str());
700 if (type != COLOR_CHANGE_EVENT && type != WALLPAPER_CHANGE_EVENT) {
701 HILOG_ERROR("do not support event type: %{public}s", type.c_str());
702 JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(E_PARAMETERS_INVALID);
703 JsError::ThrowError(env, jsErrorInfo.code, jsErrorInfo.message);
704 return nullptr;
705 }
706 std::shared_ptr<WallpaperMgrService::WallpaperEventListener> listener = nullptr;
707 if (argc >= TWO) {
708 if (NapiWallpaperAbility::IsValidArgType(env, argv[1], napi_function)) {
709 listener = std::make_shared<NapiWallpaperAbility>(env, argv[1]);
710 }
711 }
712 ErrorCode errorCode = WallpaperMgrService::WallpaperManagerkits::GetInstance().Off(type, listener);
713 if (errorCode != E_OK) {
714 HILOG_ERROR("WallpaperMgrService::WallpaperManagerkits::GetInstance().Off failed!");
715 if (type == COLOR_CHANGE_EVENT) {
716 return nullptr;
717 }
718 JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(errorCode);
719 JsError::ThrowError(env, jsErrorInfo.code, jsErrorInfo.message);
720 return nullptr;
721 }
722 napi_value result = nullptr;
723 napi_get_undefined(env, &result);
724 return result;
725 }
726
NAPI_SetCustomWallpaper(napi_env env,napi_callback_info info)727 napi_value NAPI_SetCustomWallpaper(napi_env env, napi_callback_info info)
728 {
729 auto context = std::make_shared<SetContextInfo>();
730 NapiWallpaperAbility::SetCustomWallpaper(context);
731 Call call(env, info, context, TWO, true);
732 return call.AsyncCall(env);
733 }
734
SetCustomWallpaper(std::shared_ptr<SetContextInfo> context)735 void NapiWallpaperAbility::SetCustomWallpaper(std::shared_ptr<SetContextInfo> context)
736 {
737 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
738 if (argc < TWO || !NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_string) ||
739 !NapiWallpaperAbility::IsValidArgType(env, argv[1], napi_number)) {
740 HILOG_ERROR("Input argc: %{public}zu", argc);
741 context->SetErrInfo(ErrorThrowType::PARAMETER_ERROR, PARAMETERERRORMESSAGE);
742 return napi_invalid_arg;
743 }
744 context->uri = WallpaperJSUtil::Convert2String(env, argv[0]);
745 napi_get_value_int32(env, argv[1], &context->wallpaperType);
746 HILOG_DEBUG("Input wallpaperType: %{public}d", context->wallpaperType);
747 return napi_ok;
748 };
749
750 auto exec = [context](Call::Context *ctx) {
751 ErrorCode wallpaperErrorCode =
752 WallpaperMgrService::WallpaperManagerkits::GetInstance().SetCustomWallpaper(context->uri,
753 context->wallpaperType);
754 if (wallpaperErrorCode == E_OK) {
755 context->status = napi_ok;
756 } else {
757 JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(wallpaperErrorCode);
758 if (jsErrorInfo.code != 0) {
759 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message);
760 }
761 }
762 HILOG_DEBUG("Exec context status:[%{public}d]", context->status);
763 };
764 context->SetAction(std::move(input), nullptr);
765 context->SetExecution(std::move(exec));
766 }
767
NapiWallpaperAbility(napi_env env,napi_value callback)768 NapiWallpaperAbility::NapiWallpaperAbility(napi_env env, napi_value callback) : env_(env)
769 {
770 napi_create_reference(env, callback, 1, &callback_);
771 napi_get_uv_event_loop(env, &loop_);
772 }
773
~NapiWallpaperAbility()774 NapiWallpaperAbility::~NapiWallpaperAbility()
775 {
776 HILOG_ERROR("NapiWallpaperAbility::~NapiWallpaperAbility start!");
777 WorkData *workData = new (std::nothrow) WorkData(env_, callback_);
778 if (workData != nullptr) {
779 uv_after_work_cb afterCallback = [](uv_work_t *work, int status) {
780 WorkData *workData = reinterpret_cast<WorkData *>(work->data);
781 napi_delete_reference(workData->env_, workData->callback_);
782 delete workData;
783 delete work;
784 };
785 MiscServices::UvQueue::Call(env_, workData, afterCallback);
786 }
787 }
788
OnColorsChange(const std::vector<uint64_t> & color,int wallpaperType)789 void NapiWallpaperAbility::OnColorsChange(const std::vector<uint64_t> &color, int wallpaperType)
790 {
791 HILOG_ERROR("NapiWallpaperAbility::OnColorsChange start!");
792 WallpaperMgrService::WallpaperEventListener::OnColorsChange(color, wallpaperType);
793 EventDataWorker *eventDataWorker = new (std::nothrow)
794 EventDataWorker(this->shared_from_this(), color, wallpaperType);
795 if (eventDataWorker == nullptr) {
796 return;
797 }
798 uv_work_t *work = new (std::nothrow) uv_work_t;
799 if (work == nullptr) {
800 delete eventDataWorker;
801 return;
802 }
803 work->data = eventDataWorker;
804 uv_queue_work_with_qos(
805 loop_, work, [](uv_work_t *work) {},
806 [](uv_work_t *work, int status) {
807 EventDataWorker *eventDataInner = reinterpret_cast<EventDataWorker *>(work->data);
808 if (eventDataInner == nullptr || eventDataInner->listener == nullptr) {
809 delete work;
810 return;
811 }
812 napi_handle_scope scope = nullptr;
813 napi_open_handle_scope(eventDataInner->listener->env_, &scope);
814 if (scope == nullptr) {
815 delete eventDataInner;
816 delete work;
817 return;
818 }
819 napi_value jsWallpaperType = nullptr;
820 napi_create_int32(eventDataInner->listener->env_, eventDataInner->wallpaperType, &jsWallpaperType);
821 napi_value jsRgbaArray =
822 WallpaperJSUtil::Convert2JSRgbaArray(eventDataInner->listener->env_, eventDataInner->color);
823 napi_value callback = nullptr;
824 napi_value args[2] = { jsRgbaArray, jsWallpaperType };
825 napi_get_reference_value(eventDataInner->listener->env_, eventDataInner->listener->callback_, &callback);
826 napi_value global = nullptr;
827 napi_get_global(eventDataInner->listener->env_, &global);
828 napi_value result;
829 napi_status callStatus = napi_call_function(eventDataInner->listener->env_, global, callback,
830 sizeof(args) / sizeof(args[0]), args, &result);
831 if (callStatus != napi_ok) {
832 HILOG_ERROR("notify data change failed callStatus:%{public}d", callStatus);
833 }
834 napi_close_handle_scope(eventDataInner->listener->env_, scope);
835 delete eventDataInner;
836 delete work;
837 },
838 uv_qos_user_initiated);
839 }
840
OnWallpaperChange(WallpaperType wallpaperType,WallpaperResourceType resourceType,const std::string & uri)841 void NapiWallpaperAbility::OnWallpaperChange(WallpaperType wallpaperType, WallpaperResourceType resourceType,
842 const std::string &uri)
843 {
844 WallpaperChangedData *data = new (std::nothrow)
845 WallpaperChangedData(this->shared_from_this(), wallpaperType, resourceType, uri);
846 if (data == nullptr) {
847 return;
848 }
849 uv_work_t *work = new (std::nothrow) uv_work_t;
850 if (work == nullptr) {
851 delete data;
852 return;
853 }
854 work->data = data;
855 uv_queue_work_with_qos(
856 loop_, work, [](uv_work_t *work) {},
857 [](uv_work_t *work, int status) {
858 WallpaperChangedData *dataInner = reinterpret_cast<WallpaperChangedData *>(work->data);
859 if (dataInner == nullptr || dataInner->listener == nullptr) {
860 delete work;
861 return;
862 }
863 napi_handle_scope scope = nullptr;
864 napi_open_handle_scope(dataInner->listener->env_, &scope);
865 if (scope == nullptr) {
866 delete dataInner;
867 delete work;
868 return;
869 }
870 napi_value jsWallpaperType = nullptr;
871 napi_value jsResourceType = nullptr;
872 napi_value jsResourceUri = nullptr;
873 napi_create_int32(dataInner->listener->env_, dataInner->wallpaperType, &jsWallpaperType);
874 napi_create_int32(dataInner->listener->env_, dataInner->resourceType, &jsResourceType);
875 napi_create_string_utf8(dataInner->listener->env_, dataInner->uri.c_str(), dataInner->uri.length(),
876 &jsResourceUri);
877 napi_value callback = nullptr;
878 napi_value args[3] = { jsWallpaperType, jsResourceType, jsResourceUri };
879 napi_get_reference_value(dataInner->listener->env_, dataInner->listener->callback_, &callback);
880 napi_value global = nullptr;
881 napi_get_global(dataInner->listener->env_, &global);
882 napi_value result;
883 napi_status callStatus = napi_call_function(dataInner->listener->env_, global, callback,
884 sizeof(args) / sizeof(args[0]), args, &result);
885 if (callStatus != napi_ok) {
886 HILOG_ERROR("notify data change failed callStatus:%{public}d", callStatus);
887 }
888 napi_close_handle_scope(dataInner->listener->env_, scope);
889 delete dataInner;
890 delete work;
891 }, uv_qos_user_initiated);
892 }
893
IsValidArgCount(size_t argc,size_t expectationSize)894 bool NapiWallpaperAbility::IsValidArgCount(size_t argc, size_t expectationSize)
895 {
896 return argc >= expectationSize;
897 }
898
IsValidArgType(napi_env env,napi_value argValue,napi_valuetype expectationType)899 bool NapiWallpaperAbility::IsValidArgType(napi_env env, napi_value argValue, napi_valuetype expectationType)
900 {
901 napi_valuetype valueType = napi_undefined;
902 napi_typeof(env, argValue, &valueType);
903 return (valueType != expectationType) ? false : true;
904 }
905
IsValidArgRange(napi_env env,napi_value argValue)906 bool NapiWallpaperAbility::IsValidArgRange(napi_env env, napi_value argValue)
907 {
908 int wallpaperType;
909 napi_get_value_int32(env, argValue, &wallpaperType);
910 return (wallpaperType != WALLPAPER_LOCKSCREEN && wallpaperType != WALLPAPER_SYSTEM) ? false : true;
911 }
912
CheckValidArgWallpaperType(napi_env env,size_t argc,napi_value argValue,std::shared_ptr<Call::Context> ctx)913 bool NapiWallpaperAbility::CheckValidArgWallpaperType(napi_env env, size_t argc, napi_value argValue,
914 std::shared_ptr<Call::Context> ctx)
915 {
916 if (!NapiWallpaperAbility::IsValidArgCount(argc, ONE) ||
917 !NapiWallpaperAbility::IsValidArgType(env, argValue, napi_number) ||
918 !NapiWallpaperAbility::IsValidArgRange(env, argValue)) {
919 HILOG_DEBUG("input argc : %{public}zu", argc);
920 ctx->SetErrInfo(ErrorThrowType::PARAMETER_ERROR, PARAMETERERRORMESSAGE);
921 return false;
922 }
923 return true;
924 }
925 } // namespace WallpaperNAPI
926 } // namespace OHOS
927