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 <pthread.h>
19 #include <unistd.h>
20 #include <uv.h>
21
22 #include <map>
23 #include <string>
24 #include <vector>
25
26 #include "hilog_wrapper.h"
27 #include "js_error.h"
28 #include "uv_queue.h"
29 #include "wallpaper_manager.h"
30 #include "wallpaper_manager_common_info.h"
31 #include "wallpaper_common.h"
32
33 using namespace OHOS::Media;
34 namespace OHOS {
35 namespace WallpaperNAPI {
36 const int32_t ONE = 1;
37 const int32_t TWO = 2;
38
39 struct WorkData {
40 napi_env env_;
41 napi_ref callback_;
WorkDataOHOS::WallpaperNAPI::WorkData42 WorkData(napi_env env, napi_ref callback) : env_(env), callback_(callback)
43 {
44 }
45 };
46
NAPI_GetColors(napi_env env,napi_callback_info info)47 napi_value NAPI_GetColors(napi_env env, napi_callback_info info)
48 {
49 HILOG_DEBUG("NAPI_GetColors in");
50 auto context = std::make_shared<GetContextInfo>();
51 ApiInfo apiInfo{ false, false };
52 NapiWallpaperAbility::GetColorsInner(context);
53 AsyncCall asyncCall(env, info, std::dynamic_pointer_cast<AsyncCall::Context>(context), 1, apiInfo.needException);
54 return asyncCall.Call(env);
55 }
56
NAPI_GetColorsSync(napi_env env,napi_callback_info info)57 napi_value NAPI_GetColorsSync(napi_env env, napi_callback_info info)
58 {
59 HILOG_DEBUG("NAPI_GetColorsSync in");
60 auto context = std::make_shared<GetContextInfo>();
61 ApiInfo apiInfo{ true, true };
62 NapiWallpaperAbility::GetColorsInner(context);
63 AsyncCall asyncCall(env, info, context, 1, apiInfo.needException);
64 return asyncCall.SyncCall(env);
65 }
66
GetColorsInner(std::shared_ptr<GetContextInfo> context)67 void NapiWallpaperAbility::GetColorsInner(std::shared_ptr<GetContextInfo> context)
68 {
69 HILOG_DEBUG("GetColorsInner in");
70 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
71 if (!NapiWallpaperAbility::CheckValidArgWallpaperType(env, argc, argv[0], context)) {
72 return napi_invalid_arg;
73 }
74 napi_get_value_int32(env, argv[0], &context->wallpaperType);
75 HILOG_DEBUG("input wallpaperType : %{public}d", context->wallpaperType);
76 return napi_ok;
77 };
78 auto output = [context](napi_env env, napi_value *result) -> napi_status {
79 napi_value data = WallpaperJSUtil::Convert2JSRgbaArray(env, context->colors);
80 HILOG_DEBUG("output Convert2JSRgbaArray data != nullptr[%{public}d]", data != nullptr);
81 *result = data;
82 return napi_ok;
83 };
84 auto exec = [context](AsyncCall::Context *ctx) {
85 HILOG_DEBUG("exec GetColors");
86 context->colors = WallpaperMgrService::WallpaperManagerkits::GetInstance().GetColors(context->wallpaperType);
87 HILOG_DEBUG("exec GetColors colors size : %{public}zu", context->colors.size());
88 if (!context->colors.empty()) {
89 context->status = napi_ok;
90 }
91 HILOG_DEBUG("exec GetColors colors size : %{public}zu", context->colors.size());
92 };
93 context->SetAction(std::move(input), std::move(output));
94 context->SetExecution(std::move(exec));
95 }
96
NAPI_GetId(napi_env env,napi_callback_info info)97 napi_value NAPI_GetId(napi_env env, napi_callback_info info)
98 {
99 auto context = std::make_shared<GetContextInfo>();
100 ApiInfo apiInfo{ false, false };
101 NapiWallpaperAbility::GetIdInner(context);
102 AsyncCall asyncCall(env, info, context, 1, apiInfo.needException);
103 return asyncCall.Call(env);
104 }
105
NAPI_GetIdSync(napi_env env,napi_callback_info info)106 napi_value NAPI_GetIdSync(napi_env env, napi_callback_info info)
107 {
108 HILOG_DEBUG("NAPI_GetIdSync in");
109 auto context = std::make_shared<GetContextInfo>();
110 ApiInfo apiInfo{ true, true };
111 NapiWallpaperAbility::GetIdInner(context);
112 AsyncCall asyncCall(env, info, context, 1, apiInfo.needException);
113 return asyncCall.SyncCall(env);
114 }
115
GetIdInner(std::shared_ptr<GetContextInfo> context)116 void NapiWallpaperAbility::GetIdInner(std::shared_ptr<GetContextInfo> context)
117 {
118 HILOG_DEBUG("GetIdInner in");
119 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
120 if (!NapiWallpaperAbility::CheckValidArgWallpaperType(env, argc, argv[0], context)) {
121 return napi_invalid_arg;
122 }
123 napi_get_value_int32(env, argv[0], &context->wallpaperType);
124 HILOG_DEBUG("input wallpaperType : %{public}d", context->wallpaperType);
125 return napi_ok;
126 };
127 auto output = [context](napi_env env, napi_value *result) -> napi_status {
128 napi_status status = napi_create_int32(env, context->wallpaperId, result);
129 HILOG_DEBUG("output napi_create_int32[%{public}d]", status);
130 return status;
131 };
132 auto exec = [context](AsyncCall::Context *ctx) {
133 HILOG_DEBUG("exec GetWallpaperId");
134 context->wallpaperId =
135 WallpaperMgrService::WallpaperManagerkits::GetInstance().GetWallpaperId(context->wallpaperType);
136 HILOG_DEBUG("exec GetWallpaperId wallpaperId : %{public}d", context->wallpaperId);
137 context->status = napi_ok;
138 };
139 context->SetAction(std::move(input), std::move(output));
140 context->SetExecution(std::move(exec));
141 }
142
NAPI_GetFile(napi_env env,napi_callback_info info)143 napi_value NAPI_GetFile(napi_env env, napi_callback_info info)
144 {
145 HILOG_DEBUG("NAPI_GetFile in");
146 auto context = std::make_shared<GetFileContextInfo>();
147 ApiInfo apiInfo{ false, false };
148 NapiWallpaperAbility::GetFileInner(context, apiInfo);
149 AsyncCall asyncCall(env, info, context, 1, apiInfo.needException);
150 return asyncCall.Call(env);
151 }
152
NAPI_GetFileSync(napi_env env,napi_callback_info info)153 napi_value NAPI_GetFileSync(napi_env env, napi_callback_info info)
154 {
155 HILOG_DEBUG("NAPI_GetFileSync in");
156 auto context = std::make_shared<GetFileContextInfo>();
157 ApiInfo apiInfo{ true, true };
158 NapiWallpaperAbility::GetFileInner(context, apiInfo);
159 AsyncCall asyncCall(env, info, context, 1, apiInfo.needException);
160 return asyncCall.SyncCall(env);
161 }
162
GetFileInner(std::shared_ptr<GetFileContextInfo> context,const ApiInfo & apiInfo)163 void NapiWallpaperAbility::GetFileInner(std::shared_ptr<GetFileContextInfo> context, const ApiInfo &apiInfo)
164 {
165 HILOG_DEBUG("GetFileInner in");
166 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
167 if (!NapiWallpaperAbility::CheckValidArgWallpaperType(env, argc, argv[0], context)) {
168 return napi_invalid_arg;
169 }
170 napi_get_value_int32(env, argv[0], &context->wallpaperType);
171 HILOG_DEBUG("input wallpaperType : %{public}d", context->wallpaperType);
172 return napi_ok;
173 };
174
175 auto output = [context](napi_env env, napi_value *result) -> napi_status {
176 napi_value data = nullptr;
177 napi_create_int32(env, context->wallpaperFd, &data);
178 HILOG_DEBUG("output [%{public}d]", data != nullptr);
179 *result = data;
180 return napi_ok;
181 };
182 auto exec = [context, apiInfo](AsyncCall::Context *ctx) {
183 HILOG_DEBUG("exec GetFile");
184 int32_t wallpaperErrorCode =
185 WallpaperMgrService::WallpaperManagerkits::GetInstance().GetFile(context->wallpaperType,
186 context->wallpaperFd);
187 if (wallpaperErrorCode == static_cast<int32_t>(E_OK) && context->wallpaperFd >= 0) {
188 context->status = napi_ok;
189 return;
190 }
191 if (apiInfo.needException) {
192 JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(wallpaperErrorCode);
193 if (jsErrorInfo.code != 0) {
194 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message);
195 }
196 }
197 HILOG_DEBUG("exec GetFile fd: %{public}d", context->wallpaperFd);
198 };
199 context->SetAction(std::move(input), std::move(output));
200 context->SetExecution(std::move(exec));
201 }
202
NAPI_GetMinHeight(napi_env env,napi_callback_info info)203 napi_value NAPI_GetMinHeight(napi_env env, napi_callback_info info)
204 {
205 HILOG_DEBUG("NAPI_GetMinHeight in");
206 auto context = std::make_shared<GetMinContextInfo>();
207 ApiInfo apiInfo{ false, false };
208 NapiWallpaperAbility::GetMinHeightInner(context);
209 AsyncCall asyncCall(env, info, context, 0, apiInfo.needException);
210 return asyncCall.Call(env);
211 }
212
NAPI_GetMinHeightSync(napi_env env,napi_callback_info info)213 napi_value NAPI_GetMinHeightSync(napi_env env, napi_callback_info info)
214 {
215 HILOG_DEBUG("NAPI_GetMinHeightSync in");
216 auto context = std::make_shared<GetMinContextInfo>();
217 ApiInfo apiInfo{ true, true };
218 NapiWallpaperAbility::GetMinHeightInner(context);
219 AsyncCall asyncCall(env, info, context, 0, apiInfo.needException);
220 return asyncCall.SyncCall(env);
221 }
222
GetMinHeightInner(std::shared_ptr<GetMinContextInfo> context)223 void NapiWallpaperAbility::GetMinHeightInner(std::shared_ptr<GetMinContextInfo> context)
224 {
225 HILOG_DEBUG("GetMinHeightInner in");
226 auto output = [context](napi_env env, napi_value *result) -> napi_status {
227 napi_status status = napi_create_int32(env, context->minHeight, result);
228 HILOG_DEBUG("output napi_create_int32[%{public}d]", status);
229 return status;
230 };
231 auto exec = [context](AsyncCall::Context *ctx) {
232 HILOG_DEBUG("exec GetWallpaperMinHeight");
233 context->minHeight = WallpaperMgrService::WallpaperManagerkits::GetInstance().GetWallpaperMinHeight();
234 HILOG_DEBUG("exec GetWallpaperMinHeight minHeight : %{public}d", context->minHeight);
235 if (context->minHeight >= 0) {
236 context->status = napi_ok;
237 }
238 };
239 context->SetAction(nullptr, std::move(output));
240 context->SetExecution(std::move(exec));
241 }
242
NAPI_GetMinWidth(napi_env env,napi_callback_info info)243 napi_value NAPI_GetMinWidth(napi_env env, napi_callback_info info)
244 {
245 HILOG_DEBUG("NAPI_GetMinWidth in");
246 auto context = std::make_shared<GetMinContextInfo>();
247 ApiInfo apiInfo{ false, false };
248 NapiWallpaperAbility::GetMinWidthInner(context);
249 AsyncCall asyncCall(env, info, context, 0, apiInfo.needException);
250 return asyncCall.Call(env);
251 }
252
NAPI_GetMinWidthSync(napi_env env,napi_callback_info info)253 napi_value NAPI_GetMinWidthSync(napi_env env, napi_callback_info info)
254 {
255 HILOG_DEBUG("NAPI_GetMinWidthSync in");
256 auto context = std::make_shared<GetMinContextInfo>();
257 ApiInfo apiInfo{ true, true };
258 NapiWallpaperAbility::GetMinWidthInner(context);
259 AsyncCall asyncCall(env, info, context, 0, apiInfo.needException);
260 return asyncCall.SyncCall(env);
261 }
262
GetMinWidthInner(std::shared_ptr<GetMinContextInfo> context)263 void NapiWallpaperAbility::GetMinWidthInner(std::shared_ptr<GetMinContextInfo> context)
264 {
265 HILOG_DEBUG("GetMinWidthInner in");
266 auto output = [context](napi_env env, napi_value *result) -> napi_status {
267 napi_status status = napi_create_int32(env, context->minWidth, result);
268 HILOG_DEBUG("output napi_create_int32[%{public}d]", status);
269 return status;
270 };
271 auto exec = [context](AsyncCall::Context *ctx) {
272 HILOG_DEBUG("exec GetWallpaperMinWidth");
273 context->minWidth = WallpaperMgrService::WallpaperManagerkits::GetInstance().GetWallpaperMinWidth();
274 HILOG_DEBUG("exec GetWallpaperMinWidth minWidth : %{public}d", context->minWidth);
275 if (context->minWidth >= 0) {
276 context->status = napi_ok;
277 }
278 };
279 context->SetAction(nullptr, std::move(output));
280 context->SetExecution(std::move(exec));
281 }
282
NAPI_IsChangePermitted(napi_env env,napi_callback_info info)283 napi_value NAPI_IsChangePermitted(napi_env env, napi_callback_info info)
284 {
285 HILOG_DEBUG("NAPI_IsChangePermitted in");
286 auto context = std::make_shared<PermissionContextInfo>();
287 ApiInfo apiInfo{ false, false };
288 NapiWallpaperAbility::IsChangeAllowedInner(context);
289 AsyncCall asyncCall(env, info, context, 0, apiInfo.needException);
290 return asyncCall.Call(env);
291 }
292
NAPI_IsChangeAllowed(napi_env env,napi_callback_info info)293 napi_value NAPI_IsChangeAllowed(napi_env env, napi_callback_info info)
294 {
295 HILOG_DEBUG("NAPI_IsChangeAllowed in");
296 auto context = std::make_shared<PermissionContextInfo>();
297 ApiInfo apiInfo{ true, true };
298 NapiWallpaperAbility::IsChangeAllowedInner(context);
299 AsyncCall asyncCall(env, info, context, 0, apiInfo.needException);
300 return asyncCall.SyncCall(env);
301 }
302
IsChangeAllowedInner(std::shared_ptr<PermissionContextInfo> context)303 void NapiWallpaperAbility::IsChangeAllowedInner(std::shared_ptr<PermissionContextInfo> context)
304 {
305 HILOG_DEBUG("IsChangeAllowedInner in");
306 auto output = [context](napi_env env, napi_value *result) -> napi_status {
307 napi_status status = napi_get_boolean(env, context->isChangePermitted, result);
308 HILOG_DEBUG("output napi_get_boolean[%{public}d]", status);
309 return status;
310 };
311 auto exec = [context](AsyncCall::Context *ctx) {
312 HILOG_DEBUG("exec IsChangePermitted");
313 context->isChangePermitted = WallpaperMgrService::WallpaperManagerkits::GetInstance().IsChangePermitted();
314 HILOG_DEBUG("exec IsChangePermitted : %{public}d", context->isChangePermitted);
315 context->status = napi_ok;
316 };
317 context->SetAction(nullptr, std::move(output));
318 context->SetExecution(std::move(exec));
319 }
320
NAPI_IsOperationAllowed(napi_env env,napi_callback_info info)321 napi_value NAPI_IsOperationAllowed(napi_env env, napi_callback_info info)
322 {
323 HILOG_DEBUG("NAPI_IsOperationAllowed in");
324 auto context = std::make_shared<PermissionContextInfo>();
325 ApiInfo apiInfo{ false, false };
326 NapiWallpaperAbility::IsUserChangeAllowedInner(context);
327 AsyncCall asyncCall(env, info, context, 0, apiInfo.needException);
328 return asyncCall.Call(env);
329 }
330
NAPI_IsUserChangeAllowed(napi_env env,napi_callback_info info)331 napi_value NAPI_IsUserChangeAllowed(napi_env env, napi_callback_info info)
332 {
333 HILOG_DEBUG("NAPI_IsUserChangeAllowed in");
334 auto context = std::make_shared<PermissionContextInfo>();
335 ApiInfo apiInfo{ true, true };
336 NapiWallpaperAbility::IsUserChangeAllowedInner(context);
337 AsyncCall asyncCall(env, info, context, 0, apiInfo.needException);
338 return asyncCall.SyncCall(env);
339 }
340
IsUserChangeAllowedInner(std::shared_ptr<PermissionContextInfo> context)341 void NapiWallpaperAbility::IsUserChangeAllowedInner(std::shared_ptr<PermissionContextInfo> context)
342 {
343 HILOG_DEBUG("IsUserChangeAllowedInner in");
344 auto output = [context](napi_env env, napi_value *result) -> napi_status {
345 napi_status status = napi_get_boolean(env, context->isOperationAllowed, result);
346 HILOG_DEBUG("output napi_get_boolean[%{public}d]", status);
347 return status;
348 };
349 auto exec = [context](AsyncCall::Context *ctx) {
350 HILOG_DEBUG("exec IsOperationAllowed");
351 context->isOperationAllowed = WallpaperMgrService::WallpaperManagerkits::GetInstance().IsOperationAllowed();
352 HILOG_DEBUG("exec IsOperationAllowed[%{public}d]", context->isOperationAllowed);
353 context->status = napi_ok;
354 };
355 context->SetAction(nullptr, std::move(output));
356 context->SetExecution(std::move(exec));
357 }
358
NAPI_Reset(napi_env env,napi_callback_info info)359 napi_value NAPI_Reset(napi_env env, napi_callback_info info)
360 {
361 HILOG_DEBUG("NAPI_Reset in");
362 auto context = std::make_shared<SetContextInfo>();
363 ApiInfo apiInfo{ false, false };
364 NapiWallpaperAbility::RestoreInner(context, apiInfo);
365 AsyncCall asyncCall(env, info, context, 1, apiInfo.needException);
366 return asyncCall.Call(env);
367 }
368
NAPI_Restore(napi_env env,napi_callback_info info)369 napi_value NAPI_Restore(napi_env env, napi_callback_info info)
370 {
371 HILOG_DEBUG("NAPI_Rrestore in");
372 auto context = std::make_shared<SetContextInfo>();
373 ApiInfo apiInfo{ true, true };
374 NapiWallpaperAbility::RestoreInner(context, apiInfo);
375 AsyncCall asyncCall(env, info, context, 1, apiInfo.needException);
376 return asyncCall.Call(env);
377 }
378
RestoreInner(std::shared_ptr<SetContextInfo> context,const ApiInfo & apiInfo)379 void NapiWallpaperAbility::RestoreInner(std::shared_ptr<SetContextInfo> context, const ApiInfo &apiInfo)
380 {
381 HILOG_DEBUG("RestoreInner in");
382 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
383 if (!NapiWallpaperAbility::IsValidArgCount(argc, 1)
384 || !NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_number)) {
385 HILOG_DEBUG("input argc : %{public}zu", argc);
386 context->SetErrInfo(ErrorThrowType::PARAMETER_ERROR, PARAMETERERRORMESSAGE);
387 return napi_invalid_arg;
388 }
389 napi_get_value_int32(env, argv[0], &context->wallpaperType);
390 HILOG_DEBUG("input wallpaperType : %{public}d", context->wallpaperType);
391 return napi_pending_exception;
392 };
393 auto exec = [context, apiInfo](AsyncCall::Context *ctx) {
394 HILOG_DEBUG("exec ResetWallpaper");
395 int32_t wallpaperErrorCode =
396 WallpaperMgrService::WallpaperManagerkits::GetInstance().ResetWallpaper(context->wallpaperType);
397 HILOG_DEBUG("exec ResetWallpaper[%{public}d]", wallpaperErrorCode);
398 if (wallpaperErrorCode == static_cast<int32_t>(E_OK)) {
399 context->status = napi_ok;
400 }
401 if (apiInfo.needException) {
402 JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(wallpaperErrorCode);
403 if (jsErrorInfo.code != 0) {
404 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message);
405 }
406 }
407 HILOG_DEBUG("exec status[%{public}d], context->status[%{public}d]", wallpaperErrorCode, context->status);
408 };
409 context->SetAction(std::move(input), nullptr);
410 context->SetExecution(std::move(exec));
411 }
412
NAPI_SetWallpaper(napi_env env,napi_callback_info info)413 napi_value NAPI_SetWallpaper(napi_env env, napi_callback_info info)
414 {
415 auto context = std::make_shared<SetContextInfo>();
416 ApiInfo apiInfo{ false, false };
417 NapiWallpaperAbility::SetImageInput(context);
418 NapiWallpaperAbility::SetImageExec(context, apiInfo);
419 AsyncCall asyncCall(env, info, context, TWO, apiInfo.needException);
420 return asyncCall.Call(env);
421 }
422
NAPI_SetImage(napi_env env,napi_callback_info info)423 napi_value NAPI_SetImage(napi_env env, napi_callback_info info)
424 {
425 auto context = std::make_shared<SetContextInfo>();
426 ApiInfo apiInfo{ true, true };
427 NapiWallpaperAbility::SetImageInput(context);
428 NapiWallpaperAbility::SetImageExec(context, apiInfo);
429 AsyncCall asyncCall(env, info, context, TWO, apiInfo.needException);
430 return asyncCall.Call(env);
431 }
432
SetImageInput(std::shared_ptr<SetContextInfo> context)433 void NapiWallpaperAbility::SetImageInput(std::shared_ptr<SetContextInfo> context)
434 {
435 HILOG_DEBUG("SetImageInput in");
436 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
437 if (!NapiWallpaperAbility::IsValidArgCount(argc, TWO)
438 || (!NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_string)
439 && !NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_object))
440 || !NapiWallpaperAbility::IsValidArgType(env, argv[1], napi_number)) {
441 HILOG_DEBUG("input argc : %{public}zu", argc);
442 context->SetErrInfo(ErrorThrowType::PARAMETER_ERROR, PARAMETERERRORMESSAGE);
443 return napi_invalid_arg;
444 }
445 napi_valuetype valueType = napi_undefined;
446 napi_typeof(env, argv[0], &valueType);
447 if (valueType == napi_string) {
448 context->url = WallpaperJSUtil::Convert2String(env, argv[0]);
449 } else {
450 std::shared_ptr<PixelMap> pixelMap = PixelMapNapi::GetPixelMap(env, argv[0]);
451 if (pixelMap == nullptr) {
452 HILOG_ERROR("PixelMapNapi::GetPixelMap error");
453 context->isPixelEmp = true;
454 return napi_generic_failure;
455 } else {
456 context->isPixelEmp = false;
457 }
458 context->pixelMap = pixelMap;
459 }
460 napi_get_value_int32(env, argv[1], &context->wallpaperType);
461 HILOG_DEBUG("input wallpaperType : %{public}d", context->wallpaperType);
462 return napi_ok;
463 };
464 context->SetAction(std::move(input), nullptr);
465 }
466
SetImageExec(std::shared_ptr<SetContextInfo> context,const ApiInfo & apiInfo)467 void NapiWallpaperAbility::SetImageExec(std::shared_ptr<SetContextInfo> context, const ApiInfo &apiInfo)
468 {
469 HILOG_DEBUG("SetImageExec in");
470 auto exec = [context, apiInfo](AsyncCall::Context *ctx) {
471 int32_t wallpaperErrorCode = 0;
472 if (context->url.length() == 0) {
473 HILOG_DEBUG("exec setWallpaper by pixelMap");
474 if (!context->isPixelEmp) {
475 wallpaperErrorCode =
476 WallpaperMgrService::WallpaperManagerkits::GetInstance().SetWallpaper(context->pixelMap,
477 context->wallpaperType);
478 }
479 } else {
480 HILOG_DEBUG("exec setWallpaper by url");
481 wallpaperErrorCode = WallpaperMgrService::WallpaperManagerkits::GetInstance().SetWallpaper(context->url,
482 context->wallpaperType);
483 }
484 if (wallpaperErrorCode == static_cast<int32_t>(WallpaperMgrService::E_OK)) {
485 context->status = napi_ok;
486 }
487 if (apiInfo.needException) {
488 JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(wallpaperErrorCode);
489 if (jsErrorInfo.code != 0) {
490 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message);
491 }
492 }
493 HILOG_DEBUG("exec context->status[%{public}d]", context->status);
494 };
495 context->SetExecution(std::move(exec));
496 }
497
NAPI_GetPixelMap(napi_env env,napi_callback_info info)498 napi_value NAPI_GetPixelMap(napi_env env, napi_callback_info info)
499 {
500 HILOG_DEBUG("NAPI_GetPixelMap in");
501 auto context = std::make_shared<GetContextInfo>();
502 ApiInfo apiInfo{ false, false };
503 NapiWallpaperAbility::GetImageInner(context, apiInfo);
504 AsyncCall asyncCall(env, info, context, 1, apiInfo.needException);
505 return asyncCall.Call(env);
506 }
507
NAPI_GetImage(napi_env env,napi_callback_info info)508 napi_value NAPI_GetImage(napi_env env, napi_callback_info info)
509 {
510 HILOG_DEBUG("NAPI_GetImage in");
511 auto context = std::make_shared<GetContextInfo>();
512 ApiInfo apiInfo{ true, true };
513 NapiWallpaperAbility::GetImageInner(context, apiInfo);
514 AsyncCall asyncCall(env, info, context, 1, apiInfo.needException);
515 return asyncCall.Call(env);
516 }
517
GetImageInner(std::shared_ptr<GetContextInfo> context,const ApiInfo & apiInfo)518 void NapiWallpaperAbility::GetImageInner(std::shared_ptr<GetContextInfo> context, const ApiInfo &apiInfo)
519 {
520 HILOG_DEBUG("GetImageInner in");
521 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
522 if (!NapiWallpaperAbility::IsValidArgCount(argc, 1)
523 || !NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_number)) {
524 HILOG_DEBUG("input argc : %{public}zu", argc);
525 context->SetErrInfo(ErrorThrowType::PARAMETER_ERROR, PARAMETERERRORMESSAGE);
526 return napi_invalid_arg;
527 }
528 napi_get_value_int32(env, argv[0], &context->wallpaperType);
529 HILOG_DEBUG("input wallpaperType : %{public}d", context->wallpaperType);
530 return napi_ok;
531 };
532 auto output = [context](napi_env env, napi_value *result) -> napi_status {
533 napi_value pixelVal = PixelMapNapi::CreatePixelMap(env, std::move(context->pixelMap));
534 HILOG_DEBUG("output PixelMapNapi::CreatePixelMap != nullptr[%{public}d]", pixelVal != nullptr);
535 *result = pixelVal;
536 return napi_ok;
537 };
538 auto exec = [context, apiInfo](AsyncCall::Context *ctx) {
539 HILOG_DEBUG("exec GetImageInner");
540 std::shared_ptr<OHOS::Media::PixelMap> pixelMap;
541 int32_t wallpaperErrorCode =
542 WallpaperMgrService::WallpaperManagerkits::GetInstance().GetPixelMap(context->wallpaperType, pixelMap);
543 HILOG_DEBUG("exec wallpaperErrorCode[%{public}d]", wallpaperErrorCode);
544 if (wallpaperErrorCode == static_cast<int32_t>(E_OK) && pixelMap != nullptr) {
545 context->status = napi_ok;
546 context->pixelMap = std::move(pixelMap);
547 return;
548 }
549 if (apiInfo.needException) {
550 JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(wallpaperErrorCode);
551 if (jsErrorInfo.code != 0) {
552 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message);
553 }
554 }
555 };
556 context->SetAction(std::move(input), std::move(output));
557 context->SetExecution(std::move(exec));
558 }
559
NAPI_On(napi_env env,napi_callback_info info)560 napi_value NAPI_On(napi_env env, napi_callback_info info)
561 {
562 HILOG_DEBUG("NAPI_On in");
563 size_t argc = TWO;
564 napi_value argv[TWO] = { nullptr };
565 napi_value thisVar = nullptr;
566 void *data = nullptr;
567 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
568 if (!NapiWallpaperAbility::IsValidArgCount(argc, TWO)
569 || !NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_string)
570 || !NapiWallpaperAbility::IsValidArgType(env, argv[1], napi_function)) {
571 HILOG_DEBUG("input argc : %{public}zu", argc);
572 JsError::ThrowError(env, ErrorThrowType::PARAMETER_ERROR, PARAMETERERRORMESSAGE);
573 return nullptr;
574 }
575 std::string type = WallpaperJSUtil::Convert2String(env, argv[0]);
576 HILOG_DEBUG("type : %{public}s", type.c_str());
577
578 std::shared_ptr<WallpaperMgrService::WallpaperColorChangeListener> listener =
579 std::make_shared<NapiWallpaperAbility>(env, argv[1]);
580
581 bool status = WallpaperMgrService::WallpaperManagerkits::GetInstance().On(type, listener);
582 if (!status) {
583 HILOG_ERROR("WallpaperMgrService::WallpaperManagerkits::GetInstance().On failed!");
584 return nullptr;
585 }
586
587 napi_value result = nullptr;
588 napi_get_undefined(env, &result);
589 return result;
590 }
591
NAPI_Off(napi_env env,napi_callback_info info)592 napi_value NAPI_Off(napi_env env, napi_callback_info info)
593 {
594 HILOG_DEBUG("NAPI_Off in");
595 size_t argc = 2;
596 napi_value argv[2] = { nullptr };
597 napi_value thisVar = nullptr;
598 void *data = nullptr;
599 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
600 if (!NapiWallpaperAbility::IsValidArgCount(argc, ONE)
601 || !NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_string)) {
602 HILOG_DEBUG("input argc : %{public}zu", argc);
603 JsError::ThrowError(env, ErrorThrowType::PARAMETER_ERROR, PARAMETERERRORMESSAGE);
604 return nullptr;
605 }
606 std::string type = WallpaperJSUtil::Convert2String(env, argv[0]);
607 HILOG_DEBUG("type : %{public}s", type.c_str());
608
609 std::shared_ptr<WallpaperMgrService::WallpaperColorChangeListener> listener = nullptr;
610 if (argc == TWO) {
611 if (!NapiWallpaperAbility::IsValidArgType(env, argv[1], napi_function)) {
612 JsError::ThrowError(env, ErrorThrowType::PARAMETER_ERROR, PARAMETERERRORMESSAGE);
613 return nullptr;
614 }
615 listener = std::make_shared<NapiWallpaperAbility>(env, argv[1]);
616 }
617
618 bool status = WallpaperMgrService::WallpaperManagerkits::GetInstance().Off(type, listener);
619 if (!status) {
620 HILOG_ERROR("WallpaperMgrService::WallpaperManagerkits::GetInstance().Off failed!");
621 return nullptr;
622 }
623
624 napi_value result = nullptr;
625 napi_get_undefined(env, &result);
626 return result;
627 }
628
NapiWallpaperAbility(napi_env env,napi_value callback)629 NapiWallpaperAbility::NapiWallpaperAbility(napi_env env, napi_value callback) : env_(env)
630 {
631 napi_create_reference(env, callback, 1, &callback_);
632 napi_get_uv_event_loop(env, &loop_);
633 }
634
~NapiWallpaperAbility()635 NapiWallpaperAbility::~NapiWallpaperAbility()
636 {
637 HILOG_ERROR("NapiWallpaperAbility::~NapiWallpaperAbility start!");
638 WorkData *workData = new (std::nothrow) WorkData(env_, callback_);
639 if (workData != nullptr) {
640 uv_after_work_cb afterCallback = [](uv_work_t *work, int status) {
641 WorkData *workData = reinterpret_cast<WorkData *>(work->data);
642 napi_delete_reference(workData->env_, workData->callback_);
643 delete workData;
644 delete work;
645 };
646 MiscServices::UvQueue::Call(env_, workData, afterCallback);
647 }
648 }
649
OnColorsChange(const std::vector<uint64_t> & color,int wallpaperType)650 void NapiWallpaperAbility::OnColorsChange(const std::vector<uint64_t> &color, int wallpaperType)
651 {
652 HILOG_ERROR("NapiWallpaperAbility::OnColorsChange start!");
653 WallpaperMgrService::WallpaperColorChangeListener::OnColorsChange(color, wallpaperType);
654 EventDataWorker *eventDataWorker = new (std::nothrow)
655 EventDataWorker(this->shared_from_this(), color, wallpaperType);
656 if (eventDataWorker == nullptr) {
657 return;
658 }
659 uv_work_t *work = new (std::nothrow) uv_work_t;
660 if (work == nullptr) {
661 delete eventDataWorker;
662 return;
663 }
664 work->data = eventDataWorker;
665 uv_queue_work(
666 loop_, work, [](uv_work_t *work) {},
667 [](uv_work_t *work, int status) {
668 EventDataWorker *eventDataInner = reinterpret_cast<EventDataWorker *>(work->data);
669 if (eventDataInner == nullptr || eventDataInner->listener == nullptr) {
670 delete work;
671 return;
672 }
673 napi_handle_scope scope = nullptr;
674 napi_open_handle_scope(eventDataInner->listener->env_, &scope);
675 if (scope == nullptr) {
676 delete eventDataInner;
677 delete work;
678 return;
679 }
680 napi_value jsWallpaperType = nullptr;
681 napi_create_int32(eventDataInner->listener->env_, eventDataInner->wallpaperType, &jsWallpaperType);
682 napi_value jsRgbaArray =
683 WallpaperJSUtil::Convert2JSRgbaArray(eventDataInner->listener->env_, eventDataInner->color);
684 napi_value callback = nullptr;
685 napi_value args[2] = { jsRgbaArray, jsWallpaperType };
686 napi_get_reference_value(eventDataInner->listener->env_, eventDataInner->listener->callback_, &callback);
687 napi_value global = nullptr;
688 napi_get_global(eventDataInner->listener->env_, &global);
689 napi_value result;
690 napi_status callStatus = napi_call_function(eventDataInner->listener->env_, global, callback,
691 sizeof(args) / sizeof(args[0]), args, &result);
692 if (callStatus != napi_ok) {
693 HILOG_ERROR("notify data change failed callStatus:%{public}d", callStatus);
694 }
695 napi_close_handle_scope(eventDataInner->listener->env_, scope);
696 delete eventDataInner;
697 delete work;
698 });
699 }
700
IsValidArgCount(size_t argc,size_t expectationSize)701 bool NapiWallpaperAbility::IsValidArgCount(size_t argc, size_t expectationSize)
702 {
703 return argc >= expectationSize;
704 }
705
IsValidArgType(napi_env env,napi_value argValue,napi_valuetype expectationType)706 bool NapiWallpaperAbility::IsValidArgType(napi_env env, napi_value argValue, napi_valuetype expectationType)
707 {
708 napi_valuetype valueType = napi_undefined;
709 napi_typeof(env, argValue, &valueType);
710 return (valueType != expectationType) ? false : true;
711 }
712
IsValidArgRange(napi_env env,napi_value argValue)713 bool NapiWallpaperAbility::IsValidArgRange(napi_env env, napi_value argValue)
714 {
715 int wallpaperType;
716 napi_get_value_int32(env, argValue, &wallpaperType);
717 return (wallpaperType != WALLPAPER_LOCKSCREEN && wallpaperType != WALLPAPER_SYSTEM) ? false : true;
718 }
719
CheckValidArgWallpaperType(napi_env env,size_t argc,napi_value argValue,std::shared_ptr<AsyncCall::Context> ctx)720 bool NapiWallpaperAbility::CheckValidArgWallpaperType(
721 napi_env env, size_t argc, napi_value argValue, std::shared_ptr<AsyncCall::Context> ctx)
722 {
723 if (!NapiWallpaperAbility::IsValidArgCount(argc, ONE)
724 || !NapiWallpaperAbility::IsValidArgType(env, argValue, napi_number)
725 || !NapiWallpaperAbility::IsValidArgRange(env, argValue)) {
726 HILOG_DEBUG("input argc : %{public}zu", argc);
727 ctx->SetErrInfo(ErrorThrowType::PARAMETER_ERROR, PARAMETERERRORMESSAGE);
728 return false;
729 }
730 return true;
731 }
732 } // namespace WallpaperNAPI
733 } // namespace OHOS