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_common.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, apiInfo);
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
62 ApiInfo apiInfo{ true, true };
63 NapiWallpaperAbility::GetColorsInner(context, apiInfo);
64 AsyncCall asyncCall(env, info, context, 1, apiInfo.needException);
65 return asyncCall.SyncCall(env);
66 }
67
GetColorsInner(std::shared_ptr<GetContextInfo> context,const ApiInfo & apiInfo)68 void NapiWallpaperAbility::GetColorsInner(std::shared_ptr<GetContextInfo> context, const ApiInfo &apiInfo)
69 {
70 HILOG_DEBUG("GetColorsInner in");
71 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
72 if (!NapiWallpaperAbility::CheckValidArgWallpaperType(env, argc, argv[0], context)) {
73 return napi_invalid_arg;
74 }
75 napi_get_value_int32(env, argv[0], &context->wallpaperType);
76 HILOG_DEBUG("input wallpaperType : %{public}d", context->wallpaperType);
77 return napi_ok;
78 };
79 auto output = [context](napi_env env, napi_value *result) -> napi_status {
80 napi_value data = WallpaperJSUtil::Convert2JSRgbaArray(env, context->colors);
81 HILOG_DEBUG("output Convert2JSRgbaArray data != nullptr[%{public}d]", data != nullptr);
82 *result = data;
83 return napi_ok;
84 };
85
86 auto exec = [context, apiInfo](AsyncCall::Context *ctx) {
87 HILOG_DEBUG("exec GetColors");
88 int32_t wallpaperErrorCode =
89 WallpaperMgrService::WallpaperManagerkits::GetInstance().GetColors(context->wallpaperType, apiInfo,
90 context->colors);
91 if (wallpaperErrorCode == static_cast<int32_t>(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 ApiInfo apiInfo{ false, false };
111 NapiWallpaperAbility::GetIdInner(context);
112 AsyncCall asyncCall(env, info, context, 1, apiInfo.needException);
113 return asyncCall.Call(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
GetFileInner(std::shared_ptr<GetFileContextInfo> context,const ApiInfo & apiInfo)153 void NapiWallpaperAbility::GetFileInner(std::shared_ptr<GetFileContextInfo> context, const ApiInfo &apiInfo)
154 {
155 HILOG_DEBUG("GetFileInner in");
156 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
157 if (!NapiWallpaperAbility::CheckValidArgWallpaperType(env, argc, argv[0], context)) {
158 return napi_invalid_arg;
159 }
160 napi_get_value_int32(env, argv[0], &context->wallpaperType);
161 HILOG_DEBUG("input wallpaperType : %{public}d", context->wallpaperType);
162 return napi_ok;
163 };
164
165 auto output = [context](napi_env env, napi_value *result) -> napi_status {
166 napi_value data = nullptr;
167 napi_create_int32(env, context->wallpaperFd, &data);
168 HILOG_DEBUG("output [%{public}d]", data != nullptr);
169 *result = data;
170 return napi_ok;
171 };
172 auto exec = [context, apiInfo](AsyncCall::Context *ctx) {
173 HILOG_DEBUG("exec GetFile");
174 int32_t wallpaperErrorCode =
175 WallpaperMgrService::WallpaperManagerkits::GetInstance().GetFile(context->wallpaperType,
176 context->wallpaperFd);
177 if (wallpaperErrorCode == static_cast<int32_t>(E_OK) && context->wallpaperFd >= 0) {
178 context->status = napi_ok;
179 return;
180 }
181 if (apiInfo.needException) {
182 JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(wallpaperErrorCode);
183 if (jsErrorInfo.code != 0) {
184 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message);
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 AsyncCall asyncCall(env, info, context, 0, apiInfo.needException);
200 return asyncCall.Call(env);
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 AsyncCall asyncCall(env, info, context, 0, apiInfo.needException);
210 return asyncCall.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](AsyncCall::Context *ctx) {
222 HILOG_DEBUG("exec GetWallpaperMinHeight");
223 int32_t wallpaperErrorCode =
224 WallpaperMgrService::WallpaperManagerkits::GetInstance().GetWallpaperMinHeight(apiInfo, context->minHeight);
225 if (wallpaperErrorCode == static_cast<int32_t>(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 AsyncCall asyncCall(env, info, context, 0, apiInfo.needException);
247 return asyncCall.Call(env);
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 AsyncCall asyncCall(env, info, context, 0, apiInfo.needException);
257 return asyncCall.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](AsyncCall::Context *ctx) {
269 HILOG_DEBUG("exec GetWallpaperMinWidth");
270 int32_t wallpaperErrorCode =
271 WallpaperMgrService::WallpaperManagerkits::GetInstance().GetWallpaperMinWidth(apiInfo, context->minWidth);
272 if (wallpaperErrorCode == static_cast<int32_t>(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 ApiInfo apiInfo{ false, false };
291 NapiWallpaperAbility::IsChangeAllowedInner(context);
292 AsyncCall asyncCall(env, info, context, 0, apiInfo.needException);
293 return asyncCall.Call(env);
294 }
295
IsChangeAllowedInner(std::shared_ptr<PermissionContextInfo> context)296 void NapiWallpaperAbility::IsChangeAllowedInner(std::shared_ptr<PermissionContextInfo> context)
297 {
298 HILOG_DEBUG("IsChangeAllowedInner in");
299 auto output = [context](napi_env env, napi_value *result) -> napi_status {
300 napi_status status = napi_get_boolean(env, context->isChangePermitted, result);
301 HILOG_DEBUG("output napi_get_boolean[%{public}d]", status);
302 return status;
303 };
304 auto exec = [context](AsyncCall::Context *ctx) {
305 HILOG_DEBUG("exec IsChangePermitted");
306 context->isChangePermitted = WallpaperMgrService::WallpaperManagerkits::GetInstance().IsChangePermitted();
307 HILOG_DEBUG("exec IsChangePermitted : %{public}d", context->isChangePermitted);
308 context->status = napi_ok;
309 };
310 context->SetAction(nullptr, std::move(output));
311 context->SetExecution(std::move(exec));
312 }
313
NAPI_IsOperationAllowed(napi_env env,napi_callback_info info)314 napi_value NAPI_IsOperationAllowed(napi_env env, napi_callback_info info)
315 {
316 HILOG_DEBUG("NAPI_IsOperationAllowed in");
317 auto context = std::make_shared<PermissionContextInfo>();
318 ApiInfo apiInfo{ false, false };
319 NapiWallpaperAbility::IsUserChangeAllowedInner(context);
320 AsyncCall asyncCall(env, info, context, 0, apiInfo.needException);
321 return asyncCall.Call(env);
322 }
323
IsUserChangeAllowedInner(std::shared_ptr<PermissionContextInfo> context)324 void NapiWallpaperAbility::IsUserChangeAllowedInner(std::shared_ptr<PermissionContextInfo> context)
325 {
326 HILOG_DEBUG("IsUserChangeAllowedInner in");
327 auto output = [context](napi_env env, napi_value *result) -> napi_status {
328 napi_status status = napi_get_boolean(env, context->isOperationAllowed, result);
329 HILOG_DEBUG("output napi_get_boolean[%{public}d]", status);
330 return status;
331 };
332 auto exec = [context](AsyncCall::Context *ctx) {
333 HILOG_DEBUG("exec IsOperationAllowed");
334 context->isOperationAllowed = WallpaperMgrService::WallpaperManagerkits::GetInstance().IsOperationAllowed();
335 HILOG_DEBUG("exec IsOperationAllowed[%{public}d]", context->isOperationAllowed);
336 context->status = napi_ok;
337 };
338 context->SetAction(nullptr, std::move(output));
339 context->SetExecution(std::move(exec));
340 }
341
NAPI_Reset(napi_env env,napi_callback_info info)342 napi_value NAPI_Reset(napi_env env, napi_callback_info info)
343 {
344 HILOG_DEBUG("NAPI_Reset in");
345 auto context = std::make_shared<SetContextInfo>();
346 ApiInfo apiInfo{ false, false };
347 NapiWallpaperAbility::RestoreInner(context, apiInfo);
348 AsyncCall asyncCall(env, info, context, 1, apiInfo.needException);
349 return asyncCall.Call(env);
350 }
351
NAPI_Restore(napi_env env,napi_callback_info info)352 napi_value NAPI_Restore(napi_env env, napi_callback_info info)
353 {
354 HILOG_DEBUG("NAPI_Rrestore in");
355 auto context = std::make_shared<SetContextInfo>();
356 ApiInfo apiInfo{ true, true };
357 NapiWallpaperAbility::RestoreInner(context, apiInfo);
358 AsyncCall asyncCall(env, info, context, 1, apiInfo.needException);
359 return asyncCall.Call(env);
360 }
361
RestoreInner(std::shared_ptr<SetContextInfo> context,const ApiInfo & apiInfo)362 void NapiWallpaperAbility::RestoreInner(std::shared_ptr<SetContextInfo> context, const ApiInfo &apiInfo)
363 {
364 HILOG_DEBUG("RestoreInner in");
365 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
366 if (!NapiWallpaperAbility::IsValidArgCount(argc, 1)
367 || !NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_number)) {
368 HILOG_DEBUG("input argc : %{public}zu", argc);
369 context->SetErrInfo(ErrorThrowType::PARAMETER_ERROR, PARAMETERERRORMESSAGE);
370 return napi_invalid_arg;
371 }
372 napi_get_value_int32(env, argv[0], &context->wallpaperType);
373 HILOG_DEBUG("input wallpaperType : %{public}d", context->wallpaperType);
374 return napi_pending_exception;
375 };
376 auto exec = [context, apiInfo](AsyncCall::Context *ctx) {
377 HILOG_DEBUG("exec ResetWallpaper");
378 int32_t wallpaperErrorCode =
379 WallpaperMgrService::WallpaperManagerkits::GetInstance().ResetWallpaper(context->wallpaperType, apiInfo);
380 HILOG_DEBUG("exec ResetWallpaper[%{public}d]", wallpaperErrorCode);
381 if (wallpaperErrorCode == static_cast<int32_t>(E_OK)) {
382 context->status = napi_ok;
383 }
384 if (apiInfo.needException) {
385 JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(wallpaperErrorCode);
386 if (jsErrorInfo.code != 0) {
387 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message);
388 }
389 }
390 HILOG_DEBUG("exec status[%{public}d], context->status[%{public}d]", wallpaperErrorCode, context->status);
391 };
392 context->SetAction(std::move(input), nullptr);
393 context->SetExecution(std::move(exec));
394 }
395
NAPI_SetWallpaper(napi_env env,napi_callback_info info)396 napi_value NAPI_SetWallpaper(napi_env env, napi_callback_info info)
397 {
398 auto context = std::make_shared<SetContextInfo>();
399 ApiInfo apiInfo{ false, false };
400 NapiWallpaperAbility::SetImageInput(context);
401 NapiWallpaperAbility::SetImageExec(context, apiInfo);
402 AsyncCall asyncCall(env, info, context, TWO, apiInfo.needException);
403 return asyncCall.Call(env);
404 }
405
NAPI_SetImage(napi_env env,napi_callback_info info)406 napi_value NAPI_SetImage(napi_env env, napi_callback_info info)
407 {
408 auto context = std::make_shared<SetContextInfo>();
409 ApiInfo apiInfo{ true, true };
410 NapiWallpaperAbility::SetImageInput(context);
411 NapiWallpaperAbility::SetImageExec(context, apiInfo);
412 AsyncCall asyncCall(env, info, context, TWO, apiInfo.needException);
413 return asyncCall.Call(env);
414 }
415
SetImageInput(std::shared_ptr<SetContextInfo> context)416 void NapiWallpaperAbility::SetImageInput(std::shared_ptr<SetContextInfo> context)
417 {
418 HILOG_DEBUG("SetImageInput in");
419 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
420 if (!NapiWallpaperAbility::IsValidArgCount(argc, TWO)
421 || (!NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_string)
422 && !NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_object))
423 || !NapiWallpaperAbility::IsValidArgType(env, argv[1], napi_number)) {
424 HILOG_DEBUG("input argc : %{public}zu", argc);
425 context->SetErrInfo(ErrorThrowType::PARAMETER_ERROR, PARAMETERERRORMESSAGE);
426 return napi_invalid_arg;
427 }
428 napi_valuetype valueType = napi_undefined;
429 napi_typeof(env, argv[0], &valueType);
430 if (valueType == napi_string) {
431 context->url = WallpaperJSUtil::Convert2String(env, argv[0]);
432 } else {
433 std::shared_ptr<PixelMap> pixelMap = PixelMapNapi::GetPixelMap(env, argv[0]);
434 if (pixelMap == nullptr) {
435 HILOG_ERROR("PixelMapNapi::GetPixelMap error");
436 context->isPixelEmp = true;
437 return napi_generic_failure;
438 } else {
439 context->isPixelEmp = false;
440 }
441 context->pixelMap = pixelMap;
442 }
443 napi_get_value_int32(env, argv[1], &context->wallpaperType);
444 HILOG_DEBUG("input wallpaperType : %{public}d", context->wallpaperType);
445 return napi_ok;
446 };
447 context->SetAction(std::move(input), nullptr);
448 }
449
SetImageExec(std::shared_ptr<SetContextInfo> context,const ApiInfo & apiInfo)450 void NapiWallpaperAbility::SetImageExec(std::shared_ptr<SetContextInfo> context, const ApiInfo &apiInfo)
451 {
452 HILOG_DEBUG("SetImageExec in");
453 auto exec = [context, apiInfo](AsyncCall::Context *ctx) {
454 int32_t wallpaperErrorCode = 0;
455 if (context->url.length() == 0) {
456 HILOG_DEBUG("exec setWallpaper by pixelMap");
457 if (!context->isPixelEmp) {
458 wallpaperErrorCode =
459 WallpaperMgrService::WallpaperManagerkits::GetInstance().SetWallpaper(context->pixelMap,
460 context->wallpaperType, apiInfo);
461 }
462 } else {
463 HILOG_DEBUG("exec setWallpaper by url");
464 wallpaperErrorCode = WallpaperMgrService::WallpaperManagerkits::GetInstance().SetWallpaper(context->url,
465 context->wallpaperType, apiInfo);
466 }
467 if (wallpaperErrorCode == static_cast<int32_t>(WallpaperMgrService::E_OK)) {
468 context->status = napi_ok;
469 }
470 if (apiInfo.needException) {
471 JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(wallpaperErrorCode);
472 if (jsErrorInfo.code != 0) {
473 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message);
474 }
475 }
476 HILOG_DEBUG("exec context->status[%{public}d]", context->status);
477 };
478 context->SetExecution(std::move(exec));
479 }
480
NAPI_GetPixelMap(napi_env env,napi_callback_info info)481 napi_value NAPI_GetPixelMap(napi_env env, napi_callback_info info)
482 {
483 HILOG_DEBUG("NAPI_GetPixelMap in");
484 auto context = std::make_shared<GetContextInfo>();
485 ApiInfo apiInfo{ false, false };
486 NapiWallpaperAbility::GetImageInner(context, apiInfo);
487 AsyncCall asyncCall(env, info, context, 1, apiInfo.needException);
488 return asyncCall.Call(env);
489 }
490
NAPI_GetImage(napi_env env,napi_callback_info info)491 napi_value NAPI_GetImage(napi_env env, napi_callback_info info)
492 {
493 HILOG_DEBUG("NAPI_GetImage in");
494 auto context = std::make_shared<GetContextInfo>();
495 ApiInfo apiInfo{ true, true };
496 NapiWallpaperAbility::GetImageInner(context, apiInfo);
497 AsyncCall asyncCall(env, info, context, 1, apiInfo.needException);
498 return asyncCall.Call(env);
499 }
500
GetImageInner(std::shared_ptr<GetContextInfo> context,const ApiInfo & apiInfo)501 void NapiWallpaperAbility::GetImageInner(std::shared_ptr<GetContextInfo> context, const ApiInfo &apiInfo)
502 {
503 HILOG_DEBUG("GetImageInner in");
504 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
505 if (!NapiWallpaperAbility::IsValidArgCount(argc, 1)
506 || !NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_number)) {
507 HILOG_DEBUG("input argc : %{public}zu", argc);
508 context->SetErrInfo(ErrorThrowType::PARAMETER_ERROR, PARAMETERERRORMESSAGE);
509 return napi_invalid_arg;
510 }
511 napi_get_value_int32(env, argv[0], &context->wallpaperType);
512 HILOG_DEBUG("input wallpaperType : %{public}d", context->wallpaperType);
513 return napi_ok;
514 };
515 auto output = [context](napi_env env, napi_value *result) -> napi_status {
516 napi_value pixelVal = PixelMapNapi::CreatePixelMap(env, std::move(context->pixelMap));
517 HILOG_DEBUG("output PixelMapNapi::CreatePixelMap != nullptr[%{public}d]", pixelVal != nullptr);
518 *result = pixelVal;
519 return napi_ok;
520 };
521 auto exec = [context, apiInfo](AsyncCall::Context *ctx) {
522 HILOG_DEBUG("exec GetImageInner");
523 std::shared_ptr<OHOS::Media::PixelMap> pixelMap;
524 int32_t wallpaperErrorCode =
525 WallpaperMgrService::WallpaperManagerkits::GetInstance().GetPixelMap(context->wallpaperType, apiInfo,
526 pixelMap);
527 HILOG_DEBUG("exec wallpaperErrorCode[%{public}d]", wallpaperErrorCode);
528 if (wallpaperErrorCode == static_cast<int32_t>(E_OK) && pixelMap != nullptr) {
529 context->status = napi_ok;
530 context->pixelMap = std::move(pixelMap);
531 return;
532 }
533 if (apiInfo.needException) {
534 JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(wallpaperErrorCode);
535 if (jsErrorInfo.code != 0) {
536 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message);
537 }
538 }
539 };
540 context->SetAction(std::move(input), std::move(output));
541 context->SetExecution(std::move(exec));
542 }
543
NAPI_On(napi_env env,napi_callback_info info)544 napi_value NAPI_On(napi_env env, napi_callback_info info)
545 {
546 HILOG_DEBUG("NAPI_On in");
547 size_t argc = TWO;
548 napi_value argv[TWO] = { nullptr };
549 napi_value thisVar = nullptr;
550 void *data = nullptr;
551 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
552 if (!NapiWallpaperAbility::IsValidArgCount(argc, TWO) ||
553 !NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_string) ||
554 !NapiWallpaperAbility::IsValidArgType(env, argv[1], napi_function)) {
555 HILOG_DEBUG("input argc : %{public}zu", argc);
556 return nullptr;
557 }
558 std::string type = WallpaperJSUtil::Convert2String(env, argv[0]);
559 HILOG_DEBUG("type : %{public}s", type.c_str());
560
561 std::shared_ptr<WallpaperMgrService::WallpaperColorChangeListener> listener =
562 std::make_shared<NapiWallpaperAbility>(env, argv[1]);
563
564 bool status = WallpaperMgrService::WallpaperManagerkits::GetInstance().On(type, listener);
565 if (!status) {
566 HILOG_ERROR("WallpaperMgrService::WallpaperManagerkits::GetInstance().On failed!");
567 return nullptr;
568 }
569
570 napi_value result = nullptr;
571 napi_get_undefined(env, &result);
572 return result;
573 }
574
NAPI_Off(napi_env env,napi_callback_info info)575 napi_value NAPI_Off(napi_env env, napi_callback_info info)
576 {
577 HILOG_DEBUG("NAPI_Off in");
578 size_t argc = 2;
579 napi_value argv[2] = { nullptr };
580 napi_value thisVar = nullptr;
581 void *data = nullptr;
582 napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
583 if (!NapiWallpaperAbility::IsValidArgCount(argc, ONE)
584 || !NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_string)) {
585 HILOG_DEBUG("input argc : %{public}zu", argc);
586 return nullptr;
587 }
588 std::string type = WallpaperJSUtil::Convert2String(env, argv[0]);
589 HILOG_DEBUG("type : %{public}s", type.c_str());
590
591 std::shared_ptr<WallpaperMgrService::WallpaperColorChangeListener> listener = nullptr;
592 if (argc == TWO) {
593 if (!NapiWallpaperAbility::IsValidArgType(env, argv[1], napi_function)) {
594 return nullptr;
595 }
596 listener = std::make_shared<NapiWallpaperAbility>(env, argv[1]);
597 }
598
599 bool status = WallpaperMgrService::WallpaperManagerkits::GetInstance().Off(type, listener);
600 if (!status) {
601 HILOG_ERROR("WallpaperMgrService::WallpaperManagerkits::GetInstance().Off failed!");
602 return nullptr;
603 }
604
605 napi_value result = nullptr;
606 napi_get_undefined(env, &result);
607 return result;
608 }
609
NapiWallpaperAbility(napi_env env,napi_value callback)610 NapiWallpaperAbility::NapiWallpaperAbility(napi_env env, napi_value callback) : env_(env)
611 {
612 napi_create_reference(env, callback, 1, &callback_);
613 napi_get_uv_event_loop(env, &loop_);
614 }
615
~NapiWallpaperAbility()616 NapiWallpaperAbility::~NapiWallpaperAbility()
617 {
618 HILOG_ERROR("NapiWallpaperAbility::~NapiWallpaperAbility start!");
619 WorkData *workData = new (std::nothrow) WorkData(env_, callback_);
620 if (workData != nullptr) {
621 uv_after_work_cb afterCallback = [](uv_work_t *work, int status) {
622 WorkData *workData = reinterpret_cast<WorkData *>(work->data);
623 napi_delete_reference(workData->env_, workData->callback_);
624 delete workData;
625 delete work;
626 };
627 MiscServices::UvQueue::Call(env_, workData, afterCallback);
628 }
629 }
630
OnColorsChange(const std::vector<uint64_t> & color,int wallpaperType)631 void NapiWallpaperAbility::OnColorsChange(const std::vector<uint64_t> &color, int wallpaperType)
632 {
633 HILOG_ERROR("NapiWallpaperAbility::OnColorsChange start!");
634 WallpaperMgrService::WallpaperColorChangeListener::OnColorsChange(color, wallpaperType);
635 EventDataWorker *eventDataWorker = new (std::nothrow)
636 EventDataWorker(this->shared_from_this(), color, wallpaperType);
637 if (eventDataWorker == nullptr) {
638 return;
639 }
640 uv_work_t *work = new (std::nothrow) uv_work_t;
641 if (work == nullptr) {
642 delete eventDataWorker;
643 return;
644 }
645 work->data = eventDataWorker;
646 uv_queue_work(
647 loop_, work, [](uv_work_t *work) {},
648 [](uv_work_t *work, int status) {
649 EventDataWorker *eventDataInner = reinterpret_cast<EventDataWorker *>(work->data);
650 if (eventDataInner == nullptr || eventDataInner->listener == nullptr) {
651 delete work;
652 return;
653 }
654 napi_handle_scope scope = nullptr;
655 napi_open_handle_scope(eventDataInner->listener->env_, &scope);
656 if (scope == nullptr) {
657 delete eventDataInner;
658 delete work;
659 return;
660 }
661 napi_value jsWallpaperType = nullptr;
662 napi_create_int32(eventDataInner->listener->env_, eventDataInner->wallpaperType, &jsWallpaperType);
663 napi_value jsRgbaArray =
664 WallpaperJSUtil::Convert2JSRgbaArray(eventDataInner->listener->env_, eventDataInner->color);
665 napi_value callback = nullptr;
666 napi_value args[2] = { jsRgbaArray, jsWallpaperType };
667 napi_get_reference_value(eventDataInner->listener->env_, eventDataInner->listener->callback_, &callback);
668 napi_value global = nullptr;
669 napi_get_global(eventDataInner->listener->env_, &global);
670 napi_value result;
671 napi_status callStatus = napi_call_function(eventDataInner->listener->env_, global, callback,
672 sizeof(args) / sizeof(args[0]), args, &result);
673 if (callStatus != napi_ok) {
674 HILOG_ERROR("notify data change failed callStatus:%{public}d", callStatus);
675 }
676 napi_close_handle_scope(eventDataInner->listener->env_, scope);
677 delete eventDataInner;
678 delete work;
679 });
680 }
681
IsValidArgCount(size_t argc,size_t expectationSize)682 bool NapiWallpaperAbility::IsValidArgCount(size_t argc, size_t expectationSize)
683 {
684 return argc >= expectationSize;
685 }
686
IsValidArgType(napi_env env,napi_value argValue,napi_valuetype expectationType)687 bool NapiWallpaperAbility::IsValidArgType(napi_env env, napi_value argValue, napi_valuetype expectationType)
688 {
689 napi_valuetype valueType = napi_undefined;
690 napi_typeof(env, argValue, &valueType);
691 return (valueType != expectationType) ? false : true;
692 }
693
IsValidArgRange(napi_env env,napi_value argValue)694 bool NapiWallpaperAbility::IsValidArgRange(napi_env env, napi_value argValue)
695 {
696 int wallpaperType;
697 napi_get_value_int32(env, argValue, &wallpaperType);
698 return (wallpaperType != WALLPAPER_LOCKSCREEN && wallpaperType != WALLPAPER_SYSTEM) ? false : true;
699 }
700
CheckValidArgWallpaperType(napi_env env,size_t argc,napi_value argValue,std::shared_ptr<AsyncCall::Context> ctx)701 bool NapiWallpaperAbility::CheckValidArgWallpaperType(
702 napi_env env, size_t argc, napi_value argValue, std::shared_ptr<AsyncCall::Context> ctx)
703 {
704 if (!NapiWallpaperAbility::IsValidArgCount(argc, ONE)
705 || !NapiWallpaperAbility::IsValidArgType(env, argValue, napi_number)
706 || !NapiWallpaperAbility::IsValidArgRange(env, argValue)) {
707 HILOG_DEBUG("input argc : %{public}zu", argc);
708 ctx->SetErrInfo(ErrorThrowType::PARAMETER_ERROR, PARAMETERERRORMESSAGE);
709 return false;
710 }
711 return true;
712 }
713 } // namespace WallpaperNAPI
714 } // namespace OHOS