• 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 <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