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