1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "napi_wallpaper_ability.h"
17
18 #include <map>
19 #include <pthread.h>
20 #include <string>
21 #include <unistd.h>
22 #include <uv.h>
23 #include <vector>
24
25 #include "hilog_wrapper.h"
26 #include "wallpaper_manager.h"
27 #include "wallpaper_manager_common_info.h"
28
29 using namespace OHOS::Media;
30 namespace OHOS {
31 namespace WallpaperNAPI {
32 const int32_t ONE = 1;
33 const int32_t TWO = 2;
34
NAPI_GetColors(napi_env env,napi_callback_info info)35 napi_value NAPI_GetColors(napi_env env, napi_callback_info info)
36 {
37 HILOG_DEBUG("NAPI_GetColors in");
38 auto context = std::make_shared<GetContextInfo>();
39 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
40 return napi_ok;
41 };
42 auto output = [context](napi_env env, napi_value *result) -> napi_status { return napi_ok; };
43 auto exec = [context](AsyncCall::Context *ctx) {
44 context->SetErrInfo(AsyncCall::ErrorCode::NOT_SUPPORT, "not support");
45 HILOG_DEBUG("exec-----NAPI_GetColors in");
46 };
47 context->SetAction(std::move(input), std::move(output));
48 AsyncCall asyncCall(env, info, std::dynamic_pointer_cast<AsyncCall::Context>(context), ONE);
49 return asyncCall.Call(env, exec);
50 }
51
NAPI_GetId(napi_env env,napi_callback_info info)52 napi_value NAPI_GetId(napi_env env, napi_callback_info info)
53 {
54 HILOG_DEBUG("NAPI_GetId in");
55 auto context = std::make_shared<GetContextInfo>();
56 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
57 NAPI_ASSERT_BASE(env, argc == 1 || argc == 2, " should 1 or 2 parameters!", napi_invalid_arg);
58 HILOG_DEBUG("input ---- argc : %{public}d", argc);
59 napi_valuetype valueType = napi_undefined;
60 napi_typeof(env, argv[0], &valueType);
61 NAPI_ASSERT_BASE(env, valueType == napi_number, "param type wrong!", napi_invalid_arg);
62 napi_get_value_int32(env, argv[0], &context->wallpaperType);
63 HILOG_DEBUG("input ---- wallpaperType : %{public}d", context->wallpaperType);
64 return napi_ok;
65 };
66 auto output = [context](napi_env env, napi_value *result) -> napi_status {
67 napi_status status = napi_create_int32(env, context->wallpaperId, result);
68 HILOG_DEBUG("output ---- napi_create_int32[%{public}d]", status);
69 return status;
70 };
71 auto exec = [context](AsyncCall::Context *ctx) {
72 HILOG_DEBUG("exec ---- GetWallpaperId");
73 context->wallpaperId =
74 WallpaperMgrService::WallpaperManagerkits::GetInstance().GetWallpaperId(context->wallpaperType);
75 HILOG_DEBUG("exec ---- GetWallpaperId wallpaperId : %{public}d", context->wallpaperId);
76 context->status = napi_ok;
77 };
78 context->SetAction(std::move(input), std::move(output));
79 AsyncCall asyncCall(env, info, std::dynamic_pointer_cast<AsyncCall::Context>(context), 1);
80 return asyncCall.Call(env, exec);
81 }
82
NAPI_GetPixelMap(napi_env env,napi_callback_info info)83 napi_value NAPI_GetPixelMap(napi_env env, napi_callback_info info)
84 {
85 HILOG_DEBUG("NAPI_GetPixelMap in");
86 auto context = std::make_shared<GetContextInfo>();
87 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
88 NAPI_ASSERT_BASE(env, argc == 1 || argc == 2, " should 1 or 2 parameters!", napi_invalid_arg);
89 HILOG_DEBUG("input ---- argc : %{public}d", argc);
90 napi_valuetype valueType = napi_undefined;
91 napi_typeof(env, argv[0], &valueType);
92 NAPI_ASSERT_BASE(env, valueType == napi_number, "param type wrong!", napi_invalid_arg);
93 napi_get_value_int32(env, argv[0], &context->wallpaperType);
94 HILOG_DEBUG("input ---- wallpaperType : %{public}d", context->wallpaperType);
95 return napi_ok;
96 };
97 auto output = [context](napi_env env, napi_value *result) -> napi_status {
98 napi_value pixelVal = PixelMapNapi::CreatePixelMap(env, context->pixelMap);
99 HILOG_DEBUG("output ---- PixelMapNapi::CreatePixelMap != nullptr[%{public}d]", pixelVal != nullptr);
100 *result = pixelVal;
101 return napi_ok;
102 };
103 auto exec = [context](AsyncCall::Context *ctx) {
104 HILOG_DEBUG("exec ---- GetPixelMap");
105 auto pixel = WallpaperMgrService::WallpaperManagerkits::GetInstance().GetPixelMap(context->wallpaperType);
106 HILOG_DEBUG("exec ---- CreatPixelMap end");
107 if (pixel != nullptr) {
108 HILOG_DEBUG("exec ---- GetPixelMap pixel != nullptr");
109 context->status = napi_ok;
110 context->pixelMap = std::move(pixel);
111 HILOG_DEBUG("exec ---- GetPixelMap pixel != nullptr");
112 }
113 };
114 context->SetAction(std::move(input), std::move(output));
115 AsyncCall asyncCall(env, info, std::dynamic_pointer_cast<AsyncCall::Context>(context), 1);
116 return asyncCall.Call(env, exec);
117 }
118
NAPI_GetMinHeight(napi_env env,napi_callback_info info)119 napi_value NAPI_GetMinHeight(napi_env env, napi_callback_info info)
120 {
121 HILOG_DEBUG("NAPI_GetMinHeight in");
122 auto context = std::make_shared<GetMinContextInfo>();
123 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
124 NAPI_ASSERT_BASE(env, argc == 0 || argc == 1, " should 0 or 1 parameters!", napi_invalid_arg);
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->minHeight, result);
129 HILOG_DEBUG("output ---- napi_create_int32[%{public}d]", status);
130 return status;
131 };
132 auto exec = [context](AsyncCall::Context *ctx) {
133 HILOG_DEBUG("exec ---- GetWallpaperMinHeight");
134 context->minHeight = WallpaperMgrService::WallpaperManagerkits::GetInstance().GetWallpaperMinHeight();
135 HILOG_DEBUG("exec ---- GetWallpaperMinHeight minHeight : %{public}d", context->minHeight);
136 if (context->minHeight) {
137 context->status = napi_ok;
138 }
139 };
140 context->SetAction(std::move(input), std::move(output));
141 AsyncCall asyncCall(env, info, std::dynamic_pointer_cast<AsyncCall::Context>(context), 0);
142 return asyncCall.Call(env, exec);
143 }
144
NAPI_GetMinWidth(napi_env env,napi_callback_info info)145 napi_value NAPI_GetMinWidth(napi_env env, napi_callback_info info)
146 {
147 HILOG_DEBUG("NAPI_GetMinWidth in");
148 auto context = std::make_shared<GetMinContextInfo>();
149 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
150 NAPI_ASSERT_BASE(env, argc == 0 || argc == 1, " should 0 or 1 parameters!", napi_invalid_arg);
151 return napi_ok;
152 };
153 auto output = [context](napi_env env, napi_value *result) -> napi_status {
154 napi_status status = napi_create_int32(env, context->minWidth, result);
155 HILOG_DEBUG("output ---- napi_create_int32[%{public}d]", status);
156 return status;
157 };
158 auto exec = [context](AsyncCall::Context *ctx) {
159 HILOG_DEBUG("exec ---- GetWallpaperMinWidth");
160 context->minWidth = WallpaperMgrService::WallpaperManagerkits::GetInstance().GetWallpaperMinWidth();
161 HILOG_DEBUG("exec ---- GetWallpaperMinWidth minWidth : %{public}d", context->minWidth);
162 if (context->minWidth) {
163 context->status = napi_ok;
164 }
165 };
166 context->SetAction(std::move(input), std::move(output));
167 AsyncCall asyncCall(env, info, std::dynamic_pointer_cast<AsyncCall::Context>(context), 0);
168 return asyncCall.Call(env, exec);
169 }
170
NAPI_IsChangePermitted(napi_env env,napi_callback_info info)171 napi_value NAPI_IsChangePermitted(napi_env env, napi_callback_info info)
172 {
173 HILOG_DEBUG("NAPI_IsChangePermitted in");
174 auto context = std::make_shared<PermissionContextInfo>();
175 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
176 NAPI_ASSERT_BASE(env, argc == 0 || argc == 1, " should 0 or 1 parameters!", napi_invalid_arg);
177 return napi_ok;
178 };
179 auto output = [context](napi_env env, napi_value *result) -> napi_status {
180 napi_status status = napi_get_boolean(env, context->isChangePermitted, result);
181 HILOG_DEBUG("output ---- napi_get_boolean[%{public}d]", status);
182 return status;
183 };
184 auto exec = [context](AsyncCall::Context *ctx) {
185 HILOG_DEBUG("exec ---- IsChangePermitted");
186 context->isChangePermitted = WallpaperMgrService::WallpaperManagerkits::GetInstance().IsChangePermitted();
187 HILOG_DEBUG("exec ---- IsChangePermitted : %{public}d", context->isChangePermitted);
188 context->status = napi_ok;
189 };
190 context->SetAction(std::move(input), std::move(output));
191 AsyncCall asyncCall(env, info, std::dynamic_pointer_cast<AsyncCall::Context>(context), 0);
192 return asyncCall.Call(env, exec);
193 }
194
NAPI_IsOperationAllowed(napi_env env,napi_callback_info info)195 napi_value NAPI_IsOperationAllowed(napi_env env, napi_callback_info info)
196 {
197 HILOG_DEBUG("NAPI_IsOperationAllowed in");
198 auto context = std::make_shared<PermissionContextInfo>();
199 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
200 NAPI_ASSERT_BASE(env, argc == 0 || argc == 1, " should 0 or 1 parameters!", napi_invalid_arg);
201 return napi_ok;
202 };
203 auto output = [context](napi_env env, napi_value *result) -> napi_status {
204 napi_status status = napi_get_boolean(env, context->isOperationAllowed, result);
205 HILOG_DEBUG("output ---- napi_get_boolean[%{public}d]", status);
206 return status;
207 };
208 auto exec = [context](AsyncCall::Context *ctx) {
209 HILOG_DEBUG("exec ---- IsOperationAllowed");
210 context->isOperationAllowed = WallpaperMgrService::WallpaperManagerkits::GetInstance().IsOperationAllowed();
211 HILOG_DEBUG("exec ---- IsOperationAllowed[%{public}d]", context->isOperationAllowed);
212 context->status = napi_ok;
213 };
214 context->SetAction(std::move(input), std::move(output));
215 AsyncCall asyncCall(env, info, std::dynamic_pointer_cast<AsyncCall::Context>(context), 0);
216 return asyncCall.Call(env, exec);
217 }
218
NAPI_Reset(napi_env env,napi_callback_info info)219 napi_value NAPI_Reset(napi_env env, napi_callback_info info)
220 {
221 HILOG_DEBUG("NAPI_Reset in");
222 auto context = std::make_shared<SetContextInfo>();
223 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
224 NAPI_ASSERT_BASE(env, argc == 1 || argc == 2, " should 1 or 2 parameters!", napi_invalid_arg);
225 HILOG_DEBUG("input ---- argc : %{public}d", argc);
226 napi_valuetype valueType = napi_undefined;
227 napi_typeof(env, argv[0], &valueType);
228 NAPI_ASSERT_BASE(env, valueType == napi_number, "param type wrong!", napi_invalid_arg);
229 napi_get_value_int32(env, argv[0], &context->wallpaperType);
230 HILOG_DEBUG("input ---- wallpaperType : %{public}d", context->wallpaperType);
231 return napi_ok;
232 };
233 auto exec = [context](AsyncCall::Context *ctx) {
234 HILOG_DEBUG("exec ---- ResetWallpaper");
235 bool status = WallpaperMgrService::WallpaperManagerkits::GetInstance().ResetWallpaper(context->wallpaperType);
236 HILOG_DEBUG("exec ---- ResetWallpaper[%{public}d]", status);
237 if (status) {
238 context->status = napi_ok;
239 }
240 HILOG_DEBUG("exec ---- status[%{public}d], context->status[%{public}d]", status, context->status);
241 };
242 context->SetAction(std::move(input));
243 AsyncCall asyncCall(env, info, std::dynamic_pointer_cast<AsyncCall::Context>(context), 1);
244 return asyncCall.Call(env, exec);
245 }
246
NAPI_SetWallpaper(napi_env env,napi_callback_info info)247 napi_value NAPI_SetWallpaper(napi_env env, napi_callback_info info)
248 {
249 auto context = std::make_shared<SetContextInfo>();
250 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
251 NAPI_ASSERT_BASE(env, argc == 2 || argc == 3, " should 2 or 3 parameters!", napi_invalid_arg);
252 HILOG_DEBUG("input ---- argc : %{public}d", argc);
253 napi_valuetype valueType = napi_undefined;
254 napi_typeof(env, argv[0], &valueType);
255 NAPI_ASSERT_BASE(env, valueType == napi_string || valueType == napi_object, "first param type wrong!",
256 napi_invalid_arg);
257 if (valueType == napi_string) {
258 context->url = WallpaperJSUtil::Convert2String(env, argv[0]);
259 } else {
260 std::shared_ptr<PixelMap> tmpPixelMap = PixelMapNapi::GetPixelMap(env, argv[0]);
261 if (tmpPixelMap == nullptr) {
262 HILOG_ERROR("PixelMapNapi::GetPixelMap error");
263 context->isPixelEmp = true;
264 return napi_generic_failure;
265 } else {
266 context->isPixelEmp = false;
267 }
268 context->pixelMap = std::make_unique<PixelMap>(*tmpPixelMap);
269 }
270 valueType = napi_undefined;
271 napi_typeof(env, argv[1], &valueType);
272 NAPI_ASSERT_BASE(env, valueType == napi_number, "second param type wrong!", napi_invalid_arg);
273 napi_get_value_int32(env, argv[1], &context->wallpaperType);
274 HILOG_DEBUG("input ---- wallpaperType : %{public}d", context->wallpaperType);
275 return napi_ok;
276 };
277 auto exec = [context](AsyncCall::Context *ctx) {
278 bool urlret = false;
279 if (context->url.length() == 0) {
280 HILOG_DEBUG("exec ---- setWallpaper by pixelMap");
281 if (!context->isPixelEmp) {
282 urlret = WallpaperMgrService::WallpaperManagerkits::GetInstance().SetWallpaper(context->pixelMap,
283 context->wallpaperType);
284 }
285 } else {
286 HILOG_DEBUG("exec ---- setWallpaper by url");
287 urlret = WallpaperMgrService::WallpaperManagerkits::GetInstance().SetWallpaper(context->url,
288 context->wallpaperType);
289 }
290 if (urlret) {
291 context->status = napi_ok;
292 }
293 HILOG_DEBUG("exec ---- context->status[%{public}d]", context->status);
294 };
295 context->SetAction(std::move(input));
296 AsyncCall asyncCall(env, info, std::dynamic_pointer_cast<AsyncCall::Context>(context), TWO);
297 return asyncCall.Call(env, exec);
298 }
299
NAPI_ScreenshotLiveWallpaper(napi_env env,napi_callback_info info)300 napi_value NAPI_ScreenshotLiveWallpaper(napi_env env, napi_callback_info info)
301 {
302 HILOG_DEBUG("NAPI_ScreenshotLiveWallpaper in");
303 auto context = std::make_shared<GetContextInfo>();
304 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
305 return napi_ok;
306 };
307 auto output = [context](napi_env env, napi_value *result) -> napi_status { return napi_ok; };
308 auto exec = [context](AsyncCall::Context *ctx) {
309 context->SetErrInfo(AsyncCall::ErrorCode::NOT_SUPPORT, "not support");
310 HILOG_DEBUG("exec-----NAPI_ScreenshotLiveWallpaper in");
311 };
312 context->SetAction(std::move(input), std::move(output));
313 AsyncCall asyncCall(env, info, std::dynamic_pointer_cast<AsyncCall::Context>(context), TWO);
314 return asyncCall.Call(env, exec);
315 }
316
317 std::shared_ptr<WallpaperMgrService::WallpaperColorChangeListener> colorChangeListener_;
318
NAPI_On(napi_env env,napi_callback_info info)319 napi_value NAPI_On(napi_env env, napi_callback_info info)
320 {
321 HILOG_DEBUG("NAPI_On in");
322 auto context = std::make_shared<GetContextInfo>();
323 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
324 return napi_ok;
325 };
326 auto output = [context](napi_env env, napi_value *result) -> napi_status { return napi_ok; };
327 auto exec = [context](AsyncCall::Context *ctx) {
328 context->SetErrInfo(AsyncCall::ErrorCode::NOT_SUPPORT, "not support");
329 HILOG_DEBUG("exec-----NAPI_On in");
330 };
331 context->SetAction(std::move(input), std::move(output));
332 AsyncCall asyncCall(env, info, std::dynamic_pointer_cast<AsyncCall::Context>(context), ONE);
333 return asyncCall.Call(env, exec);
334 }
335
NAPI_Off(napi_env env,napi_callback_info info)336 napi_value NAPI_Off(napi_env env, napi_callback_info info)
337 {
338 HILOG_DEBUG("NAPI_Off in");
339 auto context = std::make_shared<GetContextInfo>();
340 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
341 return napi_ok;
342 };
343 auto output = [context](napi_env env, napi_value *result) -> napi_status { return napi_ok; };
344 auto exec = [context](AsyncCall::Context *ctx) {
345 context->SetErrInfo(AsyncCall::ErrorCode::NOT_SUPPORT, "not support");
346 HILOG_DEBUG("exec-----NAPI_Off in");
347 };
348 context->SetAction(std::move(input), std::move(output));
349 AsyncCall asyncCall(env, info, std::dynamic_pointer_cast<AsyncCall::Context>(context), ONE);
350 return asyncCall.Call(env, exec);
351 }
352
NAPI_GetFile(napi_env env,napi_callback_info info)353 napi_value NAPI_GetFile(napi_env env, napi_callback_info info)
354 {
355 HILOG_DEBUG("NAPI_GetFile in");
356 auto context = std::make_shared<GetFileContextInfo>();
357 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
358 return napi_ok;
359 };
360
361 auto output = [context](napi_env env, napi_value *result) -> napi_status { return napi_ok; };
362 auto exec = [context](AsyncCall::Context *ctx) {
363 context->SetErrInfo(AsyncCall::ErrorCode::NOT_SUPPORT, "not support");
364 HILOG_DEBUG("exec ---- NAPI_GetFile in");
365 };
366 context->SetAction(std::move(input), std::move(output));
367 AsyncCall asyncCall(env, info, std::dynamic_pointer_cast<AsyncCall::Context>(context), 1);
368 return asyncCall.Call(env, exec);
369 }
370
NapiWallpaperAbility(napi_env env,napi_value callback)371 NapiWallpaperAbility::NapiWallpaperAbility(napi_env env, napi_value callback) : env_(env)
372 {
373 napi_create_reference(env, callback, 1, &callback_);
374 napi_get_uv_event_loop(env, &loop_);
375 }
376
~NapiWallpaperAbility()377 NapiWallpaperAbility::~NapiWallpaperAbility()
378 {
379 napi_delete_reference(env_, callback_);
380 }
381
onColorsChange(std::vector<RgbaColor> color,int wallpaperType)382 void NapiWallpaperAbility::onColorsChange(std::vector<RgbaColor> color, int wallpaperType)
383 {
384 WallpaperMgrService::WallpaperColorChangeListener::onColorsChange(color, wallpaperType);
385 EventDataWorker *eventDataWorker = new (std::nothrow)
386 EventDataWorker(this->shared_from_this(), color, wallpaperType);
387 if (eventDataWorker == nullptr) {
388 return;
389 }
390 uv_work_t *work = new (std::nothrow) uv_work_t;
391 if (work == nullptr) {
392 delete eventDataWorker;
393 return;
394 }
395
396 work->data = eventDataWorker;
397 uv_queue_work(
398 loop_, work, [](uv_work_t *work) {},
399 [](uv_work_t *work, int status) {
400 EventDataWorker *eventDataInner = reinterpret_cast<EventDataWorker *>(work->data);
401 if (eventDataInner == nullptr || eventDataInner->listener == nullptr) {
402 delete work;
403 return;
404 }
405 napi_handle_scope scope = nullptr;
406 napi_open_handle_scope(eventDataInner->listener->env_, &scope);
407 if (scope == nullptr) {
408 delete eventDataInner;
409 delete work;
410 return;
411 }
412 napi_value jsWallpaperType = nullptr;
413 napi_create_int32(eventDataInner->listener->env_, eventDataInner->wallpaperType, &jsWallpaperType);
414 napi_value jsRgbaArray =
415 WallpaperJSUtil::Convert2JSRgbaArray(eventDataInner->listener->env_, eventDataInner->color);
416 napi_value callback = nullptr;
417 napi_value args[2] = { jsRgbaArray, jsWallpaperType };
418 napi_get_reference_value(eventDataInner->listener->env_, eventDataInner->listener->callback_, &callback);
419 napi_value global = nullptr;
420 napi_get_global(eventDataInner->listener->env_, &global);
421 napi_value result;
422 napi_status callStatus =
423 napi_call_function(eventDataInner->listener->env_, global, callback, 1, args, &result);
424 if (callStatus != napi_ok) {
425 HILOG_ERROR("notify data change failed callStatus:%{public}d callback:%{public}p", callStatus,
426 callback);
427 }
428 napi_close_handle_scope(eventDataInner->listener->env_, scope);
429 delete eventDataInner;
430 delete work;
431 });
432 }
433 } // namespace WallpaperNAPI
434 } // namespace OHOS
435