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 <unistd.h>
17 #include <uv.h>
18 
19 #include <map>
20 #include <string>
21 #include <vector>
22 
23 #include "hilog_wrapper.h"
24 #include "js_error.h"
25 #include "napi_wallpaper_ability.h"
26 #include "uv_queue.h"
27 #include "wallpaper_manager.h"
28 #include "wallpaper_manager_common_info.h"
29 
30 using namespace OHOS::Media;
31 namespace OHOS {
32 namespace WallpaperNAPI {
33 const int32_t ONE = 1;
34 const int32_t TWO = 2;
35 const int32_t THREE = 3;
36 const int32_t EVENTTYPESIZE = 64;
37 const int32_t BUFFERSIZE = 100;
38 const int32_t PARAMETER_ERROR_CODE = 401;
39 constexpr const char *COLOR_CHANGE_EVENT = "colorChange";
40 constexpr const char *WALLPAPER_CHANGE_EVENT = "wallpaperChange";
41 
NAPI_GetColors(napi_env env,napi_callback_info info)42 napi_value NAPI_GetColors(napi_env env, napi_callback_info info)
43 {
44     HILOG_DEBUG("NAPI_GetColors in.");
45     auto context = std::make_shared<GetContextInfo>();
46     ApiInfo apiInfo{ false, false };
47     NapiWallpaperAbility::GetColorsInner(context, apiInfo);
48     Call call(env, info, std::dynamic_pointer_cast<Call::Context>(context), 1, apiInfo.needException);
49     return call.AsyncCall(env, "getColors");
50 }
51 
NAPI_GetColorsSync(napi_env env,napi_callback_info info)52 napi_value NAPI_GetColorsSync(napi_env env, napi_callback_info info)
53 {
54     HILOG_DEBUG("NAPI_GetColorsSync in.");
55     auto context = std::make_shared<GetContextInfo>();
56     ApiInfo apiInfo{ true, true };
57     NapiWallpaperAbility::GetColorsInner(context, apiInfo);
58     Call call(env, info, context, 1, apiInfo.needException);
59     return call.SyncCall(env);
60 }
61 
GetColorsInner(std::shared_ptr<GetContextInfo> context,const ApiInfo & apiInfo)62 void NapiWallpaperAbility::GetColorsInner(std::shared_ptr<GetContextInfo> context, const ApiInfo &apiInfo)
63 {
64     HILOG_DEBUG("GetColorsInner in.");
65     auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
66         if (!NapiWallpaperAbility::CheckValidArgWallpaperType(env, argc, argv[0], context)) {
67             return napi_invalid_arg;
68         }
69         napi_get_value_int32(env, argv[0], &context->wallpaperType);
70         HILOG_DEBUG("input wallpaperType : %{public}d", context->wallpaperType);
71         return napi_ok;
72     };
73     auto output = [context](napi_env env, napi_value *result) -> napi_status {
74         napi_value data = WallpaperJSUtil::Convert2JSRgbaArray(env, context->colors);
75         HILOG_DEBUG("output Convert2JSRgbaArray data != nullptr[%{public}d]", data != nullptr);
76         *result = data;
77         return napi_ok;
78     };
79     auto exec = [context, apiInfo](Call::Context *ctx) {
80         HILOG_DEBUG("exec GetColors.");
81         ErrorCode wallpaperErrorCode = WallpaperMgrService::WallpaperManager::GetInstance().GetColors(
82             context->wallpaperType, apiInfo, context->colors);
83         if (wallpaperErrorCode == E_OK && !context->colors.empty()) {
84             context->status = napi_ok;
85             return;
86         }
87         if (apiInfo.needException) {
88             JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(wallpaperErrorCode);
89             if (jsErrorInfo.code != 0) {
90                 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message);
91             }
92         }
93         HILOG_DEBUG("exec GetColors colors size : %{public}zu", context->colors.size());
94     };
95     context->SetAction(std::move(input), std::move(output));
96     context->SetExecution(std::move(exec));
97 }
98 
NAPI_GetId(napi_env env,napi_callback_info info)99 napi_value NAPI_GetId(napi_env env, napi_callback_info info)
100 {
101     auto context = std::make_shared<GetContextInfo>();
102     NapiWallpaperAbility::GetIdInner(context);
103     Call call(env, info, context, 1, false);
104     return call.AsyncCall(env, "getId");
105 }
106 
GetIdInner(std::shared_ptr<GetContextInfo> context)107 void NapiWallpaperAbility::GetIdInner(std::shared_ptr<GetContextInfo> context)
108 {
109     HILOG_DEBUG("GetIdInner in.");
110     auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
111         if (!NapiWallpaperAbility::CheckValidArgWallpaperType(env, argc, argv[0], context)) {
112             return napi_invalid_arg;
113         }
114         napi_get_value_int32(env, argv[0], &context->wallpaperType);
115         HILOG_DEBUG("input wallpaperType : %{public}d", context->wallpaperType);
116         return napi_ok;
117     };
118     auto output = [context](napi_env env, napi_value *result) -> napi_status {
119         napi_status status = napi_create_int32(env, context->wallpaperId, result);
120         HILOG_DEBUG("output napi_create_int32[%{public}d]", status);
121         return status;
122     };
123     auto exec = [context](Call::Context *ctx) {
124         HILOG_DEBUG("exec GetWallpaperId.");
125         context->wallpaperId =
126             WallpaperMgrService::WallpaperManager::GetInstance().GetWallpaperId(context->wallpaperType);
127         HILOG_DEBUG("exec GetWallpaperId wallpaperId : %{public}d", context->wallpaperId);
128         context->status = napi_ok;
129     };
130     context->SetAction(std::move(input), std::move(output));
131     context->SetExecution(std::move(exec));
132 }
133 
NAPI_GetFile(napi_env env,napi_callback_info info)134 napi_value NAPI_GetFile(napi_env env, napi_callback_info info)
135 {
136     HILOG_DEBUG("NAPI_GetFile in.");
137     auto context = std::make_shared<GetFileContextInfo>();
138     ApiInfo apiInfo{ false, false };
139     NapiWallpaperAbility::GetFileInner(context, apiInfo);
140     Call call(env, info, context, 1, apiInfo.needException);
141     return call.AsyncCall(env, "getFile");
142 }
143 
GetFileInner(std::shared_ptr<GetFileContextInfo> context,const ApiInfo & apiInfo)144 void NapiWallpaperAbility::GetFileInner(std::shared_ptr<GetFileContextInfo> context, const ApiInfo &apiInfo)
145 {
146     HILOG_DEBUG("GetFileInner in.");
147     auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
148         if (!NapiWallpaperAbility::CheckValidArgWallpaperType(env, argc, argv[0], context)) {
149             return napi_invalid_arg;
150         }
151         napi_get_value_int32(env, argv[0], &context->wallpaperType);
152         HILOG_DEBUG("input wallpaperType : %{public}d", context->wallpaperType);
153         return napi_ok;
154     };
155 
156     auto output = [context](napi_env env, napi_value *result) -> napi_status {
157         napi_value data = nullptr;
158         napi_create_int32(env, context->wallpaperFd, &data);
159         HILOG_DEBUG("output [%{public}d]", data != nullptr);
160         *result = data;
161         return napi_ok;
162     };
163     auto exec = [context, apiInfo](Call::Context *ctx) {
164         HILOG_DEBUG("exec GetFile.");
165         ErrorCode wallpaperErrorCode = WallpaperMgrService::WallpaperManager::GetInstance().GetFile(
166             context->wallpaperType, context->wallpaperFd);
167         if (wallpaperErrorCode == E_OK && context->wallpaperFd >= 0) {
168             context->status = napi_ok;
169             return;
170         }
171         if (apiInfo.needException) {
172             JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(wallpaperErrorCode);
173             if (jsErrorInfo.code == PARAMETER_ERROR_CODE) {
174                 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message + WALLPAPERTYPE_PARAMETER_TYPE);
175             } else {
176                 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message);
177             }
178         }
179 
180         HILOG_DEBUG("exec GetFile fd: %{public}d", context->wallpaperFd);
181     };
182     context->SetAction(std::move(input), std::move(output));
183     context->SetExecution(std::move(exec));
184 }
185 
NAPI_GetMinHeight(napi_env env,napi_callback_info info)186 napi_value NAPI_GetMinHeight(napi_env env, napi_callback_info info)
187 {
188     HILOG_DEBUG("NAPI_GetMinHeight in.");
189     auto context = std::make_shared<GetMinContextInfo>();
190     ApiInfo apiInfo{ false, false };
191     NapiWallpaperAbility::GetMinHeightInner(context, apiInfo);
192     Call call(env, info, context, 0, apiInfo.needException);
193     return call.AsyncCall(env, "getMinHeight");
194 }
195 
NAPI_GetMinHeightSync(napi_env env,napi_callback_info info)196 napi_value NAPI_GetMinHeightSync(napi_env env, napi_callback_info info)
197 {
198     HILOG_DEBUG("NAPI_GetMinHeightSync in.");
199     auto context = std::make_shared<GetMinContextInfo>();
200     ApiInfo apiInfo{ true, true };
201     NapiWallpaperAbility::GetMinHeightInner(context, apiInfo);
202     Call call(env, info, context, 0, apiInfo.needException);
203     return call.SyncCall(env);
204 }
205 
GetMinHeightInner(std::shared_ptr<GetMinContextInfo> context,const ApiInfo & apiInfo)206 void NapiWallpaperAbility::GetMinHeightInner(std::shared_ptr<GetMinContextInfo> context, const ApiInfo &apiInfo)
207 {
208     HILOG_DEBUG("GetMinHeightInner in.");
209     auto output = [context](napi_env env, napi_value *result) -> napi_status {
210         napi_status status = napi_create_int32(env, context->minHeight, result);
211         HILOG_DEBUG("output  napi_create_int32[%{public}d]", status);
212         return status;
213     };
214     auto exec = [context, apiInfo](Call::Context *ctx) {
215         HILOG_DEBUG("exec GetWallpaperMinHeight.");
216         ErrorCode wallpaperErrorCode = WallpaperMgrService::WallpaperManager::GetInstance().GetWallpaperMinHeight(
217             apiInfo, context->minHeight);
218         if (wallpaperErrorCode == E_OK && context->minHeight >= 0) {
219             context->status = napi_ok;
220             return;
221         }
222         if (apiInfo.needException) {
223             JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(wallpaperErrorCode);
224             if (jsErrorInfo.code != 0) {
225                 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message);
226             }
227         }
228     };
229     context->SetAction(nullptr, std::move(output));
230     context->SetExecution(std::move(exec));
231 }
232 
NAPI_GetMinWidth(napi_env env,napi_callback_info info)233 napi_value NAPI_GetMinWidth(napi_env env, napi_callback_info info)
234 {
235     HILOG_DEBUG("NAPI_GetMinWidth in.");
236     auto context = std::make_shared<GetMinContextInfo>();
237     ApiInfo apiInfo{ false, false };
238     NapiWallpaperAbility::GetMinWidthInner(context, apiInfo);
239     Call call(env, info, context, 0, apiInfo.needException);
240     return call.AsyncCall(env, "getMinWidth");
241 }
242 
NAPI_GetMinWidthSync(napi_env env,napi_callback_info info)243 napi_value NAPI_GetMinWidthSync(napi_env env, napi_callback_info info)
244 {
245     HILOG_DEBUG("NAPI_GetMinWidthSync in.");
246     auto context = std::make_shared<GetMinContextInfo>();
247     ApiInfo apiInfo{ true, true };
248     NapiWallpaperAbility::GetMinWidthInner(context, apiInfo);
249     Call call(env, info, context, 0, apiInfo.needException);
250     return call.SyncCall(env);
251 }
252 
GetMinWidthInner(std::shared_ptr<GetMinContextInfo> context,const ApiInfo & apiInfo)253 void NapiWallpaperAbility::GetMinWidthInner(std::shared_ptr<GetMinContextInfo> context, const ApiInfo &apiInfo)
254 {
255     HILOG_DEBUG("GetMinWidthInner in.");
256     auto output = [context](napi_env env, napi_value *result) -> napi_status {
257         napi_status status = napi_create_int32(env, context->minWidth, result);
258         HILOG_DEBUG("output  napi_create_int32[%{public}d]", status);
259         return status;
260     };
261     auto exec = [context, apiInfo](Call::Context *ctx) {
262         HILOG_DEBUG("exec GetWallpaperMinWidth.");
263         ErrorCode wallpaperErrorCode =
264             WallpaperMgrService::WallpaperManager::GetInstance().GetWallpaperMinWidth(apiInfo, context->minWidth);
265         if (wallpaperErrorCode == E_OK && context->minWidth >= 0) {
266             context->status = napi_ok;
267         }
268         if (apiInfo.needException) {
269             JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(wallpaperErrorCode);
270             if (jsErrorInfo.code != 0) {
271                 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message);
272             }
273         }
274     };
275     context->SetAction(nullptr, std::move(output));
276     context->SetExecution(std::move(exec));
277 }
278 
NAPI_IsChangePermitted(napi_env env,napi_callback_info info)279 napi_value NAPI_IsChangePermitted(napi_env env, napi_callback_info info)
280 {
281     HILOG_DEBUG("NAPI_IsChangePermitted in.");
282     auto context = std::make_shared<PermissionContextInfo>();
283     NapiWallpaperAbility::IsChangeAllowedInner(context);
284     Call call(env, info, context, 0, false);
285     return call.AsyncCall(env, "isChangePermitted");
286 }
287 
IsChangeAllowedInner(std::shared_ptr<PermissionContextInfo> context)288 void NapiWallpaperAbility::IsChangeAllowedInner(std::shared_ptr<PermissionContextInfo> context)
289 {
290     HILOG_DEBUG("IsChangeAllowedInner in.");
291     auto output = [context](napi_env env, napi_value *result) -> napi_status {
292         napi_status status = napi_get_boolean(env, context->isChangePermitted, result);
293         HILOG_DEBUG("output napi_get_boolean[%{public}d]", status);
294         return status;
295     };
296     auto exec = [context](Call::Context *ctx) {
297         HILOG_DEBUG("exec IsChangePermitted.");
298         context->isChangePermitted = WallpaperMgrService::WallpaperManager::GetInstance().IsChangePermitted();
299         HILOG_DEBUG("exec IsChangePermitted : %{public}d", context->isChangePermitted);
300         context->status = napi_ok;
301     };
302     context->SetAction(nullptr, std::move(output));
303     context->SetExecution(std::move(exec));
304 }
305 
NAPI_IsOperationAllowed(napi_env env,napi_callback_info info)306 napi_value NAPI_IsOperationAllowed(napi_env env, napi_callback_info info)
307 {
308     HILOG_DEBUG("NAPI_IsOperationAllowed in.");
309     auto context = std::make_shared<PermissionContextInfo>();
310     NapiWallpaperAbility::IsUserChangeAllowedInner(context);
311     Call call(env, info, context, 0, false);
312     return call.AsyncCall(env, "isOperationAllowed");
313 }
314 
IsUserChangeAllowedInner(std::shared_ptr<PermissionContextInfo> context)315 void NapiWallpaperAbility::IsUserChangeAllowedInner(std::shared_ptr<PermissionContextInfo> context)
316 {
317     HILOG_DEBUG("IsUserChangeAllowedInner in.");
318     auto output = [context](napi_env env, napi_value *result) -> napi_status {
319         napi_status status = napi_get_boolean(env, context->isOperationAllowed, result);
320         HILOG_DEBUG("output napi_get_boolean[%{public}d]", status);
321         return status;
322     };
323     auto exec = [context](Call::Context *ctx) {
324         HILOG_DEBUG("exec IsOperationAllowed.");
325         context->isOperationAllowed = WallpaperMgrService::WallpaperManager::GetInstance().IsOperationAllowed();
326         HILOG_DEBUG("exec IsOperationAllowed[%{public}d]", context->isOperationAllowed);
327         context->status = napi_ok;
328     };
329     context->SetAction(nullptr, std::move(output));
330     context->SetExecution(std::move(exec));
331 }
332 
NAPI_Reset(napi_env env,napi_callback_info info)333 napi_value NAPI_Reset(napi_env env, napi_callback_info info)
334 {
335     HILOG_DEBUG("NAPI_Reset in.");
336     auto context = std::make_shared<SetContextInfo>();
337     ApiInfo apiInfo{ false, false };
338     NapiWallpaperAbility::RestoreInner(context, apiInfo);
339     Call call(env, info, context, 1, apiInfo.needException);
340     return call.AsyncCall(env, "reset");
341 }
342 
NAPI_Restore(napi_env env,napi_callback_info info)343 napi_value NAPI_Restore(napi_env env, napi_callback_info info)
344 {
345     HILOG_DEBUG("NAPI_Restore in.");
346     auto context = std::make_shared<SetContextInfo>();
347     ApiInfo apiInfo{ true, true };
348     NapiWallpaperAbility::RestoreInner(context, apiInfo);
349     Call call(env, info, context, 1, apiInfo.needException);
350     return call.AsyncCall(env, "restore");
351 }
352 
RestoreInner(std::shared_ptr<SetContextInfo> context,const ApiInfo & apiInfo)353 void NapiWallpaperAbility::RestoreInner(std::shared_ptr<SetContextInfo> context, const ApiInfo &apiInfo)
354 {
355     HILOG_DEBUG("RestoreInner in.");
356     auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
357         if (!NapiWallpaperAbility::IsValidArgCount(argc, 1)) {
358             HILOG_DEBUG("input  argc : %{public}zu", argc);
359             context->SetErrInfo(
360                 ErrorThrowType::PARAMETER_ERROR, std::string(PARAMETER_ERROR_MESSAGE) + PARAMETER_COUNT);
361             return napi_invalid_arg;
362         }
363         if (!NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_number)) {
364             HILOG_DEBUG("input  argc : %{public}zu", argc);
365             context->SetErrInfo(
366                 ErrorThrowType::PARAMETER_ERROR, std::string(PARAMETER_ERROR_MESSAGE) + WALLPAPERTYPE_PARAMETER_TYPE);
367             return napi_invalid_arg;
368         }
369         napi_get_value_int32(env, argv[0], &context->wallpaperType);
370         HILOG_DEBUG("input wallpaperType : %{public}d", context->wallpaperType);
371         return napi_pending_exception;
372     };
373     auto exec = [context, apiInfo](Call::Context *ctx) {
374         HILOG_DEBUG("exec ResetWallpaper.");
375         ErrorCode wallpaperErrorCode =
376             WallpaperMgrService::WallpaperManager::GetInstance().ResetWallpaper(context->wallpaperType, apiInfo);
377         HILOG_DEBUG("exec ResetWallpaper[%{public}d]", wallpaperErrorCode);
378         if (wallpaperErrorCode == E_OK) {
379             context->status = napi_ok;
380         }
381         if (apiInfo.needException) {
382             JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(wallpaperErrorCode);
383             if (jsErrorInfo.code == PARAMETER_ERROR_CODE) {
384                 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message + WALLPAPERTYPE_PARAMETER_TYPE);
385             } else {
386                 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message);
387             }
388         }
389         HILOG_DEBUG("exec status[%{public}d], context->status[%{public}d]", wallpaperErrorCode, context->status);
390     };
391     context->SetAction(std::move(input), nullptr);
392     context->SetExecution(std::move(exec));
393 }
394 
NAPI_SetWallpaper(napi_env env,napi_callback_info info)395 napi_value NAPI_SetWallpaper(napi_env env, napi_callback_info info)
396 {
397     auto context = std::make_shared<SetContextInfo>();
398     ApiInfo apiInfo{ false, false };
399     NapiWallpaperAbility::SetImageInput(context);
400     NapiWallpaperAbility::SetImageExec(context, apiInfo);
401     Call call(env, info, context, TWO, apiInfo.needException);
402     return call.AsyncCall(env, "setWallpaper");
403 }
404 
NAPI_SetImage(napi_env env,napi_callback_info info)405 napi_value NAPI_SetImage(napi_env env, napi_callback_info info)
406 {
407     auto context = std::make_shared<SetContextInfo>();
408     ApiInfo apiInfo{ true, true };
409     NapiWallpaperAbility::SetImageInput(context);
410     NapiWallpaperAbility::SetImageExec(context, apiInfo);
411     Call call(env, info, context, TWO, apiInfo.needException);
412     return call.AsyncCall(env, "setImage");
413 }
414 
NAPI_SendEvent(napi_env env,napi_callback_info info)415 napi_value NAPI_SendEvent(napi_env env, napi_callback_info info)
416 {
417     auto context = std::make_shared<GetContextInfo>();
418     NapiWallpaperAbility::SendEventInner(context);
419     Call call(env, info, context, TWO, true);
420     return call.AsyncCall(env);
421 }
422 
SendEventInner(std::shared_ptr<GetContextInfo> context)423 void NapiWallpaperAbility::SendEventInner(std::shared_ptr<GetContextInfo> context)
424 {
425     auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
426         if (!NapiWallpaperAbility::IsValidArgCount(argc, TWO)) {
427             HILOG_ERROR("Input argc: %{public}zu", argc);
428             context->SetErrInfo(
429                 ErrorThrowType::PARAMETER_ERROR, std::string(PARAMETER_ERROR_MESSAGE) + PARAMETER_COUNT);
430             return napi_invalid_arg;
431         }
432         if (!NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_string)
433             || !NapiWallpaperAbility::IsValidArgType(env, argv[1], napi_string)) {
434             HILOG_ERROR("Input argc: %{public}zu", argc);
435             context->SetErrInfo(
436                 ErrorThrowType::PARAMETER_ERROR, std::string(PARAMETER_ERROR_MESSAGE) + "The type must be string.");
437             return napi_invalid_arg;
438         }
439         char eventType[EVENTTYPESIZE] = { 0 };
440         size_t bufSize = BUFFERSIZE;
441         size_t len = 0;
442         napi_get_value_string_utf8(env, argv[0], eventType, bufSize, &len);
443         context->eventType = eventType;
444         HILOG_DEBUG("Input event type: %{public}s", context->eventType.c_str());
445         return napi_ok;
446     };
447 
448     auto output = [context](napi_env env, napi_value *result) -> napi_status {
449         napi_status status = napi_get_boolean(env, context->result, result);
450         HILOG_DEBUG("Output status: %{public}d", status);
451         return status;
452     };
453 
454     auto exec = [context](Call::Context *ctx) {
455         ErrorCode wallpaperErrorCode =
456             WallpaperMgrService::WallpaperManager::GetInstance().SendEvent(context->eventType);
457         if (wallpaperErrorCode == E_OK) {
458             context->status = napi_ok;
459             context->result = true;
460         } else {
461             JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(wallpaperErrorCode);
462             if (jsErrorInfo.code == PARAMETER_ERROR_CODE) {
463                 context->SetErrInfo(jsErrorInfo.code,
464                     jsErrorInfo.message + "The eventType must be SHOW_SYSTEM_SCREEN or SHOW_LOCK_SCREEN.");
465             } else {
466                 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message);
467             }
468         }
469         HILOG_DEBUG("Exec context status: [%{public}d]", context->status);
470     };
471     context->SetAction(std::move(input), std::move(output));
472     context->SetExecution(std::move(exec));
473 }
474 
NAPI_SetVideo(napi_env env,napi_callback_info info)475 napi_value NAPI_SetVideo(napi_env env, napi_callback_info info)
476 {
477     auto context = std::make_shared<SetContextInfo>();
478     NapiWallpaperAbility::SetVideoInner(context);
479     Call call(env, info, context, TWO, true);
480     return call.AsyncCall(env);
481 }
482 
SetVideoInner(std::shared_ptr<SetContextInfo> context)483 void NapiWallpaperAbility::SetVideoInner(std::shared_ptr<SetContextInfo> context)
484 {
485     auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
486         if (!NapiWallpaperAbility::IsValidArgCount(argc, TWO)) {
487             HILOG_ERROR("Input argc: %{public}zu", argc);
488             context->SetErrInfo(
489                 ErrorThrowType::PARAMETER_ERROR, std::string(PARAMETER_ERROR_MESSAGE) + PARAMETER_COUNT);
490             return napi_invalid_arg;
491         }
492         if (!NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_string)
493             || !NapiWallpaperAbility::IsValidArgType(env, argv[1], napi_number)
494             || !NapiWallpaperAbility::IsValidArgRange(env, argv[1])) {
495             HILOG_ERROR("Input argc: %{public}zu", argc);
496             context->SetErrInfo(ErrorThrowType::PARAMETER_ERROR, std::string(PARAMETER_ERROR_MESSAGE)
497                                                                      + "The first parameter type must be string, the "
498                                                                        "second type must be WallpaperType"
499                                                                      + "and parameter range must be "
500                                                                        "WALLPAPER_LOCKSCREEN or WALLPAPER_SYSTEM.");
501 
502             return napi_invalid_arg;
503         }
504         context->uri = WallpaperJSUtil::Convert2String(env, argv[0]);
505         napi_get_value_int32(env, argv[1], &context->wallpaperType);
506         HILOG_DEBUG("Input wallpaperType: %{public}d", context->wallpaperType);
507         return napi_ok;
508     };
509 
510     auto exec = [context](Call::Context *ctx) {
511         ErrorCode wallpaperErrorCode =
512             WallpaperMgrService::WallpaperManager::GetInstance().SetVideo(context->uri, context->wallpaperType);
513         if (wallpaperErrorCode == E_OK) {
514             context->status = napi_ok;
515         } else {
516             JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(wallpaperErrorCode);
517             if (jsErrorInfo.code == PARAMETER_ERROR_CODE) {
518                 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message + DYNAMIC_WALLPAPERTYPE_PARAMETER_TYPE);
519             } else {
520                 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message);
521             }
522         }
523         HILOG_DEBUG("Exec context status:[%{public}d]", context->status);
524     };
525     context->SetAction(std::move(input), nullptr);
526     context->SetExecution(std::move(exec));
527 }
528 
SetImageInput(std::shared_ptr<SetContextInfo> context)529 void NapiWallpaperAbility::SetImageInput(std::shared_ptr<SetContextInfo> context)
530 {
531     HILOG_DEBUG("SetImageInput in.");
532     auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
533         if (!NapiWallpaperAbility::IsValidArgCount(argc, TWO)) {
534             HILOG_DEBUG("input argc : %{public}zu", argc);
535             context->SetErrInfo(
536                 ErrorThrowType::PARAMETER_ERROR, std::string(PARAMETER_ERROR_MESSAGE) + PARAMETER_COUNT);
537             return napi_invalid_arg;
538         }
539         if ((!NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_string)
540                 && !NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_object))
541             || !NapiWallpaperAbility::IsValidArgType(env, argv[1], napi_number)) {
542             HILOG_DEBUG("input argc : %{public}zu", argc);
543             context->SetErrInfo(ErrorThrowType::PARAMETER_ERROR, std::string(PARAMETER_ERROR_MESSAGE)
544                                                                      + "The first parameter type must be string or "
545                                                                        "image.PixelMap, the second type must be "
546                                                                        "WallpaperType"
547                                                                      + "and parameter range must be "
548                                                                        "WALLPAPER_LOCKSCREEN or WALLPAPER_SYSTEM.");
549             return napi_invalid_arg;
550         }
551         napi_valuetype valueType = napi_undefined;
552         napi_typeof(env, argv[0], &valueType);
553         if (valueType == napi_string) {
554             context->uri = WallpaperJSUtil::Convert2String(env, argv[0]);
555         } else {
556             std::shared_ptr<PixelMap> pixelMap = PixelMapNapi::GetPixelMap(env, argv[0]);
557             if (pixelMap == nullptr) {
558                 HILOG_ERROR("PixelMapNapi::GetPixelMap error!");
559                 context->isPixelEmp = true;
560                 return napi_generic_failure;
561             } else {
562                 context->isPixelEmp = false;
563             }
564             context->pixelMap = pixelMap;
565         }
566         napi_get_value_int32(env, argv[1], &context->wallpaperType);
567         HILOG_DEBUG("input wallpaperType : %{public}d", context->wallpaperType);
568         return napi_ok;
569     };
570     context->SetAction(std::move(input), nullptr);
571 }
572 
SetImageExec(std::shared_ptr<SetContextInfo> context,const ApiInfo & apiInfo)573 void NapiWallpaperAbility::SetImageExec(std::shared_ptr<SetContextInfo> context, const ApiInfo &apiInfo)
574 {
575     HILOG_DEBUG("SetImageExec in.");
576     auto exec = [context, apiInfo](Call::Context *ctx) {
577         ErrorCode wallpaperErrorCode = E_UNKNOWN;
578         if (context->uri.length() == 0) {
579             HILOG_DEBUG("exec setWallpaper by pixelMap.");
580             if (!context->isPixelEmp) {
581                 wallpaperErrorCode = WallpaperMgrService::WallpaperManager::GetInstance().SetWallpaper(
582                     context->pixelMap, context->wallpaperType, apiInfo);
583             }
584         } else {
585             HILOG_DEBUG("exec setWallpaper by uri.");
586             wallpaperErrorCode = WallpaperMgrService::WallpaperManager::GetInstance().SetWallpaper(
587                 context->uri, context->wallpaperType, apiInfo);
588         }
589         if (wallpaperErrorCode == E_OK) {
590             context->status = napi_ok;
591         }
592         if (apiInfo.needException) {
593             JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(wallpaperErrorCode);
594             if (jsErrorInfo.code == PARAMETER_ERROR_CODE) {
595                 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message + DYNAMIC_WALLPAPERTYPE_PARAMETER_TYPE);
596             } else {
597                 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message);
598             }
599         }
600         HILOG_DEBUG("exec context->status[%{public}d]", context->status);
601     };
602     context->SetExecution(std::move(exec));
603 }
604 
NAPI_GetPixelMap(napi_env env,napi_callback_info info)605 napi_value NAPI_GetPixelMap(napi_env env, napi_callback_info info)
606 {
607     HILOG_DEBUG("NAPI_GetPixelMap in.");
608     auto context = std::make_shared<GetContextInfo>();
609     ApiInfo apiInfo{ false, false };
610     NapiWallpaperAbility::GetImageInner(context, apiInfo);
611     Call call(env, info, context, 1, apiInfo.needException);
612     return call.AsyncCall(env, "getPixelMap");
613 }
614 
NAPI_GetImage(napi_env env,napi_callback_info info)615 napi_value NAPI_GetImage(napi_env env, napi_callback_info info)
616 {
617     HILOG_DEBUG("NAPI_GetImage in.");
618     auto context = std::make_shared<GetContextInfo>();
619     ApiInfo apiInfo{ true, true };
620     NapiWallpaperAbility::GetImageInner(context, apiInfo);
621     Call call(env, info, context, 1, apiInfo.needException);
622     return call.AsyncCall(env, "getImage");
623 }
624 
GetImageInner(std::shared_ptr<GetContextInfo> context,const ApiInfo & apiInfo)625 void NapiWallpaperAbility::GetImageInner(std::shared_ptr<GetContextInfo> context, const ApiInfo &apiInfo)
626 {
627     HILOG_DEBUG("GetImageInner in.");
628     auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
629         if (!NapiWallpaperAbility::IsValidArgCount(argc, 1)) {
630             HILOG_DEBUG("input argc : %{public}zu", argc);
631             context->SetErrInfo(
632                 ErrorThrowType::PARAMETER_ERROR, std::string(PARAMETER_ERROR_MESSAGE) + PARAMETER_COUNT);
633             return napi_invalid_arg;
634         }
635         if (!NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_number)
636             || !NapiWallpaperAbility::IsValidArgRange(env, argv[0])) {
637             context->SetErrInfo(
638                 ErrorThrowType::PARAMETER_ERROR, std::string(PARAMETER_ERROR_MESSAGE) + WALLPAPERTYPE_PARAMETER_TYPE);
639             return napi_invalid_arg;
640         }
641         napi_get_value_int32(env, argv[0], &context->wallpaperType);
642         return napi_ok;
643     };
644     auto output = [context](napi_env env, napi_value *result) -> napi_status {
645         napi_value pixelVal =
646             (context->pixelMap != nullptr ? PixelMapNapi::CreatePixelMap(env, std::move(context->pixelMap)) : nullptr);
647         HILOG_DEBUG("output PixelMapNapi::CreatePixelMap != nullptr[%{public}d]", pixelVal != nullptr);
648         *result = pixelVal;
649         return napi_ok;
650     };
651     auto exec = [context, apiInfo](Call::Context *ctx) {
652         HILOG_DEBUG("exec GetImageInner.");
653         std::shared_ptr<OHOS::Media::PixelMap> pixelMap;
654         ErrorCode wallpaperErrorCode = WallpaperMgrService::WallpaperManager::GetInstance().GetPixelMap(
655             context->wallpaperType, apiInfo, pixelMap);
656         HILOG_DEBUG("exec wallpaperErrorCode[%{public}d]", wallpaperErrorCode);
657         if (wallpaperErrorCode == E_OK) {
658             context->status = napi_ok;
659             context->pixelMap = (pixelMap != nullptr ? std::move(pixelMap) : nullptr);
660             return;
661         }
662         if (apiInfo.needException) {
663             JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(wallpaperErrorCode);
664             if (jsErrorInfo.code == PARAMETER_ERROR_CODE) {
665                 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message + WALLPAPERTYPE_PARAMETER_TYPE);
666             } else {
667                 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message);
668             }
669         }
670     };
671     context->SetAction(std::move(input), std::move(output));
672     context->SetExecution(std::move(exec));
673 }
674 
NAPI_GetCorrespondWallpaper(napi_env env,napi_callback_info info)675 napi_value NAPI_GetCorrespondWallpaper(napi_env env, napi_callback_info info)
676 {
677     auto context = std::make_shared<GetContextInfo>();
678     ApiInfo apiInfo{ true, true };
679     NapiWallpaperAbility::GetCorrespondWallpaperInner(context, apiInfo);
680     Call call(env, info, context, TWO, apiInfo.needException);
681     return call.AsyncCall(env, "getCorrespondWallpaper");
682 }
683 
GetCorrespondWallpaperInner(std::shared_ptr<GetContextInfo> context,const ApiInfo & apiInfo)684 void NapiWallpaperAbility::GetCorrespondWallpaperInner(std::shared_ptr<GetContextInfo> context, const ApiInfo &apiInfo)
685 {
686     auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
687         if (!IsValidArgCount(argc, THREE)) {
688             context->SetErrInfo(PARAMETER_ERROR, std::string(PARAMETER_ERROR_MESSAGE) + PARAMETER_COUNT);
689             return napi_invalid_arg;
690         }
691         if (!IsValidArgType(env, argv[0], napi_number) || !IsValidArgRange(env, argv[0])) {
692             context->SetErrInfo(PARAMETER_ERROR, std::string(PARAMETER_ERROR_MESSAGE) + WALLPAPERTYPE_PARAMETER_TYPE);
693             return napi_invalid_arg;
694         }
695         if (!IsValidArgType(env, argv[1], napi_number) || !IsValidFoldStateRange(env, argv[1])) {
696             context->SetErrInfo(PARAMETER_ERROR, std::string(PARAMETER_ERROR_MESSAGE) + FOLDSTATE_PARAMETER_TYPE);
697             return napi_invalid_arg;
698         }
699         if (!IsValidArgType(env, argv[2], napi_number) || !IsValidRotateStateRange(env, argv[2])) {
700             context->SetErrInfo(PARAMETER_ERROR, std::string(PARAMETER_ERROR_MESSAGE) + ROTATESTATE_PARAMETER_TYPE);
701             return napi_invalid_arg;
702         }
703         napi_get_value_int32(env, argv[0], &context->wallpaperType);
704         napi_get_value_int32(env, argv[1], &context->foldState);
705         napi_get_value_int32(env, argv[2], &context->rotateState);
706         return napi_ok;
707     };
708     auto output = [context](napi_env env, napi_value *result) -> napi_status {
709         napi_value pixelVal =
710             context->pixelMap != nullptr ? PixelMapNapi::CreatePixelMap(env, std::move(context->pixelMap)) : nullptr;
711         *result = pixelVal;
712         return napi_ok;
713     };
714     auto exec = [context, apiInfo](Call::Context *ctx) {
715         std::shared_ptr<OHOS::Media::PixelMap> pixelMap;
716         ErrorCode wallpaperErrorCode = WallpaperManager::GetInstance().GetCorrespondWallpaper(
717             context->wallpaperType, context->foldState, context->rotateState, pixelMap);
718         if (wallpaperErrorCode == E_OK) {
719             context->status = napi_ok;
720             context->pixelMap = pixelMap != nullptr ? std::move(pixelMap) : nullptr;
721             return;
722         }
723         if (apiInfo.needException) {
724             JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(wallpaperErrorCode);
725             context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message);
726         }
727     };
728     context->SetAction(std::move(input), std::move(output));
729     context->SetExecution(std::move(exec));
730 }
731 
NAPI_On(napi_env env,napi_callback_info info)732 napi_value NAPI_On(napi_env env, napi_callback_info info)
733 {
734     HILOG_DEBUG("NAPI_On in.");
735     size_t argc = TWO;
736     napi_value argv[TWO] = { nullptr };
737     napi_value thisVar = nullptr;
738     void *data = nullptr;
739     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
740     if (!NapiWallpaperAbility::IsValidArgCount(argc, TWO)
741         || !NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_string)
742         || !NapiWallpaperAbility::IsValidArgType(env, argv[1], napi_function)) {
743         HILOG_DEBUG("input argc : %{public}zu", argc);
744         if (NapiWallpaperAbility::IsValidArgCount(argc, 1) && // 1: argument count
745             NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_string)
746             && WallpaperJSUtil::Convert2String(env, argv[0]) == COLOR_CHANGE_EVENT) {
747             return nullptr;
748         }
749         JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(E_PARAMETERS_INVALID);
750         JsError::ThrowError(env, jsErrorInfo.code,
751             jsErrorInfo.message
752                 + "The parameters must be two, the first parameters must be string, second parameter must be "
753                   "function.");
754         return nullptr;
755     }
756     std::string type = WallpaperJSUtil::Convert2String(env, argv[0]);
757     HILOG_DEBUG("type : %{public}s", type.c_str());
758     if (type != COLOR_CHANGE_EVENT && type != WALLPAPER_CHANGE_EVENT) {
759         HILOG_ERROR("do not support event type: %{public}s", type.c_str());
760         JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(E_PARAMETERS_INVALID);
761         JsError::ThrowError(env, jsErrorInfo.code,
762             jsErrorInfo.message + "The first parameter type must be COLOR_CHANGE_EVENT and WALLPAPER_CHANGE_EVENT.");
763         return nullptr;
764     }
765     std::shared_ptr<WallpaperMgrService::WallpaperEventListener> listener =
766         std::make_shared<NapiWallpaperAbility>(env, argv[1]);
767     ErrorCode errorCode = WallpaperMgrService::WallpaperManager::GetInstance().On(type, listener);
768     if (errorCode != E_OK) {
769         HILOG_ERROR("WallpaperMgrService::WallpaperManager::GetInstance().On failed!");
770         if (type == COLOR_CHANGE_EVENT) {
771             return nullptr;
772         }
773         JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(errorCode);
774         JsError::ThrowError(env, jsErrorInfo.code, jsErrorInfo.message);
775         return nullptr;
776     }
777     napi_value result = nullptr;
778     napi_get_undefined(env, &result);
779     return result;
780 }
781 
NAPI_Off(napi_env env,napi_callback_info info)782 napi_value NAPI_Off(napi_env env, napi_callback_info info)
783 {
784     HILOG_DEBUG("NAPI_Off in.");
785     size_t argc = 2;
786     napi_value argv[2] = { nullptr };
787     napi_value thisVar = nullptr;
788     void *data = nullptr;
789     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
790     if (!NapiWallpaperAbility::IsValidArgCount(argc, 1) || // 1: argument count
791         !NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_string)) {
792         HILOG_DEBUG("input argc : %{public}zu", argc);
793         JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(E_PARAMETERS_INVALID);
794         JsError::ThrowError(
795             env, jsErrorInfo.code, jsErrorInfo.message + "Only one parameter and the type must be string.");
796         return nullptr;
797     }
798     std::string type = WallpaperJSUtil::Convert2String(env, argv[0]);
799     HILOG_DEBUG("type : %{public}s", type.c_str());
800     if (type != COLOR_CHANGE_EVENT && type != WALLPAPER_CHANGE_EVENT) {
801         HILOG_ERROR("do not support event type: %{public}s", type.c_str());
802         JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(E_PARAMETERS_INVALID);
803         JsError::ThrowError(env, jsErrorInfo.code,
804             jsErrorInfo.message + "The first parameter type must be COLOR_CHANGE_EVENT and WALLPAPER_CHANGE_EVENT.");
805         return nullptr;
806     }
807     std::shared_ptr<WallpaperMgrService::WallpaperEventListener> listener = nullptr;
808     if (argc >= TWO) {
809         if (NapiWallpaperAbility::IsValidArgType(env, argv[1], napi_function)) {
810             listener = std::make_shared<NapiWallpaperAbility>(env, argv[1]);
811         } else if (!NapiWallpaperAbility::IsValidArgType(env, argv[1], napi_undefined)
812                    && !NapiWallpaperAbility::IsValidArgType(env, argv[1], napi_null)) {
813             JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(E_PARAMETERS_INVALID);
814             JsError::ThrowError(env, jsErrorInfo.code,
815                 jsErrorInfo.message + "The second parameter is neither a valid function type nor undefined or null.");
816             return nullptr;
817         }
818     }
819     ErrorCode errorCode = WallpaperMgrService::WallpaperManager::GetInstance().Off(type, listener);
820     if (errorCode != E_OK) {
821         HILOG_ERROR("WallpaperMgrService::WallpaperManager::GetInstance().Off failed!");
822         if (type == COLOR_CHANGE_EVENT) {
823             return nullptr;
824         }
825         JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(errorCode);
826         JsError::ThrowError(env, jsErrorInfo.code, jsErrorInfo.message);
827         return nullptr;
828     }
829     napi_value result = nullptr;
830     napi_get_undefined(env, &result);
831     return result;
832 }
833 
NAPI_SetCustomWallpaper(napi_env env,napi_callback_info info)834 napi_value NAPI_SetCustomWallpaper(napi_env env, napi_callback_info info)
835 {
836     auto context = std::make_shared<SetContextInfo>();
837     NapiWallpaperAbility::SetCustomWallpaper(context);
838     Call call(env, info, context, TWO, true);
839     return call.AsyncCall(env);
840 }
841 
SetCustomWallpaper(std::shared_ptr<SetContextInfo> context)842 void NapiWallpaperAbility::SetCustomWallpaper(std::shared_ptr<SetContextInfo> context)
843 {
844     auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
845         if (argc < TWO) {
846             HILOG_ERROR("Input argc: %{public}zu", argc);
847             context->SetErrInfo(
848                 ErrorThrowType::PARAMETER_ERROR, std::string(PARAMETER_ERROR_MESSAGE) + PARAMETER_COUNT);
849             return napi_invalid_arg;
850         }
851         if (!NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_string)
852             || !NapiWallpaperAbility::IsValidArgType(env, argv[1], napi_number)) {
853             HILOG_ERROR("Input argc: %{public}zu", argc);
854             context->SetErrInfo(ErrorThrowType::PARAMETER_ERROR, std::string(PARAMETER_ERROR_MESSAGE)
855                                                                      + "The first parameter type must be string. the "
856                                                                        "second type must be WallpaperType and"
857                                                                      + "parameter range must be WALLPAPER_LOCKSCREEN "
858                                                                        "or WALLPAPER_SYSTEM.");
859             return napi_invalid_arg;
860         }
861         context->uri = WallpaperJSUtil::Convert2String(env, argv[0]);
862         napi_get_value_int32(env, argv[1], &context->wallpaperType);
863         HILOG_DEBUG("Input wallpaperType: %{public}d", context->wallpaperType);
864         return napi_ok;
865     };
866 
867     auto exec = [context](Call::Context *ctx) {
868         ErrorCode wallpaperErrorCode = WallpaperMgrService::WallpaperManager::GetInstance().SetCustomWallpaper(
869             context->uri, context->wallpaperType);
870         if (wallpaperErrorCode == E_OK) {
871             context->status = napi_ok;
872         } else {
873             JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(wallpaperErrorCode);
874             if (jsErrorInfo.code == PARAMETER_ERROR_CODE) {
875                 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message + WALLPAPERTYPE_PARAMETER_TYPE);
876             } else {
877                 context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message);
878             }
879         }
880         HILOG_DEBUG("Exec context status:[%{public}d]", context->status);
881     };
882     context->SetAction(std::move(input), nullptr);
883     context->SetExecution(std::move(exec));
884 }
885 
NAPI_SetAllWallpapers(napi_env env,napi_callback_info info)886 napi_value NAPI_SetAllWallpapers(napi_env env, napi_callback_info info)
887 {
888     auto context = std::make_shared<SetContextInfo>();
889     NapiWallpaperAbility::SetAllWallpapers(context);
890     Call call(env, info, context, TWO, true);
891     return call.AsyncCall(env);
892 }
893 
SetAllWallpapers(std::shared_ptr<SetContextInfo> context)894 void NapiWallpaperAbility::SetAllWallpapers(std::shared_ptr<SetContextInfo> context)
895 {
896     auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
897         if (argc < TWO) {
898             HILOG_ERROR("Input argc: %{public}zu", argc);
899             context->SetErrInfo(
900                 ErrorThrowType::PARAMETER_ERROR, std::string(PARAMETER_ERROR_MESSAGE) + PARAMETER_COUNT);
901             return napi_invalid_arg;
902         }
903         bool isArray = false;
904         napi_is_array(env, argv[0], &isArray);
905         if (!NapiWallpaperAbility::IsValidArgType(env, argv[0], napi_object)
906             || !NapiWallpaperAbility::IsValidArgType(env, argv[1], napi_number)
907             || !NapiWallpaperAbility::IsValidArgRange(env, argv[1]) || !isArray) {
908             context->SetErrInfo(ErrorThrowType::PARAMETER_ERROR, std::string(PARAMETER_ERROR_MESSAGE)
909                                                                      + "The first parameter type must be "
910                                                                        "Array<WallpaperInfo>.The second type must be "
911                                                                        "WallpaperType.");
912             return napi_invalid_arg;
913         }
914         if (!NapiWallpaperAbility::IsValidWallpaperInfos(env, argv[0])) {
915             context->SetErrInfo(ErrorThrowType::PARAMETER_ERROR, std::string(PARAMETER_ERROR_MESSAGE)
916                                                                      + "The first parameter type must be "
917                                                                        "Array<WallpaperInfo>,"
918                                                                        "must include wallpaper with FoldState NORMAL "
919                                                                        "and RotateState PORTRAIT.");
920             return napi_invalid_arg;
921         }
922         WallpaperJSUtil::Convert2WallpaperInfos(env, argv[0], context->wallpaperInfos);
923         auto res = napi_get_value_int32(env, argv[1], &context->wallpaperType);
924         if (res != napi_ok) {
925             HILOG_ERROR("get wallpaperType failed, res:%{public}d", res);
926             return res;
927         }
928         HILOG_DEBUG("Input wallpaperType: %{public}d", context->wallpaperType);
929         return napi_ok;
930     };
931 
932     auto exec = [context](Call::Context *ctx) {
933         ErrorCode wallpaperErrorCode = WallpaperMgrService::WallpaperManager::GetInstance().SetAllWallpapers(
934             context->wallpaperInfos, context->wallpaperType);
935         if (wallpaperErrorCode == E_OK) {
936             context->status = napi_ok;
937         } else {
938             JsErrorInfo jsErrorInfo = JsError::ConvertErrorCode(wallpaperErrorCode);
939             context->SetErrInfo(jsErrorInfo.code, jsErrorInfo.message);
940         }
941         HILOG_DEBUG("Exec context status:[%{public}d]", context->status);
942     };
943     context->SetAction(std::move(input), nullptr);
944     context->SetExecution(std::move(exec));
945 }
946 
NapiWallpaperAbility(napi_env env,napi_value callback)947 NapiWallpaperAbility::NapiWallpaperAbility(napi_env env, napi_value callback) : env_(env)
948 {
949     napi_create_reference(env, callback, 1, &callback_);
950     napi_get_uv_event_loop(env, &loop_);
951 }
952 
~NapiWallpaperAbility()953 NapiWallpaperAbility::~NapiWallpaperAbility()
954 {
955     HILOG_INFO("~NapiWallpaperAbility start.");
956     WorkData *workData = new (std::nothrow) WorkData(env_, callback_);
957     if (workData != nullptr) {
958         uv_after_work_cb afterCallback = [](uv_work_t *work, int status) {
959             WorkData *workData = reinterpret_cast<WorkData *>(work->data);
960             napi_delete_reference(workData->env_, workData->callback_);
961             delete workData;
962             delete work;
963         };
964         MiscServices::UvQueue::Call(env_, workData, afterCallback);
965     }
966 }
967 
OnColorsChange(const std::vector<uint64_t> & color,int wallpaperType)968 void NapiWallpaperAbility::OnColorsChange(const std::vector<uint64_t> &color, int wallpaperType)
969 {
970     WallpaperMgrService::WallpaperEventListener::OnColorsChange(color, wallpaperType);
971     EventDataWorker *eventDataWorker = new (std::nothrow)
972         EventDataWorker(this->shared_from_this(), color, wallpaperType);
973     if (eventDataWorker == nullptr) {
974         return;
975     }
976     uv_work_t *work = new (std::nothrow) uv_work_t;
977     if (work == nullptr) {
978         delete eventDataWorker;
979         return;
980     }
981     work->data = eventDataWorker;
982     auto ret = uv_queue_work_with_qos(
983         loop_, work, [](uv_work_t *work) {},
984         [](uv_work_t *work, int status) { OnColorsChangeLambdaFunction(work, status); }, uv_qos_user_initiated);
985     if (ret != 0) {
986         delete eventDataWorker;
987         delete work;
988         HILOG_ERROR("uv_queue_work failed, retCode:%{public}d", ret);
989         return;
990     }
991 }
992 
OnWallpaperChange(WallpaperType wallpaperType,WallpaperResourceType resourceType,const std::string & uri)993 void NapiWallpaperAbility::OnWallpaperChange(
994     WallpaperType wallpaperType, WallpaperResourceType resourceType, const std::string &uri)
995 {
996     WallpaperChangedData *data = new (std::nothrow)
997         WallpaperChangedData(this->shared_from_this(), wallpaperType, resourceType, uri);
998     if (data == nullptr) {
999         return;
1000     }
1001     uv_work_t *work = new (std::nothrow) uv_work_t;
1002     if (work == nullptr) {
1003         delete data;
1004         return;
1005     }
1006     work->data = data;
1007     auto ret = uv_queue_work_with_qos(
1008         loop_, work, [](uv_work_t *work) {},
1009         [](uv_work_t *work, int status) { OnWallpaperChangeLambdaFunction(work, status); }, uv_qos_user_initiated);
1010     if (ret != 0) {
1011         delete data;
1012         delete work;
1013         HILOG_ERROR("uv_queue_work failed, retCode:%{public}d", ret);
1014         return;
1015     }
1016 }
1017 
IsValidArgCount(size_t argc,size_t expectationSize)1018 bool NapiWallpaperAbility::IsValidArgCount(size_t argc, size_t expectationSize)
1019 {
1020     return argc >= expectationSize;
1021 }
1022 
IsValidArgType(napi_env env,napi_value argValue,napi_valuetype expectationType)1023 bool NapiWallpaperAbility::IsValidArgType(napi_env env, napi_value argValue, napi_valuetype expectationType)
1024 {
1025     napi_valuetype valueType = napi_undefined;
1026     napi_typeof(env, argValue, &valueType);
1027     return (valueType != expectationType) ? false : true;
1028 }
1029 
IsValidArgRange(napi_env env,napi_value argValue)1030 bool NapiWallpaperAbility::IsValidArgRange(napi_env env, napi_value argValue)
1031 {
1032     int wallpaperType;
1033     napi_get_value_int32(env, argValue, &wallpaperType);
1034     return (wallpaperType != WALLPAPER_LOCKSCREEN && wallpaperType != WALLPAPER_SYSTEM) ? false : true;
1035 }
1036 
IsValidWallpaperInfos(napi_env env,napi_value argValue)1037 bool NapiWallpaperAbility::IsValidWallpaperInfos(napi_env env, napi_value argValue)
1038 {
1039     std::vector<WallpaperInfo> wallpaperInfos;
1040     if (WallpaperJSUtil::Convert2WallpaperInfos(env, argValue, wallpaperInfos) != napi_ok) {
1041         return false;
1042     }
1043     for (const auto &wallpaperInfo : wallpaperInfos) {
1044         if (wallpaperInfo.foldState == FoldState::NORMAL && wallpaperInfo.rotateState == RotateState::PORT) {
1045             return true;
1046         }
1047     }
1048     return false;
1049 }
1050 
IsValidFoldStateRange(napi_env env,napi_value argValue)1051 bool NapiWallpaperAbility::IsValidFoldStateRange(napi_env env, napi_value argValue)
1052 {
1053     int foldState;
1054     auto res = napi_get_value_int32(env, argValue, &foldState);
1055     if (res != napi_ok) {
1056         HILOG_ERROR("get foldState failed, res:%{public}d", res);
1057         return res;
1058     }
1059     return foldState == NORMAL || foldState == UNFOLD_1 || foldState == UNFOLD_2;
1060 }
1061 
IsValidRotateStateRange(napi_env env,napi_value argValue)1062 bool NapiWallpaperAbility::IsValidRotateStateRange(napi_env env, napi_value argValue)
1063 {
1064     int rotateState;
1065     auto res = napi_get_value_int32(env, argValue, &rotateState);
1066     if (res != napi_ok) {
1067         HILOG_ERROR("get rotateState failed, res:%{public}d", res);
1068         return res;
1069     }
1070     return rotateState == PORT || rotateState == LAND;
1071 }
1072 
CheckValidArgWallpaperType(napi_env env,size_t argc,napi_value argValue,std::shared_ptr<Call::Context> ctx)1073 bool NapiWallpaperAbility::CheckValidArgWallpaperType(
1074     napi_env env, size_t argc, napi_value argValue, std::shared_ptr<Call::Context> ctx)
1075 {
1076     if (!NapiWallpaperAbility::IsValidArgCount(argc, ONE)) {
1077         HILOG_DEBUG("input argc : %{public}zu", argc);
1078         ctx->SetErrInfo(ErrorThrowType::PARAMETER_ERROR, std::string(PARAMETER_ERROR_MESSAGE) + PARAMETER_COUNT);
1079         return false;
1080     }
1081     if (!NapiWallpaperAbility::IsValidArgType(env, argValue, napi_number)
1082         || !NapiWallpaperAbility::IsValidArgRange(env, argValue)) {
1083         HILOG_DEBUG("input argc : %{public}zu", argc);
1084         ctx->SetErrInfo(
1085             ErrorThrowType::PARAMETER_ERROR, std::string(PARAMETER_ERROR_MESSAGE) + WALLPAPERTYPE_PARAMETER_TYPE);
1086         return false;
1087     }
1088     return true;
1089 }
1090 
OnColorsChangeLambdaFunction(uv_work_t * work,int status)1091 void NapiWallpaperAbility::OnColorsChangeLambdaFunction(uv_work_t *work, int status)
1092 {
1093     EventDataWorker *eventDataInner = reinterpret_cast<EventDataWorker *>(work->data);
1094     if (eventDataInner == nullptr) {
1095         delete work;
1096         return;
1097     }
1098     if (eventDataInner->listener == nullptr) {
1099         delete eventDataInner;
1100         delete work;
1101         return;
1102     }
1103     napi_handle_scope scope = nullptr;
1104     napi_open_handle_scope(eventDataInner->listener->env_, &scope);
1105     if (scope == nullptr) {
1106         delete eventDataInner;
1107         delete work;
1108         return;
1109     }
1110     napi_value jsWallpaperType = nullptr;
1111     napi_create_int32(eventDataInner->listener->env_, eventDataInner->wallpaperType, &jsWallpaperType);
1112     napi_value jsRgbaArray =
1113         WallpaperJSUtil::Convert2JSRgbaArray(eventDataInner->listener->env_, eventDataInner->color);
1114     napi_value callback = nullptr;
1115     napi_value args[2] = { jsRgbaArray, jsWallpaperType };
1116     napi_get_reference_value(eventDataInner->listener->env_, eventDataInner->listener->callback_, &callback);
1117     napi_value global = nullptr;
1118     napi_get_global(eventDataInner->listener->env_, &global);
1119     napi_value result;
1120     napi_status callStatus = napi_call_function(
1121         eventDataInner->listener->env_, global, callback, sizeof(args) / sizeof(args[0]), args, &result);
1122     if (callStatus != napi_ok) {
1123         HILOG_ERROR("notify data change failed, callStatus:%{public}d", callStatus);
1124     }
1125     napi_close_handle_scope(eventDataInner->listener->env_, scope);
1126     delete eventDataInner;
1127     delete work;
1128     return;
1129 }
1130 
OnWallpaperChangeLambdaFunction(uv_work_t * work,int status)1131 void NapiWallpaperAbility::OnWallpaperChangeLambdaFunction(uv_work_t *work, int status)
1132 {
1133     WallpaperChangedData *dataInner = reinterpret_cast<WallpaperChangedData *>(work->data);
1134     if (dataInner == nullptr) {
1135         delete work;
1136         return;
1137     }
1138     if (dataInner->listener == nullptr) {
1139         delete dataInner;
1140         delete work;
1141         return;
1142     }
1143     napi_handle_scope scope = nullptr;
1144     napi_open_handle_scope(dataInner->listener->env_, &scope);
1145     if (scope == nullptr) {
1146         delete dataInner;
1147         delete work;
1148         return;
1149     }
1150     napi_value jsWallpaperType = nullptr;
1151     napi_value jsResourceType = nullptr;
1152     napi_value jsResourceUri = nullptr;
1153     napi_create_int32(dataInner->listener->env_, dataInner->wallpaperType, &jsWallpaperType);
1154     napi_create_int32(dataInner->listener->env_, dataInner->resourceType, &jsResourceType);
1155     napi_create_string_utf8(dataInner->listener->env_, dataInner->uri.c_str(), dataInner->uri.length(), &jsResourceUri);
1156     napi_value callback = nullptr;
1157     napi_value args[3] = { jsWallpaperType, jsResourceType, jsResourceUri };
1158     napi_get_reference_value(dataInner->listener->env_, dataInner->listener->callback_, &callback);
1159     napi_value global = nullptr;
1160     napi_get_global(dataInner->listener->env_, &global);
1161     napi_value result;
1162     napi_status callStatus =
1163         napi_call_function(dataInner->listener->env_, global, callback, sizeof(args) / sizeof(args[0]), args, &result);
1164     if (callStatus != napi_ok) {
1165         HILOG_ERROR("notify data change failed, callStatus:%{public}d", callStatus);
1166     }
1167     napi_close_handle_scope(dataInner->listener->env_, scope);
1168     delete dataInner;
1169     delete work;
1170     return;
1171 }
1172 } // namespace WallpaperNAPI
1173 } // namespace OHOS
1174