• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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