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