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