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