• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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