1 /*
2 * Copyright (c) 2021-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 #include "js_err_utils.h"
16 #include "js_window_manager.h"
17 #include <ability.h>
18 #include <cinttypes>
19 #include <hitrace_meter.h>
20 #include <new>
21 #include <transaction/rs_interfaces.h>
22 #include "ability_context.h"
23 #include "display_manager.h"
24 #include "dm_common.h"
25 #include "wm_common.h"
26 #include "js_window.h"
27 #include "js_window_utils.h"
28 #include "window_helper.h"
29 #include "window_manager_hilog.h"
30 #include "window_option.h"
31 #include "pixel_map_napi.h"
32 #include "permission.h"
33 #include "singleton_container.h"
34
35 namespace OHOS {
36 namespace Rosen {
37 using namespace AbilityRuntime;
38 namespace {
39 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "JsWindowManager"};
40 const std::string PIP_WINDOW = "pip_window";
41 constexpr size_t ARGC_ONE = 1;
42 constexpr size_t ARGC_TWO = 2;
43 constexpr size_t ARGC_THREE = 3;
44 constexpr size_t ARGC_FOUR = 4;
45 constexpr int32_t INVALID_COORDINATE = -1;
46 }
47
JsWindowManager()48 JsWindowManager::JsWindowManager() : registerManager_(std::make_unique<JsWindowRegisterManager>())
49 {
50 }
51
~JsWindowManager()52 JsWindowManager::~JsWindowManager()
53 {
54 }
55
Finalizer(napi_env env,void * data,void * hint)56 void JsWindowManager::Finalizer(napi_env env, void* data, void* hint)
57 {
58 WLOGI("Finalizer");
59 std::unique_ptr<JsWindowManager>(static_cast<JsWindowManager*>(data));
60 }
61
Create(napi_env env,napi_callback_info info)62 napi_value JsWindowManager::Create(napi_env env, napi_callback_info info)
63 {
64 JsWindowManager* me = CheckParamsAndGetThis<JsWindowManager>(env, info);
65 return (me != nullptr) ? me->OnCreate(env, info) : nullptr;
66 }
67
CreateWindow(napi_env env,napi_callback_info info)68 napi_value JsWindowManager::CreateWindow(napi_env env, napi_callback_info info)
69 {
70 JsWindowManager* me = CheckParamsAndGetThis<JsWindowManager>(env, info);
71 return (me != nullptr) ? me->OnCreateWindow(env, info) : nullptr;
72 }
73
FindWindow(napi_env env,napi_callback_info info)74 napi_value JsWindowManager::FindWindow(napi_env env, napi_callback_info info)
75 {
76 JsWindowManager* me = CheckParamsAndGetThis<JsWindowManager>(env, info);
77 return (me != nullptr) ? me->OnFindWindow(env, info) : nullptr;
78 }
79
FindWindowSync(napi_env env,napi_callback_info info)80 napi_value JsWindowManager::FindWindowSync(napi_env env, napi_callback_info info)
81 {
82 JsWindowManager* me = CheckParamsAndGetThis<JsWindowManager>(env, info);
83 return (me != nullptr) ? me->OnFindWindowSync(env, info) : nullptr;
84 }
85
MinimizeAll(napi_env env,napi_callback_info info)86 napi_value JsWindowManager::MinimizeAll(napi_env env, napi_callback_info info)
87 {
88 JsWindowManager* me = CheckParamsAndGetThis<JsWindowManager>(env, info);
89 return (me != nullptr) ? me->OnMinimizeAll(env, info) : nullptr;
90 }
91
ToggleShownStateForAllAppWindows(napi_env env,napi_callback_info info)92 napi_value JsWindowManager::ToggleShownStateForAllAppWindows(napi_env env, napi_callback_info info)
93 {
94 JsWindowManager* me = CheckParamsAndGetThis<JsWindowManager>(env, info);
95 return (me != nullptr) ? me->OnToggleShownStateForAllAppWindows(env, info) : nullptr;
96 }
97
RegisterWindowManagerCallback(napi_env env,napi_callback_info info)98 napi_value JsWindowManager::RegisterWindowManagerCallback(napi_env env, napi_callback_info info)
99 {
100 JsWindowManager* me = CheckParamsAndGetThis<JsWindowManager>(env, info);
101 return (me != nullptr) ? me->OnRegisterWindowManagerCallback(env, info) : nullptr;
102 }
103
UnregisterWindowMangerCallback(napi_env env,napi_callback_info info)104 napi_value JsWindowManager::UnregisterWindowMangerCallback(napi_env env, napi_callback_info info)
105 {
106 JsWindowManager* me = CheckParamsAndGetThis<JsWindowManager>(env, info);
107 return (me != nullptr) ? me->OnUnregisterWindowManagerCallback(env, info) : nullptr;
108 }
109
GetTopWindow(napi_env env,napi_callback_info info)110 napi_value JsWindowManager::GetTopWindow(napi_env env, napi_callback_info info)
111 {
112 JsWindowManager* me = CheckParamsAndGetThis<JsWindowManager>(env, info);
113 return (me != nullptr) ? me->OnGetTopWindow(env, info) : nullptr;
114 }
115
116 /** @note @window.hierarchy */
GetLastWindow(napi_env env,napi_callback_info info)117 napi_value JsWindowManager::GetLastWindow(napi_env env, napi_callback_info info)
118 {
119 JsWindowManager* me = CheckParamsAndGetThis<JsWindowManager>(env, info);
120 return (me != nullptr) ? me->OnGetLastWindow(env, info) : nullptr;
121 }
122
GetSnapshot(napi_env env,napi_callback_info info)123 napi_value JsWindowManager::GetSnapshot(napi_env env, napi_callback_info info)
124 {
125 JsWindowManager* me = CheckParamsAndGetThis<JsWindowManager>(env, info);
126 return (me != nullptr) ? me->OnGetSnapshot(env, info) : nullptr;
127 }
128
SetWindowLayoutMode(napi_env env,napi_callback_info info)129 napi_value JsWindowManager::SetWindowLayoutMode(napi_env env, napi_callback_info info)
130 {
131 JsWindowManager* me = CheckParamsAndGetThis<JsWindowManager>(env, info);
132 return (me != nullptr) ? me->OnSetWindowLayoutMode(env, info) : nullptr;
133 }
134
SetGestureNavigationEnabled(napi_env env,napi_callback_info info)135 napi_value JsWindowManager::SetGestureNavigationEnabled(napi_env env, napi_callback_info info)
136 {
137 JsWindowManager* me = CheckParamsAndGetThis<JsWindowManager>(env, info);
138 return (me != nullptr) ? me->OnSetGestureNavigationEnabled(env, info) : nullptr;
139 }
140
SetWaterMarkImage(napi_env env,napi_callback_info info)141 napi_value JsWindowManager::SetWaterMarkImage(napi_env env, napi_callback_info info)
142 {
143 JsWindowManager* me = CheckParamsAndGetThis<JsWindowManager>(env, info);
144 return (me != nullptr) ? me->OnSetWaterMarkImage(env, info) : nullptr;
145 }
146
ShiftAppWindowFocus(napi_env env,napi_callback_info info)147 napi_value JsWindowManager::ShiftAppWindowFocus(napi_env env, napi_callback_info info)
148 {
149 JsWindowManager* me = CheckParamsAndGetThis<JsWindowManager>(env, info);
150 return (me != nullptr) ? me->OnShiftAppWindowFocus(env, info) : nullptr;
151 }
152
GetVisibleWindowInfo(napi_env env,napi_callback_info info)153 napi_value JsWindowManager::GetVisibleWindowInfo(napi_env env, napi_callback_info info)
154 {
155 JsWindowManager* me = CheckParamsAndGetThis<JsWindowManager>(env, info);
156 return (me != nullptr) ? me->OnGetVisibleWindowInfo(env, info) : nullptr;
157 }
158
GetWindowsByCoordinate(napi_env env,napi_callback_info info)159 napi_value JsWindowManager::GetWindowsByCoordinate(napi_env env, napi_callback_info info)
160 {
161 JsWindowManager* me = CheckParamsAndGetThis<JsWindowManager>(env, info);
162 return (me != nullptr) ? me->OnGetWindowsByCoordinate(env, info) : nullptr;
163 }
164
GetNativeContext(napi_env env,napi_value nativeContext,void * & contextPtr,WMError & errCode)165 static void GetNativeContext(napi_env env, napi_value nativeContext, void*& contextPtr, WMError& errCode)
166 {
167 AppExecFwk::Ability* ability = nullptr;
168 bool isOldApi = GetAPI7Ability(env, ability);
169 WLOGFD("FA mode:%{public}u", isOldApi);
170 if (isOldApi) {
171 return;
172 }
173 if (nativeContext != nullptr) {
174 napi_unwrap(env, nativeContext, &contextPtr);
175 }
176 }
177
GetParentId(napi_env env)178 static uint32_t GetParentId(napi_env env)
179 {
180 AppExecFwk::Ability* ability = nullptr;
181 uint32_t parentId = 0;
182 bool isOldApi = GetAPI7Ability(env, ability);
183 if (isOldApi) {
184 if (ability == nullptr) {
185 WLOGE("FA mode GetAPI7Ability failed");
186 return parentId;
187 }
188 auto window = ability->GetWindow();
189 if (window == nullptr) {
190 WLOGE("Get mainWindow failed");
191 return parentId;
192 }
193 parentId = window->GetWindowId();
194 }
195 return parentId;
196 }
197
GetWindowTypeAndParentId(napi_env env,uint32_t & parentId,WindowType & winType,napi_value nativeString,napi_value nativeType)198 static bool GetWindowTypeAndParentId(napi_env env, uint32_t& parentId, WindowType& winType,
199 napi_value nativeString, napi_value nativeType)
200 {
201 napi_value type = nativeType;
202 if (type == nullptr) {
203 WLOGFE("Failed to convert parameter to windowType");
204 return false;
205 }
206 uint32_t resultValue = 0;
207 napi_get_value_uint32(env, type, &resultValue);
208 if (resultValue >= static_cast<uint32_t>(ApiWindowType::TYPE_BASE) &&
209 resultValue < static_cast<uint32_t>(ApiWindowType::TYPE_END)) {
210 winType = JS_TO_NATIVE_WINDOW_TYPE_MAP.at(static_cast<ApiWindowType>(resultValue));
211 } else {
212 WLOGFE("Type %{public}u is not supported", resultValue);
213 return false;
214 }
215
216 AppExecFwk::Ability* ability = nullptr;
217 bool isOldApi = GetAPI7Ability(env, ability);
218 if (isOldApi) {
219 if (ability == nullptr || !WindowHelper::IsSubWindow(winType)) {
220 WLOGE("FA mode GetAPI7Ability failed or type %{public}u is not subWinodw", winType);
221 return false;
222 }
223 auto window = ability->GetWindow();
224 if (window == nullptr) {
225 WLOGE("Get mainWindow failed");
226 return false;
227 }
228 parentId = window->GetWindowId();
229 } else {
230 if (!WindowHelper::IsSystemWindow(winType)) {
231 WLOGFE("Only SystemWindow support create in stage mode, type is %{public}u", winType);
232 return false;
233 }
234 }
235 return true;
236 }
237
CreateNewSystemWindowTask(void * contextPtr,sptr<WindowOption> windowOption,napi_env env,NapiAsyncTask & task)238 static void CreateNewSystemWindowTask(void* contextPtr, sptr<WindowOption> windowOption,
239 napi_env env, NapiAsyncTask& task)
240 {
241 WLOGI("CreateSystemWindowTask");
242 if (windowOption == nullptr) {
243 task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_SYSTEM_ABNORMALLY,
244 "New window option failed"));
245 WLOGFE("New window option failed");
246 return;
247 }
248 auto context = static_cast<std::weak_ptr<AbilityRuntime::Context>*>(contextPtr);
249 if (contextPtr == nullptr || context == nullptr) {
250 task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_CONTEXT_ABNORMALLY,
251 "Context is nullptr"));
252 WLOGFE("Context is nullptr");
253 return;
254 }
255 if (windowOption->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT ||
256 windowOption->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT_CAMERA) {
257 auto abilityContext = Context::ConvertTo<AbilityRuntime::AbilityContext>(context->lock());
258 if (abilityContext != nullptr) {
259 if (!CheckCallingPermission("ohos.permission.SYSTEM_FLOAT_WINDOW")) {
260 task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_NO_PERMISSION,
261 "TYPE_FLOAT CheckCallingPermission failed"));
262 return;
263 }
264 }
265 }
266 WMError wmError = WMError::WM_OK;
267 sptr<Window> window = Window::Create(windowOption->GetWindowName(), windowOption, context->lock(), wmError);
268 WmErrorCode wmErrorCode = WM_JS_TO_ERROR_CODE_MAP.at(wmError);
269 if (window != nullptr && wmErrorCode == WmErrorCode::WM_OK) {
270 task.Resolve(env, CreateJsWindowObject(env, window));
271 } else {
272 WLOGFE("Create window failed");
273 task.Reject(env, JsErrUtils::CreateJsError(env, wmErrorCode, "Create window failed"));
274 }
275 }
276
CreateSystemWindowTask(void * contextPtr,std::string windowName,WindowType winType,napi_env env,NapiAsyncTask & task)277 static void CreateSystemWindowTask(void* contextPtr, std::string windowName, WindowType winType,
278 napi_env env, NapiAsyncTask& task)
279 {
280 WLOGFD("CreateSystemWindowTask");
281 auto context = static_cast<std::weak_ptr<AbilityRuntime::Context>*>(contextPtr);
282 if (contextPtr == nullptr || context == nullptr) {
283 task.Reject(env, JsErrUtils::CreateJsError(env, WMError::WM_ERROR_NULLPTR, "Context is nullptr"));
284 WLOGFE("Context is nullptr");
285 return;
286 }
287 if (winType == WindowType::WINDOW_TYPE_FLOAT || winType == WindowType::WINDOW_TYPE_FLOAT_CAMERA) {
288 auto abilityContext = Context::ConvertTo<AbilityRuntime::AbilityContext>(context->lock());
289 if (abilityContext != nullptr) {
290 if (!CheckCallingPermission("ohos.permission.SYSTEM_FLOAT_WINDOW")) {
291 task.Reject(env, JsErrUtils::CreateJsError(env, WMError::WM_ERROR_INVALID_PERMISSION,
292 "TYPE_FLOAT CheckCallingPermission failed"));
293 return;
294 }
295 }
296 }
297 sptr<WindowOption> windowOption = new(std::nothrow) WindowOption();
298 if (windowOption == nullptr) {
299 task.Reject(env, JsErrUtils::CreateJsError(env, WMError::WM_ERROR_NULLPTR, "New window option failed"));
300 WLOGFE("New window option failed");
301 return;
302 }
303 windowOption->SetWindowType(winType);
304 WMError wmError = WMError::WM_OK;
305 sptr<Window> window = Window::Create(windowName, windowOption, context->lock(), wmError);
306 WmErrorCode wmErrorCode = WM_JS_TO_ERROR_CODE_MAP.at(wmError);
307 if (window != nullptr && wmErrorCode == WmErrorCode::WM_OK) {
308 task.Resolve(env, CreateJsWindowObject(env, window));
309 } else {
310 WLOGFE("Create window failed");
311 task.Reject(env, JsErrUtils::CreateJsError(env, wmErrorCode, "Create window failed"));
312 }
313 }
314
CreateNewSubWindowTask(sptr<WindowOption> windowOption,napi_env env,NapiAsyncTask & task)315 static void CreateNewSubWindowTask(sptr<WindowOption> windowOption, napi_env env, NapiAsyncTask& task)
316 {
317 if (windowOption == nullptr) {
318 task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_SYSTEM_ABNORMALLY,
319 "New window option failed"));
320 WLOGFE("New window option failed");
321 return;
322 }
323 windowOption->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_FLOATING);
324 if (windowOption->GetParentId() == INVALID_WINDOW_ID) {
325 uint32_t parentId = GetParentId(env);
326 if (!parentId) {
327 task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY,
328 "parent window missed"));
329 WLOGFE("can not find parent window");
330 return;
331 }
332 windowOption->SetParentId(parentId);
333 }
334 sptr<Window> window = Window::Create(windowOption->GetWindowName(), windowOption);
335 if (window != nullptr) {
336 task.Resolve(env, CreateJsWindowObject(env, window));
337 } else {
338 WLOGFE("Create window failed");
339 task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY,
340 "Create window failed"));
341 }
342 }
343
CreateSubWindowTask(uint32_t parentWinId,std::string windowName,WindowType winType,napi_env env,NapiAsyncTask & task,bool newErrorCode=false)344 static void CreateSubWindowTask(uint32_t parentWinId, std::string windowName, WindowType winType,
345 napi_env env, NapiAsyncTask& task, bool newErrorCode = false)
346 {
347 WLOGI("CreateSubWindowTask, parent id = %{public}u", parentWinId);
348 sptr<WindowOption> windowOption = new(std::nothrow) WindowOption();
349 if (windowOption == nullptr) {
350 if (newErrorCode) {
351 task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_SYSTEM_ABNORMALLY,
352 "New window option failed"));
353 } else {
354 task.Reject(env, JsErrUtils::CreateJsError(env, WMError::WM_ERROR_NULLPTR, "New window option failed"));
355 }
356 WLOGFE("New window option failed");
357 return;
358 }
359 windowOption->SetWindowType(winType);
360 windowOption->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_FLOATING);
361 windowOption->SetParentId(parentWinId);
362 sptr<Window> window = Window::Create(windowName, windowOption);
363 if (window != nullptr) {
364 task.Resolve(env, CreateJsWindowObject(env, window));
365 } else {
366 WLOGFE("Create window failed");
367 if (newErrorCode) {
368 task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY,
369 "Create window failed"));
370 } else {
371 task.Reject(env, JsErrUtils::CreateJsError(env, WMError::WM_ERROR_NULLPTR, "Create window failed"));
372 }
373 }
374 }
375
isConfigOptionWindowTypeValid(napi_env env,WindowOption & option)376 static bool isConfigOptionWindowTypeValid(napi_env env, WindowOption& option)
377 {
378 WindowType type = option.GetWindowType();
379 AppExecFwk::Ability* ability = nullptr;
380 bool isOldApi = GetAPI7Ability(env, ability);
381 if (isOldApi) {
382 if (ability == nullptr || !WindowHelper::IsSubWindow(type)) {
383 WLOGE("FA mode GetAPI7Ability failed or convert parameter to invalid winType %{public}u", type);
384 return false;
385 }
386 } else {
387 if (!WindowHelper::IsSystemWindow(type)) {
388 WLOGFE("Stage mode convert parameter to invalid winType %{public}u", type);
389 return false;
390 }
391 }
392
393 return true;
394 }
395
OnCreate(napi_env env,napi_callback_info info)396 napi_value JsWindowManager::OnCreate(napi_env env, napi_callback_info info)
397 {
398 WLOGFD("OnCreate");
399 napi_value nativeString = nullptr, nativeContext = nullptr, nativeType = nullptr, callback = nullptr;
400 size_t argc = 4;
401 napi_value argv[4] = {nullptr};
402 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
403 if (argc >= 2 && GetType(env, argv[0]) == napi_string) { // 2: minimum params num
404 nativeString = argv[0];
405 nativeType = argv[1];
406 callback = (argc == 2) ? nullptr : (GetType(env, argv[2]) == napi_function ? argv[2] : nullptr); // 2: index
407 } else if (argc >= 3) { // 3: minimum params num
408 nativeContext = GetType(env, argv[0]) == napi_object ? argv[0] : nullptr;
409 nativeString = argv[1];
410 nativeType = argv[2]; // 2: index of type
411 callback = (argc == 3) ? nullptr : (GetType(env, argv[3]) == napi_function ? argv[3] : nullptr); // 3: index
412 }
413 std::string windowName;
414 WMError errCode = WMError::WM_OK;
415 if (!ConvertFromJsValue(env, nativeString, windowName)) {
416 WLOGFE("Failed to convert parameter to windowName");
417 errCode = WMError::WM_ERROR_INVALID_PARAM;
418 }
419 uint32_t parentId = INVALID_WINDOW_ID;
420 WindowType winType = WindowType::SYSTEM_WINDOW_BASE;
421 if (errCode == WMError::WM_OK &&
422 !GetWindowTypeAndParentId(env, parentId, winType, nativeString, nativeType)) {
423 errCode = WMError::WM_ERROR_INVALID_PARAM;
424 }
425 void* contextPtr = nullptr;
426 GetNativeContext(env, nativeContext, contextPtr, errCode);
427
428 WLOGFD("Window name = %{public}s, type = %{public}u, err = %{public}d", windowName.c_str(), winType, errCode);
429 NapiAsyncTask::CompleteCallback complete =
430 [=](napi_env env, NapiAsyncTask& task, int32_t status) {
431 if (errCode != WMError::WM_OK) {
432 task.Reject(env, JsErrUtils::CreateJsError(env, errCode, "Invalidate params"));
433 return;
434 }
435 if (parentId == INVALID_WINDOW_ID) {
436 return CreateSystemWindowTask(contextPtr, windowName, winType, env, task);
437 } else {
438 return CreateSubWindowTask(parentId, windowName, winType, env, task);
439 }
440 };
441 napi_value result = nullptr;
442 NapiAsyncTask::Schedule("JsWindowManager::OnCreate", env,
443 CreateAsyncTaskWithLastParam(env, callback, nullptr, std::move(complete), &result));
444 return result;
445 }
446
ParseRequiredConfigOption(napi_env env,napi_value jsObject,WindowOption & option)447 bool JsWindowManager::ParseRequiredConfigOption(napi_env env, napi_value jsObject,
448 WindowOption& option)
449 {
450 std::string windowName;
451 if (ParseJsValue(jsObject, env, "name", windowName)) {
452 option.SetWindowName(windowName);
453 } else {
454 WLOGFE("Failed to convert parameter to windowName");
455 return false;
456 }
457
458 uint32_t winType;
459 if (ParseJsValue(jsObject, env, "windowType", winType)) {
460 if (winType >= static_cast<uint32_t>(ApiWindowType::TYPE_BASE) &&
461 winType < static_cast<uint32_t>(ApiWindowType::TYPE_END)) {
462 option.SetWindowType(JS_TO_NATIVE_WINDOW_TYPE_MAP.at(static_cast<ApiWindowType>(winType)));
463 } else {
464 TLOGE(WmsLogTag::DEFAULT, "Invalid winType");
465 return false;
466 }
467 } else {
468 WLOGFE("Failed to convert parameter to winType");
469 return false;
470 }
471 return true;
472 }
473
ParseConfigOption(napi_env env,napi_value jsObject,WindowOption & option,void * & contextPtr)474 bool JsWindowManager::ParseConfigOption(napi_env env, napi_value jsObject,
475 WindowOption& option, void*& contextPtr)
476 {
477 if (!ParseRequiredConfigOption(env, jsObject, option)) {
478 return false;
479 }
480 if (!isConfigOptionWindowTypeValid(env, option)) {
481 return false;
482 }
483 napi_value value = nullptr;
484 napi_get_named_property(env, jsObject, "ctx", &value);
485 if (GetType(env, value) == napi_undefined) {
486 return true;
487 }
488 WMError errCode = WMError::WM_OK;
489 GetNativeContext(env, value, contextPtr, errCode);
490 if (errCode != WMError::WM_OK) {
491 return false;
492 }
493
494 bool dialogDecorEnable = false;
495 if (ParseJsValue(jsObject, env, "decorEnabled", dialogDecorEnable)) {
496 option.SetDialogDecorEnable(dialogDecorEnable);
497 }
498
499 std::string dialogTitle;
500 if (ParseJsValue(jsObject, env, "title", dialogTitle)) {
501 option.SetDialogTitle(dialogTitle);
502 }
503
504 int64_t displayId = static_cast<int64_t>(DISPLAY_ID_INVALID);
505 if (ParseJsValue(jsObject, env, "displayId", displayId)) {
506 if (displayId < 0 ||
507 SingletonContainer::Get<DisplayManager>().GetDisplayById(static_cast<uint64_t>(displayId)) == nullptr) {
508 return false;
509 }
510 option.SetDisplayId(displayId);
511 } else {
512 return true;
513 }
514
515 int64_t parentId = -1;
516 if (ParseJsValue(jsObject, env, "parentId", parentId)) {
517 option.SetParentId(parentId);
518 }
519
520 return true;
521 }
522
OnCreateWindow(napi_env env,napi_callback_info info)523 napi_value JsWindowManager::OnCreateWindow(napi_env env, napi_callback_info info)
524 {
525 WLOGFD("Called");
526 size_t argc = 4;
527 napi_value argv[4] = {nullptr};
528 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
529 if (argc < 1) {
530 napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
531 return NapiGetUndefined(env);
532 }
533 napi_value nativeObj = argv[0];
534 if (nativeObj == nullptr) {
535 WLOGFE("Failed to convert object to CreateWindow");
536 napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
537 return NapiGetUndefined(env);
538 }
539 WindowOption option;
540 void* contextPtr = nullptr;
541 if (!ParseConfigOption(env, nativeObj, option, contextPtr)) {
542 WLOGFE("Failed to parse config");
543 napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
544 return NapiGetUndefined(env);
545 }
546 napi_value callback = nullptr;
547 if (argc > 1) {
548 callback = GetType(env, argv[1]) == napi_function ? argv[1] : nullptr; // 1: index of callback
549 }
550 NapiAsyncTask::CompleteCallback complete =
551 [=](napi_env env, NapiAsyncTask& task, int32_t status) {
552 sptr<WindowOption> windowOption = new WindowOption(option);
553 if (WindowHelper::IsSystemWindow(option.GetWindowType())) {
554 return CreateNewSystemWindowTask(contextPtr, windowOption, env, task);
555 }
556 if (WindowHelper::IsSubWindow(option.GetWindowType())) {
557 return CreateNewSubWindowTask(windowOption, env, task);
558 }
559 };
560
561 napi_value result = nullptr;
562 NapiAsyncTask::Schedule("JsWindowManager::OnCreateWindow", env,
563 CreateAsyncTaskWithLastParam(env, callback, nullptr, std::move(complete), &result));
564 return result;
565 }
566
OnGetSnapshot(napi_env env,napi_callback_info info)567 napi_value JsWindowManager::OnGetSnapshot(napi_env env, napi_callback_info info)
568 {
569 constexpr int maxArgumentsNum = 4;
570 size_t argc = maxArgumentsNum;
571 napi_value argv[maxArgumentsNum] = {nullptr};
572 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
573 if (argc != 1) {
574 TLOGE(WmsLogTag::WMS_SYSTEM, "[NAPI]Argc is invalid:%{public}zu", argc);
575 napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
576 return NapiGetUndefined(env);
577 }
578 int32_t windowId = 0;
579 if (!ConvertFromJsValue(env, argv[0], windowId)) {
580 TLOGE(WmsLogTag::WMS_SYSTEM, "[NAPI]Failed to convert parameter to integer");
581 napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
582 return NapiGetUndefined(env);
583 }
584 std::shared_ptr<WindowSnapshotDataPack> dataPack = std::make_shared<WindowSnapshotDataPack>();
585 NapiAsyncTask::ExecuteCallback execute = [dataPack, windowId]() {
586 dataPack->result = SingletonContainer::Get<WindowManager>()
587 .GetSnapshotByWindowId(windowId, dataPack->pixelMap);
588 };
589 NapiAsyncTask::CompleteCallback complete =
590 [=](napi_env env, NapiAsyncTask& task, int32_t status) {
591 if (dataPack->result != WMError::WM_OK) {
592 task.Reject(env, JsErrUtils::CreateJsError(env, WM_JS_TO_ERROR_CODE_MAP.at(dataPack->result)));
593 TLOGW(WmsLogTag::WMS_SYSTEM, "[NAPI]Get snapshot not ok!");
594 return;
595 }
596 if (dataPack->pixelMap == nullptr) {
597 task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
598 TLOGE(WmsLogTag::WMS_SYSTEM, "[NAPI]Get snapshot is nullptr!");
599 return;
600 }
601 auto nativePixelMap = Media::PixelMapNapi::CreatePixelMap(env, dataPack->pixelMap);
602 if (nativePixelMap == nullptr) {
603 task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
604 TLOGE(WmsLogTag::WMS_SYSTEM, "[NAPI]Create native pixelmap is nullptr!");
605 return;
606 }
607 task.Resolve(env, nativePixelMap);
608 };
609 napi_value lastParam = (argc <= 1) ? nullptr : argv[0];
610 napi_value result = nullptr;
611 NapiAsyncTask::Schedule("JsWindowManager::OnGetSnapshot",
612 env, CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
613 return result;
614 }
615
OnFindWindow(napi_env env,napi_callback_info info)616 napi_value JsWindowManager::OnFindWindow(napi_env env, napi_callback_info info)
617 {
618 WLOGFD("OnFindWindow");
619 std::string windowName;
620 WMError errCode = WMError::WM_OK;
621 size_t argc = 4;
622 napi_value argv[4] = {nullptr};
623 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
624 if (argc < 1 || argc > 2) { // 2: maximum params num
625 WLOGFE("Argc is invalid: %{public}zu", argc);
626 errCode = WMError::WM_ERROR_INVALID_PARAM;
627 } else {
628 if (!ConvertFromJsValue(env, argv[0], windowName)) {
629 WLOGFE("Failed to convert parameter to windowName");
630 errCode = WMError::WM_ERROR_INVALID_PARAM;
631 }
632 }
633 if (windowName.compare(PIP_WINDOW) == 0) {
634 errCode = WMError::WM_ERROR_INVALID_PARAM;
635 }
636 WLOGI("Window name = %{public}s, err = %{public}d", windowName.c_str(), errCode);
637 NapiAsyncTask::CompleteCallback complete =
638 [=](napi_env env, NapiAsyncTask& task, int32_t status) {
639 if (errCode != WMError::WM_OK) {
640 task.Reject(env, JsErrUtils::CreateJsError(env, errCode, "Invalidate params"));
641 return;
642 }
643 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "WM:Find %s", windowName.c_str());
644 std::shared_ptr<NativeReference> jsWindowObj = FindJsWindowObject(windowName);
645 if (jsWindowObj != nullptr && jsWindowObj->GetNapiValue() != nullptr) {
646 WLOGI("Find window: %{public}s, use exist js window", windowName.c_str());
647 task.Resolve(env, jsWindowObj->GetNapiValue());
648 } else {
649 sptr<Window> window = Window::Find(windowName);
650 if (window == nullptr) {
651 WLOGFE("Cannot find window: %{public}s", windowName.c_str());
652 task.Reject(env, JsErrUtils::CreateJsError(env, WMError::WM_ERROR_NULLPTR, "Cannot find window"));
653 } else {
654 task.Resolve(env, CreateJsWindowObject(env, window));
655 WLOGI("Find window: %{public}s, create js window", windowName.c_str());
656 }
657 }
658 };
659
660 napi_value lastParam = (argc <= 1) ? nullptr :
661 (GetType(env, argv[1]) == napi_function ? argv[1] : nullptr);
662 napi_value result = nullptr;
663 NapiAsyncTask::Schedule("JsWindowManager::OnFindWindow",
664 env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
665 return result;
666 }
667
OnFindWindowSync(napi_env env,napi_callback_info info)668 napi_value JsWindowManager::OnFindWindowSync(napi_env env, napi_callback_info info)
669 {
670 WLOGFD("OnFindWindowSync");
671 std::string windowName;
672 WmErrorCode errCode = WmErrorCode::WM_OK;
673 size_t argc = 4;
674 napi_value argv[4] = {nullptr};
675 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
676 if (argc < 1) { // 1: params num
677 WLOGFE("Argc is invalid: %{public}zu", argc);
678 errCode = WmErrorCode::WM_ERROR_INVALID_PARAM;
679 } else {
680 if (!ConvertFromJsValue(env, argv[0], windowName)) {
681 WLOGFE("Failed to convert parameter to windowName");
682 errCode = WmErrorCode::WM_ERROR_INVALID_PARAM;
683 }
684 }
685 if (windowName.compare(PIP_WINDOW) == 0) {
686 errCode = WmErrorCode::WM_ERROR_INVALID_PARAM;
687 }
688 if (errCode == WmErrorCode::WM_ERROR_INVALID_PARAM) {
689 napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
690 return NapiGetUndefined(env);
691 }
692
693 WLOGD("Window name = %{public}s, err = %{public}d", windowName.c_str(), errCode);
694 std::shared_ptr<NativeReference> jsWindowObj = FindJsWindowObject(windowName);
695 if (jsWindowObj != nullptr && jsWindowObj->GetNapiValue() != nullptr) {
696 WLOGD("Find window: %{public}s, use exist js window", windowName.c_str());
697 return jsWindowObj->GetNapiValue();
698 } else {
699 sptr<Window> window = Window::Find(windowName);
700 if (window == nullptr) {
701 napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
702 return NapiGetUndefined(env);
703 } else {
704 return CreateJsWindowObject(env, window);
705 }
706 }
707 }
708
OnMinimizeAll(napi_env env,napi_callback_info info)709 napi_value JsWindowManager::OnMinimizeAll(napi_env env, napi_callback_info info)
710 {
711 WLOGI("OnMinimizeAll");
712 WmErrorCode errCode = WmErrorCode::WM_OK;
713 size_t argc = 4;
714 napi_value argv[4] = {nullptr};
715 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
716 if (argc < 1) {
717 WLOGFE("Argc is invalid: %{public}zu", argc);
718 errCode = WmErrorCode::WM_ERROR_INVALID_PARAM;
719 }
720 int64_t displayId = static_cast<int64_t>(DISPLAY_ID_INVALID);
721 if (errCode == WmErrorCode::WM_OK && !ConvertFromJsValue(env, argv[0], displayId)) {
722 WLOGFE("Failed to convert parameter to displayId");
723 errCode = WmErrorCode::WM_ERROR_INVALID_PARAM;
724 }
725 if (displayId < 0 ||
726 SingletonContainer::Get<DisplayManager>().GetDisplayById(static_cast<uint64_t>(displayId)) == nullptr) {
727 errCode = WmErrorCode::WM_ERROR_INVALID_PARAM;
728 }
729 if (errCode == WmErrorCode::WM_ERROR_INVALID_PARAM) {
730 WLOGFE("JsWindowManager::OnMinimizeAll failed, Invalidate params.");
731 napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
732 return NapiGetUndefined(env);
733 }
734
735 WLOGI("Display id = %{public}" PRIu64", err = %{public}d", static_cast<uint64_t>(displayId), errCode);
736 NapiAsyncTask::CompleteCallback complete =
737 [=](napi_env env, NapiAsyncTask& task, int32_t status) {
738 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "WM:MinimizeAll: " PRIu64"",
739 static_cast<uint64_t>(displayId));
740 WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(
741 SingletonContainer::Get<WindowManager>().MinimizeAllAppWindows(static_cast<uint64_t>(displayId)));
742 if (ret == WmErrorCode::WM_OK) {
743 task.Resolve(env, NapiGetUndefined(env));
744 WLOGFI("OnMinimizeAll success");
745 } else {
746 task.Reject(env, JsErrUtils::CreateJsError(env, ret, "OnMinimizeAll failed"));
747 }
748 };
749 napi_value lastParam = (argc <= 1) ? nullptr :
750 ((argv[1] != nullptr && GetType(env, argv[1]) == napi_function) ? argv[1] : nullptr);
751 napi_value result = nullptr;
752 NapiAsyncTask::Schedule("JsWindowManager::OnMinimizeAll",
753 env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
754 return result;
755 }
756
OnToggleShownStateForAllAppWindows(napi_env env,napi_callback_info info)757 napi_value JsWindowManager::OnToggleShownStateForAllAppWindows(napi_env env, napi_callback_info info)
758 {
759 WLOGI("OnToggleShownStateForAllAppWindows");
760 NapiAsyncTask::CompleteCallback complete =
761 [=](napi_env env, NapiAsyncTask& task, int32_t status) {
762 WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(
763 SingletonContainer::Get<WindowManager>().ToggleShownStateForAllAppWindows());
764 if (ret == WmErrorCode::WM_OK) {
765 task.Resolve(env, NapiGetUndefined(env));
766 WLOGI("OnToggleShownStateForAllAppWindows success");
767 } else {
768 task.Reject(env, JsErrUtils::CreateJsError(env, ret, "OnToggleShownStateForAllAppWindows failed"));
769 }
770 };
771 size_t argc = 4;
772 napi_value argv[4] = {nullptr};
773 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
774 napi_value lastParam = (argc == 0) ? nullptr :
775 (GetType(env, argv[0]) == napi_function ? argv[0] : nullptr);
776 napi_value result = nullptr;
777 NapiAsyncTask::Schedule("JsWindowManager::OnToggleShownStateForAllAppWindows",
778 env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
779 return result;
780 }
781
OnRegisterWindowManagerCallback(napi_env env,napi_callback_info info)782 napi_value JsWindowManager::OnRegisterWindowManagerCallback(napi_env env, napi_callback_info info)
783 {
784 WLOGFD("OnRegisterWindowManagerCallback");
785 size_t argc = 4;
786 napi_value argv[4] = {nullptr};
787 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
788 if (argc < 2) { // 2: params num
789 WLOGFE("Argc is invalid: %{public}zu", argc);
790 napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
791 return NapiGetUndefined(env);
792 }
793 std::string cbType;
794 if (!ConvertFromJsValue(env, argv[0], cbType)) {
795 WLOGFE("Failed to convert parameter to callbackType");
796 napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
797 return NapiGetUndefined(env);
798 }
799 napi_value value = argv[1];
800 if (!NapiIsCallable(env, value)) {
801 WLOGI("Callback(argv[1]) is not callable");
802 napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
803 return NapiGetUndefined(env);
804 }
805
806 WmErrorCode ret = registerManager_->RegisterListener(nullptr, cbType, CaseType::CASE_WINDOW_MANAGER, env, value);
807 if (ret != WmErrorCode::WM_OK) {
808 napi_throw(env, JsErrUtils::CreateJsError(env, ret));
809 return NapiGetUndefined(env);
810 }
811 WLOGI("Register end, type = %{public}s", cbType.c_str());
812 return NapiGetUndefined(env);
813 }
814
OnUnregisterWindowManagerCallback(napi_env env,napi_callback_info info)815 napi_value JsWindowManager::OnUnregisterWindowManagerCallback(napi_env env, napi_callback_info info)
816 {
817 WLOGFD("OnUnregisterWindowManagerCallback");
818 size_t argc = 4;
819 napi_value argv[4] = {nullptr};
820 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
821 if (argc < 1) {
822 WLOGFE("Argc is invalid: %{public}zu", argc);
823 napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
824 return NapiGetUndefined(env);
825 }
826 std::string cbType;
827 if (!ConvertFromJsValue(env, argv[0], cbType)) {
828 WLOGFE("Failed to convert parameter to callbackType");
829 napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
830 return NapiGetUndefined(env);
831 }
832
833 napi_value value = nullptr;
834 WmErrorCode ret = WmErrorCode::WM_OK;
835 if (argc == 1) {
836 ret = registerManager_->UnregisterListener(nullptr, cbType, CaseType::CASE_WINDOW_MANAGER, env, value);
837 } else {
838 value = argv[1];
839 if ((value == nullptr) || (!NapiIsCallable(env, value))) {
840 ret = registerManager_->UnregisterListener(nullptr, cbType, CaseType::CASE_WINDOW_MANAGER, env, nullptr);
841 } else {
842 ret = registerManager_->UnregisterListener(nullptr, cbType, CaseType::CASE_WINDOW_MANAGER, env, value);
843 }
844 }
845 if (ret != WmErrorCode::WM_OK) {
846 napi_throw(env, JsErrUtils::CreateJsError(env, ret));
847 return NapiGetUndefined(env);
848 }
849 WLOGI("Unregister end, type = %{public}s", cbType.c_str());
850 return NapiGetUndefined(env);
851 }
852
GetTopWindowTask(void * contextPtr,napi_env env,napi_value callback,bool newApi)853 static napi_value GetTopWindowTask(void* contextPtr, napi_env env, napi_value callback, bool newApi)
854 {
855 struct TopWindowInfoList {
856 sptr<Window> window = nullptr;
857 AppExecFwk::Ability* ability = nullptr;
858 int32_t errorCode = 0;
859 std::string errMsg = "";
860 };
861 std::shared_ptr<TopWindowInfoList> lists = std::make_shared<TopWindowInfoList>();
862 bool isOldApi = GetAPI7Ability(env, lists->ability);
863 NapiAsyncTask::ExecuteCallback execute = [lists, isOldApi, newApi, contextPtr]() {
864 if (lists == nullptr) {
865 return;
866 }
867 if (isOldApi) {
868 if (lists->ability->GetWindow() == nullptr) {
869 lists->errorCode = newApi ? static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY) :
870 static_cast<int32_t>(WMError::WM_ERROR_NULLPTR);
871 lists->errMsg = "FA mode can not get ability window";
872 return;
873 }
874 lists->window = Window::GetTopWindowWithId(lists->ability->GetWindow()->GetWindowId());
875 } else {
876 auto context = static_cast<std::weak_ptr<AbilityRuntime::Context>*>(contextPtr);
877 if (contextPtr == nullptr || context == nullptr) {
878 lists->errorCode = newApi ? static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY) :
879 static_cast<int32_t>(WMError::WM_ERROR_NULLPTR);
880 lists->errMsg = "Stage mode without context";
881 return;
882 }
883 lists->window = Window::GetTopWindowWithContext(context->lock());
884 }
885 };
886 NapiAsyncTask::CompleteCallback complete = [lists, newApi](napi_env env, NapiAsyncTask& task, int32_t status) {
887 if (lists == nullptr) {
888 if (newApi) {
889 task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY,
890 "napi abnormal"));
891 } else {
892 task.Reject(env, JsErrUtils::CreateJsError(env, WMError::WM_ERROR_NULLPTR, "napi abnormal"));
893 }
894 return;
895 }
896 if (lists->errorCode != 0) {
897 if (newApi) {
898 task.Reject(env, JsErrUtils::CreateJsError(env, static_cast<WmErrorCode>(lists->errorCode),
899 lists->errMsg));
900 } else {
901 task.Reject(env, JsErrUtils::CreateJsError(env, static_cast<WMError>(lists->errorCode),
902 lists->errMsg));
903 }
904 WLOGFE("%{public}s", lists->errMsg.c_str());
905 return;
906 }
907 if (lists->window == nullptr || lists->window->GetWindowState() == WindowState::STATE_DESTROYED) {
908 if (newApi) {
909 task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY,
910 "Get top window failed"));
911 } else {
912 task.Reject(env, JsErrUtils::CreateJsError(env, WMError::WM_ERROR_NULLPTR,
913 "Get top window failed"));
914 }
915 return;
916 }
917 task.Resolve(env, CreateJsWindowObject(env, lists->window));
918 WLOGD("Get top window success");
919 };
920 napi_value result = nullptr;
921 NapiAsyncTask::Schedule("JsWindowManager::OnGetTopWindow",
922 env, CreateAsyncTaskWithLastParam(env, callback, std::move(execute), std::move(complete), &result));
923 return result;
924 }
925
OnGetTopWindow(napi_env env,napi_callback_info info)926 napi_value JsWindowManager::OnGetTopWindow(napi_env env, napi_callback_info info)
927 {
928 WLOGFD("OnGetTopWindow");
929 WMError errCode = WMError::WM_OK;
930 napi_value nativeContext = nullptr;
931 napi_value nativeCallback = nullptr;
932 void* contextPtr = nullptr;
933 size_t argc = 4;
934 napi_value argv[4] = {nullptr};
935 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
936 if (argc > 2) { // 2: maximum params num
937 WLOGFE("Argc is invalid: %{public}zu", argc);
938 errCode = WMError::WM_ERROR_INVALID_PARAM;
939 } else {
940 if (argc > 0 && GetType(env, argv[0]) == napi_object) { // (context, callback?)
941 nativeContext = argv[0];
942 nativeCallback = (argc == 1) ? nullptr :
943 (GetType(env, argv[1]) == napi_function ? argv[1] : nullptr);
944 } else { // (callback?)
945 nativeCallback = (argc == 0) ? nullptr :
946 (GetType(env, argv[0]) == napi_function ? argv[0] : nullptr);
947 }
948 GetNativeContext(env, nativeContext, contextPtr, errCode);
949 }
950 return GetTopWindowTask(contextPtr, env, nativeCallback, false);
951 }
952
OnGetLastWindow(napi_env env,napi_callback_info info)953 napi_value JsWindowManager::OnGetLastWindow(napi_env env, napi_callback_info info)
954 {
955 WLOGFD("OnGetLastWindow");
956 WMError errCode = WMError::WM_OK;
957 napi_value nativeContext = nullptr;
958 napi_value nativeCallback = nullptr;
959 void* contextPtr = nullptr;
960 size_t argc = 4;
961 napi_value argv[4] = {nullptr};
962 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
963 if (argc < 1) {
964 WLOGFE("Argc is invalid: %{public}zu", argc);
965 napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
966 return NapiGetUndefined(env);
967 } else {
968 nativeContext = argv[0];
969 nativeCallback = (argc == 1) ? nullptr : argv[1];
970 GetNativeContext(env, nativeContext, contextPtr, errCode);
971 }
972 if (errCode != WMError::WM_OK) {
973 napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
974 return NapiGetUndefined(env);
975 }
976
977 return GetTopWindowTask(contextPtr, env, nativeCallback, true);
978 }
979
OnSetWindowLayoutMode(napi_env env,napi_callback_info info)980 napi_value JsWindowManager::OnSetWindowLayoutMode(napi_env env, napi_callback_info info)
981 {
982 WLOGFD("OnSetWindowLayoutMode");
983 WmErrorCode errCode = WmErrorCode::WM_OK;
984 size_t argc = 4;
985 napi_value argv[4] = {nullptr};
986 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
987 if (argc < 1) { // 1: minimum params num
988 TLOGE(WmsLogTag::WMS_LAYOUT, "Argc is invalid: %{public}zu", argc);
989 errCode = WmErrorCode::WM_ERROR_INVALID_PARAM;
990 }
991 WindowLayoutMode winLayoutMode = WindowLayoutMode::CASCADE;
992 if (!Permission::IsSystemCalling() && !Permission::IsStartByHdcd()) {
993 TLOGE(WmsLogTag::WMS_LAYOUT, "set window layout mode permission denied!");
994 return NapiThrowError(env, WmErrorCode::WM_ERROR_NOT_SYSTEM_APP);
995 }
996 if (errCode == WmErrorCode::WM_OK) {
997 napi_value nativeMode = argv[0];
998 if (nativeMode == nullptr) {
999 TLOGE(WmsLogTag::WMS_LAYOUT, "Failed to convert parameter to windowLayoutMode");
1000 errCode = WmErrorCode::WM_ERROR_INVALID_PARAM;
1001 } else {
1002 uint32_t resultValue = 0;
1003 napi_get_value_uint32(env, nativeMode, &resultValue);
1004 winLayoutMode = static_cast<WindowLayoutMode>(resultValue);
1005 }
1006 }
1007 if (winLayoutMode != WindowLayoutMode::CASCADE && winLayoutMode != WindowLayoutMode::TILE) {
1008 errCode = WmErrorCode::WM_ERROR_INVALID_PARAM;
1009 }
1010 if (errCode == WmErrorCode::WM_ERROR_INVALID_PARAM) {
1011 TLOGE(WmsLogTag::WMS_LAYOUT, "JsWindowManager::OnSetWindowLayoutMode failed, Invalidate params.");
1012 napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
1013 return NapiGetUndefined(env);
1014 }
1015
1016 WLOGI("LayoutMode = %{public}u, err = %{public}d", winLayoutMode, errCode);
1017 NapiAsyncTask::CompleteCallback complete =
1018 [=](napi_env env, NapiAsyncTask& task, int32_t status) {
1019 WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(
1020 SingletonContainer::Get<WindowManager>().SetWindowLayoutMode(winLayoutMode));
1021 if (ret == WmErrorCode::WM_OK) {
1022 task.Resolve(env, NapiGetUndefined(env));
1023 WLOGD("SetWindowLayoutMode success");
1024 } else {
1025 task.Reject(env, JsErrUtils::CreateJsError(env, ret, "SetWindowLayoutMode failed"));
1026 }
1027 };
1028 // 1: maximum params num; 1: index of callback
1029 napi_value lastParam = (argc <= 1) ? nullptr :
1030 ((argv[1] != nullptr && GetType(env, argv[1]) == napi_function) ? argv[1] : nullptr);
1031 napi_value result = nullptr;
1032 NapiAsyncTask::Schedule("JsWindowManager::OnSetWindowLayoutMode",
1033 env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
1034 return result;
1035 }
1036
OnSetGestureNavigationEnabled(napi_env env,napi_callback_info info)1037 napi_value JsWindowManager::OnSetGestureNavigationEnabled(napi_env env, napi_callback_info info)
1038 {
1039 WLOGFD("OnSetGestureNavigationEnabled");
1040 size_t argc = 4;
1041 napi_value argv[4] = {nullptr};
1042 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
1043 if (argc < 1) { // 1: minimum params num
1044 WLOGFE("Argc is invalid: %{public}zu", argc);
1045 napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
1046 return NapiGetUndefined(env);
1047 }
1048
1049 napi_value nativeBool = argv[0];
1050 if (nativeBool == nullptr) {
1051 WLOGFE("Failed to convert parameter to bool");
1052 napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
1053 return NapiGetUndefined(env);
1054 }
1055 bool gestureNavigationEnable = false;
1056 napi_get_value_bool(env, nativeBool, &gestureNavigationEnable);
1057
1058 WLOGI("Set gesture navigation enable as %{public}d", gestureNavigationEnable);
1059 NapiAsyncTask::CompleteCallback complete =
1060 [gestureNavigationEnable](napi_env env, NapiAsyncTask& task, int32_t status) {
1061 WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(
1062 SingletonContainer::Get<WindowManager>().SetGestureNavigaionEnabled(gestureNavigationEnable));
1063 if (ret == WmErrorCode::WM_OK) {
1064 task.Resolve(env, NapiGetUndefined(env));
1065 WLOGD("SetGestureNavigationEnabled success");
1066 } else {
1067 task.Reject(env, JsErrUtils::CreateJsError(env, ret, "SetGestureNavigationEnabled failed"));
1068 }
1069 };
1070 // 1: maximum params num; 1: index of callback
1071 napi_value lastParam = (argc <= 1) ? nullptr :
1072 ((argv[1] != nullptr && GetType(env, argv[1]) == napi_function) ? argv[1] : nullptr);
1073 napi_value result = nullptr;
1074 NapiAsyncTask::Schedule("JsWindowManager::OnSetGestureNavigationEnabled",
1075 env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
1076 return result;
1077 }
1078
OnSetWaterMarkImage(napi_env env,napi_callback_info info)1079 napi_value JsWindowManager::OnSetWaterMarkImage(napi_env env, napi_callback_info info)
1080 {
1081 WLOGFD("OnSetWaterMarkImage");
1082 napi_value nativeObject = nullptr;
1083 napi_value nativeBoolean = nullptr;
1084 size_t argc = 4;
1085 napi_value argv[4] = {nullptr};
1086 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
1087 if (argc < 2) { // 2: params num
1088 WLOGFE("Argc is invalid: %{public}zu", argc);
1089 napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
1090 return NapiGetUndefined(env);
1091 } else {
1092 if (argc > 0 && GetType(env, argv[0]) == napi_object) {
1093 nativeObject = argv[0];
1094 nativeBoolean = (GetType(env, argv[1]) == napi_boolean ? argv[1] : nullptr);
1095 }
1096 }
1097
1098 std::shared_ptr<Media::PixelMap> pixelMap;
1099 pixelMap = OHOS::Media::PixelMapNapi::GetPixelMap(env, nativeObject);
1100 if (pixelMap == nullptr) {
1101 WLOGFE("Failed to convert parameter to PixelMap");
1102 napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
1103 return NapiGetUndefined(env);
1104 }
1105
1106 if (nativeBoolean == nullptr) {
1107 WLOGFE("Failed to convert parameter to bool");
1108 napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
1109 return NapiGetUndefined(env);
1110 }
1111 bool isShow = false;
1112 napi_get_value_bool(env, nativeBoolean, &isShow);
1113 if (!Permission::IsSystemCalling()) {
1114 WLOGFE("set watermark image permission denied!");
1115 napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_NOT_SYSTEM_APP));
1116 return NapiGetUndefined(env);
1117 }
1118
1119 NapiAsyncTask::CompleteCallback complete =
1120 [=](napi_env env, NapiAsyncTask& task, int32_t status) {
1121 RSInterfaces::GetInstance().ShowWatermark(pixelMap, isShow);
1122 task.Resolve(env, NapiGetUndefined(env));
1123 WLOGD("OnSetWaterMarkImage success");
1124 };
1125 // 2: maximum params num; 2: index of callback
1126 napi_value lastParam = (argc <= 2) ? nullptr :
1127 (GetType(env, argv[2]) == napi_function ? argv[2] : nullptr);
1128 napi_value result = nullptr;
1129 NapiAsyncTask::Schedule("JsWindowManager::OnSetWaterMarkImage",
1130 env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
1131 return result;
1132 }
1133
OnShiftAppWindowFocus(napi_env env,napi_callback_info info)1134 napi_value JsWindowManager::OnShiftAppWindowFocus(napi_env env, napi_callback_info info)
1135 {
1136 WLOGFD("OnShiftAppWindowFocus");
1137 WMError errCode = WMError::WM_OK;
1138 size_t argc = 4;
1139 napi_value argv[4] = {nullptr};
1140 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
1141 if (argc != 2) { // 2: params num
1142 WLOGFE("Argc is invalid: %{public}zu", argc);
1143 errCode = WMError::WM_ERROR_INVALID_PARAM;
1144 }
1145 int32_t sourcePersistentId = static_cast<int32_t>(INVALID_WINDOW_ID);
1146 int32_t targetPersistentId = static_cast<int32_t>(INVALID_WINDOW_ID);
1147 if (errCode == WMError::WM_OK && !ConvertFromJsValue(env, argv[0], sourcePersistentId)) {
1148 WLOGFE("Failed to convert parameter to source window Id");
1149 errCode = WMError::WM_ERROR_INVALID_PARAM;
1150 }
1151 if (errCode == WMError::WM_OK && !ConvertFromJsValue(env, argv[1], targetPersistentId)) {
1152 WLOGFE("Failed to convert parameter to target window Id");
1153 errCode = WMError::WM_ERROR_INVALID_PARAM;
1154 }
1155 if (errCode == WMError::WM_ERROR_INVALID_PARAM) {
1156 napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
1157 return NapiGetUndefined(env);
1158 }
1159 NapiAsyncTask::CompleteCallback complete =
1160 [=](napi_env env, NapiAsyncTask& task, int32_t status) {
1161 WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(
1162 SingletonContainer::Get<WindowManager>().ShiftAppWindowFocus(sourcePersistentId, targetPersistentId));
1163 if (ret == WmErrorCode::WM_OK) {
1164 task.Resolve(env, NapiGetUndefined(env));
1165 WLOGD("OnShiftAppWindowFocus success");
1166 } else {
1167 task.Reject(env, JsErrUtils::CreateJsError(env, ret, "ShiftAppWindowFocus failed"));
1168 }
1169 };
1170 // only return promiss<void>
1171 napi_value lastParam = nullptr;
1172 napi_value result = nullptr;
1173 NapiAsyncTask::Schedule("JsWindowManager::OnShiftAppWindowFocus",
1174 env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
1175 return result;
1176 }
1177
OnGetVisibleWindowInfo(napi_env env,napi_callback_info info)1178 napi_value JsWindowManager::OnGetVisibleWindowInfo(napi_env env, napi_callback_info info)
1179 {
1180 size_t argc = 4;
1181 napi_value argv[4] = {nullptr};
1182 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
1183 napi_value lastParam = argc <= 0 || GetType(env, argv[0]) != napi_function ? nullptr : argv[0];
1184 napi_value result = nullptr;
1185 NapiAsyncTask::CompleteCallback complete =
1186 [](napi_env env, NapiAsyncTask& task, int32_t status) {
1187 std::vector<sptr<WindowVisibilityInfo>> infos;
1188 WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(
1189 SingletonContainer::Get<WindowManager>().GetVisibilityWindowInfo(infos));
1190 if (ret == WmErrorCode::WM_OK) {
1191 task.Resolve(env, CreateJsWindowInfoArrayObject(env, infos));
1192 TLOGD(WmsLogTag::DEFAULT, "OnGetVisibleWindowInfo success");
1193 } else {
1194 TLOGE(WmsLogTag::DEFAULT, "OnGetVisibleWindowInfo failed");
1195 task.Reject(env, JsErrUtils::CreateJsError(env, ret, "OnGetVisibleWindowInfo failed"));
1196 }
1197 };
1198 NapiAsyncTask::Schedule("JsWindowManager::OnGetVisibleWindowInfo",
1199 env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
1200 return result;
1201 }
1202
OnGetWindowsByCoordinate(napi_env env,napi_callback_info info)1203 napi_value JsWindowManager::OnGetWindowsByCoordinate(napi_env env, napi_callback_info info)
1204 {
1205 size_t argc = ARGC_FOUR;
1206 napi_value argv[ARGC_FOUR] = {nullptr};
1207 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
1208 if (argc < ARGC_ONE || argc > ARGC_FOUR) { // min param num 1, max param num 4
1209 return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
1210 }
1211 int64_t displayId = static_cast<int64_t>(DISPLAY_ID_INVALID);
1212 if (!ConvertFromJsValue(env, argv[0], displayId)) {
1213 TLOGE(WmsLogTag::DEFAULT, "Failed to convert parameter to displayId");
1214 return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
1215 }
1216 if (displayId < 0 ||
1217 SingletonContainer::Get<DisplayManager>().GetDisplayById(static_cast<uint64_t>(displayId)) == nullptr) {
1218 TLOGE(WmsLogTag::DEFAULT, "invalid displayId");
1219 return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
1220 }
1221 int32_t windowNumber = 0;
1222 if (argc > ARGC_ONE && !ConvertFromJsValue(env, argv[ARGC_ONE], windowNumber)) {
1223 windowNumber = 0;
1224 }
1225 int32_t x = INVALID_COORDINATE;
1226 if (argc > ARGC_TWO && !ConvertFromJsValue(env, argv[ARGC_TWO], x)) {
1227 x = INVALID_COORDINATE;
1228 }
1229 int32_t y = INVALID_COORDINATE;
1230 if (argc > ARGC_THREE && !ConvertFromJsValue(env, argv[ARGC_THREE], y)) {
1231 y = INVALID_COORDINATE;
1232 }
1233 napi_value result = nullptr;
1234 NapiAsyncTask::CompleteCallback complete =
1235 [displayId, windowNumber, x, y](napi_env env, NapiAsyncTask& task, int32_t status) {
1236 std::vector<int32_t> windowIds;
1237 WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(SingletonContainer::Get<WindowManager>().
1238 GetWindowIdsByCoordinate(static_cast<uint64_t>(displayId), windowNumber, x, y, windowIds));
1239 if (ret == WmErrorCode::WM_OK) {
1240 std::vector<sptr<Window>> windows(windowIds.size());
1241 for (size_t i = 0; i < windowIds.size(); i++) {
1242 sptr<Window> window = Window::GetWindowWithId(windowIds[i]);
1243 windows[i] = window;
1244 }
1245 task.Resolve(env, CreateJsWindowArrayObject(env, windows));
1246 } else {
1247 task.Reject(env, JsErrUtils::CreateJsError(env, ret, "OnGetWindowsByCoordinate failed"));
1248 }
1249 };
1250 NapiAsyncTask::Schedule("JsWindowManager::OnGetWindowsByCoordinate",
1251 env, CreateAsyncTaskWithLastParam(env, nullptr, nullptr, std::move(complete), &result));
1252 return result;
1253 }
1254
JsWindowManagerInit(napi_env env,napi_value exportObj)1255 napi_value JsWindowManagerInit(napi_env env, napi_value exportObj)
1256 {
1257 WLOGFD("JsWindowManagerInit");
1258
1259 if (env == nullptr || exportObj == nullptr) {
1260 WLOGFE("JsWindowManagerInit env or exportObj is nullptr");
1261 return nullptr;
1262 }
1263
1264 std::unique_ptr<JsWindowManager> jsWinManager = std::make_unique<JsWindowManager>();
1265 napi_wrap(env, exportObj, jsWinManager.release(), JsWindowManager::Finalizer, nullptr, nullptr);
1266 napi_set_named_property(env, exportObj, "WindowType", WindowTypeInit(env));
1267 napi_set_named_property(env, exportObj, "AvoidAreaType", AvoidAreaTypeInit(env));
1268 napi_set_named_property(env, exportObj, "WindowMode", WindowModeInit(env));
1269 napi_set_named_property(env, exportObj, "ColorSpace", ColorSpaceInit(env));
1270 napi_set_named_property(env, exportObj, "WindowStageEventType", WindowStageEventTypeInit(env));
1271 napi_set_named_property(env, exportObj, "WindowEventType", WindowEventTypeInit(env));
1272 napi_set_named_property(env, exportObj, "WindowLayoutMode", WindowLayoutModeInit(env));
1273 napi_set_named_property(env, exportObj, "Orientation", OrientationInit(env));
1274 napi_set_named_property(env, exportObj, "BlurStyle", BlurStyleInit(env));
1275 napi_set_named_property(env, exportObj, "WmErrorCode", WindowErrorCodeInit(env));
1276 napi_set_named_property(env, exportObj, "WMError", WindowErrorInit(env));
1277 napi_set_named_property(env, exportObj, "WindowStatusType", WindowStatusTypeInit(env));
1278 napi_set_named_property(env, exportObj, "RectChangeReason", RectChangeReasonInit(env));
1279 napi_set_named_property(env, exportObj, "MaximizePresentation", MaximizePresentationInit(env));
1280 napi_set_named_property(env, exportObj, "ModalityType", ModalityTypeInit(env));
1281 napi_set_named_property(env, exportObj, "ExtensionWindowAttribute", ExtensionWindowAttributeInit(env));
1282 const char *moduleName = "JsWindowManager";
1283 BindNativeFunction(env, exportObj, "create", moduleName, JsWindowManager::Create);
1284 BindNativeFunction(env, exportObj, "createWindow", moduleName, JsWindowManager::CreateWindow);
1285 BindNativeFunction(env, exportObj, "find", moduleName, JsWindowManager::FindWindow);
1286 BindNativeFunction(env, exportObj, "findWindow", moduleName, JsWindowManager::FindWindowSync);
1287 BindNativeFunction(env, exportObj, "on", moduleName, JsWindowManager::RegisterWindowManagerCallback);
1288 BindNativeFunction(env, exportObj, "off", moduleName, JsWindowManager::UnregisterWindowMangerCallback);
1289 BindNativeFunction(env, exportObj, "getTopWindow", moduleName, JsWindowManager::GetTopWindow);
1290 BindNativeFunction(env, exportObj, "getLastWindow", moduleName, JsWindowManager::GetLastWindow);
1291 BindNativeFunction(env, exportObj, "getSnapshot", moduleName, JsWindowManager::GetSnapshot);
1292 BindNativeFunction(env, exportObj, "minimizeAll", moduleName, JsWindowManager::MinimizeAll);
1293 BindNativeFunction(env, exportObj, "toggleShownStateForAllAppWindows", moduleName,
1294 JsWindowManager::ToggleShownStateForAllAppWindows);
1295 BindNativeFunction(env, exportObj, "setWindowLayoutMode", moduleName, JsWindowManager::SetWindowLayoutMode);
1296 BindNativeFunction(env, exportObj, "setGestureNavigationEnabled", moduleName,
1297 JsWindowManager::SetGestureNavigationEnabled);
1298 BindNativeFunction(env, exportObj, "setWaterMarkImage", moduleName, JsWindowManager::SetWaterMarkImage);
1299 BindNativeFunction(env, exportObj, "shiftAppWindowFocus", moduleName, JsWindowManager::ShiftAppWindowFocus);
1300 BindNativeFunction(env, exportObj, "getVisibleWindowInfo", moduleName, JsWindowManager::GetVisibleWindowInfo);
1301 BindNativeFunction(env, exportObj, "getWindowsByCoordinate", moduleName, JsWindowManager::GetWindowsByCoordinate);
1302 return NapiGetUndefined(env);
1303 }
1304 } // namespace Rosen
1305 } // namespace OHOS
1306