• 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_window_manager.h"
16 #include <ability.h>
17 #include <cinttypes>
18 #include <new>
19 #include "ability_context.h"
20 #include "display_manager.h"
21 #include "dm_common.h"
22 #include "js_window.h"
23 #include "js_window_utils.h"
24 #include "window_helper.h"
25 #include "window_manager_hilog.h"
26 #include "window_option.h"
27 #include "singleton_container.h"
28 namespace OHOS {
29 namespace Rosen {
30 using namespace AbilityRuntime;
31 namespace {
32     constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "JsWindowManager"};
33 }
34 
JsWindowManager()35 JsWindowManager::JsWindowManager() : registerManager_(std::make_unique<JsWindowRegisterManager>())
36 {
37 }
38 
~JsWindowManager()39 JsWindowManager::~JsWindowManager()
40 {
41 }
42 
Finalizer(NativeEngine * engine,void * data,void * hint)43 void JsWindowManager::Finalizer(NativeEngine* engine, void* data, void* hint)
44 {
45     WLOGFI("JsWindowManager::Finalizer is called");
46     std::unique_ptr<JsWindowManager>(static_cast<JsWindowManager*>(data));
47 }
48 
CreateWindow(NativeEngine * engine,NativeCallbackInfo * info)49 NativeValue* JsWindowManager::CreateWindow(NativeEngine* engine, NativeCallbackInfo* info)
50 {
51     JsWindowManager* me = CheckParamsAndGetThis<JsWindowManager>(engine, info);
52     return (me != nullptr) ? me->OnCreateWindow(*engine, *info) : nullptr;
53 }
54 
FindWindow(NativeEngine * engine,NativeCallbackInfo * info)55 NativeValue* JsWindowManager::FindWindow(NativeEngine* engine, NativeCallbackInfo* info)
56 {
57     JsWindowManager* me = CheckParamsAndGetThis<JsWindowManager>(engine, info);
58     return (me != nullptr) ? me->OnFindWindow(*engine, *info) : nullptr;
59 }
60 
MinimizeAll(NativeEngine * engine,NativeCallbackInfo * info)61 NativeValue* JsWindowManager::MinimizeAll(NativeEngine* engine, NativeCallbackInfo* info)
62 {
63     JsWindowManager* me = CheckParamsAndGetThis<JsWindowManager>(engine, info);
64     return (me != nullptr) ? me->OnMinimizeAll(*engine, *info) : nullptr;
65 }
66 
RegisterWindowManagerCallback(NativeEngine * engine,NativeCallbackInfo * info)67 NativeValue* JsWindowManager::RegisterWindowManagerCallback(NativeEngine* engine, NativeCallbackInfo* info)
68 {
69     JsWindowManager* me = CheckParamsAndGetThis<JsWindowManager>(engine, info);
70     return (me != nullptr) ? me->OnRegisterWindowMangerCallback(*engine, *info) : nullptr;
71 }
72 
UnregisterWindowMangerCallback(NativeEngine * engine,NativeCallbackInfo * info)73 NativeValue* JsWindowManager::UnregisterWindowMangerCallback(NativeEngine* engine, NativeCallbackInfo* info)
74 {
75     JsWindowManager* me = CheckParamsAndGetThis<JsWindowManager>(engine, info);
76     return (me != nullptr) ? me->OnUnregisterWindowManagerCallback(*engine, *info) : nullptr;
77 }
78 
GetTopWindow(NativeEngine * engine,NativeCallbackInfo * info)79 NativeValue* JsWindowManager::GetTopWindow(NativeEngine* engine, NativeCallbackInfo* info)
80 {
81     JsWindowManager* me = CheckParamsAndGetThis<JsWindowManager>(engine, info);
82     return (me != nullptr) ? me->OnGetTopWindow(*engine, *info) : nullptr;
83 }
84 
SetWindowLayoutMode(NativeEngine * engine,NativeCallbackInfo * info)85 NativeValue* JsWindowManager::SetWindowLayoutMode(NativeEngine* engine, NativeCallbackInfo* info)
86 {
87     JsWindowManager* me = CheckParamsAndGetThis<JsWindowManager>(engine, info);
88     return (me != nullptr) ? me->OnSetWindowLayoutMode(*engine, *info) : nullptr;
89 }
90 
GetNativeContext(NativeEngine & engine,NativeValue * nativeContext,void * & contextPtr,WMError & errCode)91 static void GetNativeContext(NativeEngine& engine, NativeValue* nativeContext, void*& contextPtr, WMError& errCode)
92 {
93     AppExecFwk::Ability* ability = nullptr;
94     bool isOldApi = GetAPI7Ability(engine, ability);
95     WLOGFI("[NAPI]FA mode:%{public}u", isOldApi);
96     if (isOldApi) {
97         return;
98     }
99     if (nativeContext != nullptr) {
100         auto objContext = AbilityRuntime::ConvertNativeValueTo<NativeObject>(nativeContext);
101         if (objContext == nullptr) {
102             WLOGFE("[NAPI]ConvertNativeValueTo Context Object failed");
103             errCode = WMError::WM_ERROR_INVALID_PARAM;
104             return;
105         }
106         contextPtr = objContext->GetNativePointer();
107     }
108 }
109 
GetWindowTypeAndParentName(NativeEngine & engine,std::string & parentName,WindowType & winType,NativeValue * nativeString,NativeValue * nativeType)110 static bool GetWindowTypeAndParentName(NativeEngine& engine, std::string& parentName, WindowType& winType,
111     NativeValue* nativeString, NativeValue* nativeType)
112 {
113     NativeNumber* type = ConvertNativeValueTo<NativeNumber>(nativeType);
114     if (type == nullptr) {
115         WLOGFE("Failed to convert parameter to windowType");
116         return false;
117     }
118     // adapt to the old version
119     if (static_cast<uint32_t>(*type) >= static_cast<uint32_t>(WindowType::SYSTEM_WINDOW_BASE)) {
120         winType = static_cast<WindowType>(static_cast<uint32_t>(*type));
121     } else {
122         if (static_cast<uint32_t>(*type) >= static_cast<uint32_t>(ApiWindowType::TYPE_BASE) &&
123             static_cast<uint32_t>(*type) <= static_cast<uint32_t>(ApiWindowType::TYPE_END)) {
124             winType = JS_TO_NATIVE_WINDOW_TYPE_MAP.at(static_cast<ApiWindowType>(static_cast<uint32_t>(*type)));
125         } else {
126             WLOGFE("Do not surppot this type");
127             return false;
128         }
129     }
130     AppExecFwk::Ability* ability = nullptr;
131     bool isOldApi = GetAPI7Ability(engine, ability);
132     if (isOldApi) {
133         if (ability == nullptr || !WindowHelper::IsSubWindow(winType)) {
134             WLOGE("JsWindowManager FA mode GetAPI7Ability failed or type should be subWinodw!");
135             return false;
136         }
137         auto window = ability->GetWindow();
138         if (window == nullptr) {
139             WLOGE("JsWindowManager CheckJsWindowType in oldApi get mainWindow failed");
140             return false;
141         }
142         parentName = window->GetWindowName();
143     } else {
144         if (!WindowHelper::IsSystemWindow(winType)) {
145             WLOGFE("Only SystemWindow support create in stage mode!");
146             return false;
147         }
148     }
149     return true;
150 }
151 
CreateSystemWindowTask(void * contextPtr,std::string windowName,WindowType winType,NativeEngine & engine,AsyncTask & task)152 static void CreateSystemWindowTask(void* contextPtr, std::string windowName, WindowType winType,
153     NativeEngine& engine, AsyncTask& task)
154 {
155     WLOGFI("JsWindowManager::CreateSystemWindowTask is called");
156     auto context = static_cast<std::weak_ptr<AbilityRuntime::Context>*>(contextPtr);
157     if (contextPtr == nullptr || context == nullptr) {
158         task.Reject(engine, CreateJsError(engine,
159             static_cast<int32_t>(WMError::WM_ERROR_NULLPTR),
160             "JsWindow::OnCreateWindow newAPI failed."));
161         WLOGFE("JsWindowManager::OnCreateWindow in newApi use with empty context!");
162         return;
163     }
164     if (winType == WindowType::WINDOW_TYPE_FLOAT) {
165         auto abilityContext = Context::ConvertTo<AbilityRuntime::AbilityContext>(context->lock());
166         if (abilityContext != nullptr) {
167             if (!CheckCallingPermission("ohos.permission.SYSTEM_FLOAT_WINDOW")) {
168                 task.Reject(engine, CreateJsError(engine,
169                     static_cast<int32_t>(WMError::WM_ERROR_INVALID_PERMISSION),
170                     "JsWindow::OnCreateWindow newAPI failed."));
171                 WLOGFE("JsWindowManager::OnCreateWindow in newApi TYPE_FLOAT CheckCallingPermission failed!");
172                 return;
173             }
174         }
175     }
176     sptr<WindowOption> windowOption = new(std::nothrow) WindowOption();
177     if (windowOption == nullptr) {
178         task.Reject(engine, CreateJsError(engine,
179             static_cast<int32_t>(WMError::WM_ERROR_NULLPTR), "JsWindowManager::OnCreateWindow failed."));
180         WLOGFE("JsWindowManager::OnCreateWindow windowOption malloc failed");
181         return;
182     }
183     windowOption->SetWindowType(winType);
184     sptr<Window> window = Window::Create(windowName, windowOption, context->lock());
185     if (window != nullptr) {
186         task.Resolve(engine, CreateJsWindowObject(engine, window));
187         WLOGFI("JsWindowManager::OnCreateWindow success");
188     } else {
189         task.Reject(engine, CreateJsError(engine,
190             static_cast<int32_t>(WMError::WM_ERROR_NULLPTR), "JsWindowManager::OnCreateWindow failed."));
191     }
192 }
193 
CreateSubWindowTask(std::string parentWinName,std::string windowName,WindowType winType,NativeEngine & engine,AsyncTask & task)194 static void CreateSubWindowTask(std::string parentWinName, std::string windowName, WindowType winType,
195     NativeEngine& engine, AsyncTask& task)
196 {
197     WLOGFI("JsWindowManager::CreateSubWindowTask is called");
198     sptr<WindowOption> windowOption = new(std::nothrow) WindowOption();
199     if (windowOption == nullptr) {
200         task.Reject(engine, CreateJsError(engine,
201             static_cast<int32_t>(WMError::WM_ERROR_NULLPTR), "JsWindowManager::OnCreateWindow failed."));
202         WLOGFE("JsWindowManager::OnCreateWindow windowOption malloc failed");
203         return;
204     }
205     windowOption->SetWindowType(winType);
206     windowOption->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_FLOATING);
207     windowOption->SetParentName(parentWinName);
208     sptr<Window> window = Window::Create(windowName, windowOption);
209     if (window != nullptr) {
210         task.Resolve(engine, CreateJsWindowObject(engine, window));
211         WLOGFI("JsWindowManager::OnCreateWindow success");
212     } else {
213         task.Reject(engine, CreateJsError(engine,
214             static_cast<int32_t>(WMError::WM_ERROR_NULLPTR), "JsWindowManager::OnCreateWindow failed."));
215     }
216 }
217 
OnCreateWindow(NativeEngine & engine,NativeCallbackInfo & info)218 NativeValue* JsWindowManager::OnCreateWindow(NativeEngine& engine, NativeCallbackInfo& info)
219 {
220     WLOGFI("JsWindowManager::OnCreateWindow is called");
221     NativeValue* nativeString = nullptr;
222     NativeValue* nativeContext = nullptr;
223     NativeValue* nativeType = nullptr;
224     NativeValue* callback = nullptr;
225     if (info.argc >= 2 && info.argv[0]->TypeOf() == NATIVE_STRING) { // 2: minimum params num
226         nativeString = info.argv[0];
227         nativeType = info.argv[1];
228         // 2: minimum params num
229         callback = (info.argc == 2) ? nullptr :
230             (info.argv[2]->TypeOf() == NATIVE_FUNCTION ? info.argv[2] : nullptr); // 2: index of callback
231     } else if (info.argc >= 3) { // 3: minimum params num
232         nativeContext = info.argv[0]->TypeOf() == NATIVE_OBJECT ? info.argv[0] : nullptr;
233         nativeString = info.argv[1];
234         nativeType = info.argv[2]; // 2: index of type
235         // 3: minimum params num;
236         callback = (info.argc == 3) ? nullptr :
237             (info.argv[3]->TypeOf() == NATIVE_FUNCTION ? info.argv[3] : nullptr); // 3: index of callback
238     }
239     std::string windowName;
240     WMError errCode = WMError::WM_OK;
241     if (!ConvertFromJsValue(engine, nativeString, windowName)) {
242         WLOGFE("Failed to convert parameter to windowName");
243         errCode = WMError::WM_ERROR_INVALID_PARAM;
244     }
245     std::string parentName;
246     WindowType winType = WindowType::SYSTEM_WINDOW_BASE;
247     if (errCode == WMError::WM_OK &&
248         !GetWindowTypeAndParentName(engine, parentName, winType, nativeString, nativeType)) {
249         errCode = WMError::WM_ERROR_INVALID_PARAM;
250     }
251     void* contextPtr = nullptr;
252     GetNativeContext(engine, nativeContext, contextPtr, errCode);
253     AsyncTask::CompleteCallback complete =
254         [=](NativeEngine& engine, AsyncTask& task, int32_t status) {
255             if (errCode != WMError::WM_OK) {
256                 task.Reject(engine, CreateJsError(engine, static_cast<int32_t>(errCode), "Invalidate params."));
257                 return;
258             }
259             if (parentName.empty()) {
260                 return CreateSystemWindowTask(contextPtr, windowName, winType, engine, task);
261             } else {
262                 return CreateSubWindowTask(parentName, windowName, winType, engine, task);
263             }
264         };
265     NativeValue* result = nullptr;
266     AsyncTask::Schedule(
267         engine, CreateAsyncTaskWithLastParam(engine, callback, nullptr, std::move(complete), &result));
268     return result;
269 }
270 
OnFindWindow(NativeEngine & engine,NativeCallbackInfo & info)271 NativeValue* JsWindowManager::OnFindWindow(NativeEngine& engine, NativeCallbackInfo& info)
272 {
273     WLOGFI("JsWindowManager::JsOnFindWindow is called");
274     std::string windowName;
275     WMError errCode = WMError::WM_OK;
276     if (info.argc < 1 || info.argc > 2) { // 2: maximum params num
277         WLOGFE("param not match!");
278         errCode = WMError::WM_ERROR_INVALID_PARAM;
279     } else {
280         if (!ConvertFromJsValue(engine, info.argv[0], windowName)) {
281             WLOGFE("Failed to convert parameter to windowName");
282             errCode = WMError::WM_ERROR_INVALID_PARAM;
283         }
284     }
285     AsyncTask::CompleteCallback complete =
286         [=](NativeEngine& engine, AsyncTask& task, int32_t status) {
287             if (errCode != WMError::WM_OK) {
288                 task.Reject(engine, CreateJsError(engine, static_cast<int32_t>(errCode), "Invalidate params."));
289                 return;
290             }
291             std::shared_ptr<NativeReference> jsWindowObj = FindJsWindowObject(windowName);
292             if (jsWindowObj != nullptr && jsWindowObj->Get() != nullptr) {
293                 task.Resolve(engine, jsWindowObj->Get());
294                 WLOGFI("JsWindowManager::OnFindWindow success");
295             } else {
296                 sptr<Window> window = Window::Find(windowName);
297                 if (window == nullptr) {
298                     task.Reject(engine, CreateJsError(engine,
299                         static_cast<int32_t>(WMError::WM_ERROR_NULLPTR), "JsWindowManager::OnFindWindow failed."));
300                 } else {
301                     task.Resolve(engine, CreateJsWindowObject(engine, window));
302                 }
303             }
304         };
305 
306     NativeValue* lastParam = (info.argc <= 1) ? nullptr :
307         (info.argv[1]->TypeOf() == NATIVE_FUNCTION ? info.argv[1] : nullptr);
308     NativeValue* result = nullptr;
309     AsyncTask::Schedule(
310         engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
311     return result;
312 }
313 
OnMinimizeAll(NativeEngine & engine,NativeCallbackInfo & info)314 NativeValue* JsWindowManager::OnMinimizeAll(NativeEngine& engine, NativeCallbackInfo& info)
315 {
316     WLOGFI("JsWindowManager::OnMinimizeAll is called");
317     WMError errCode = WMError::WM_OK;
318     if (info.argc < 1 || info.argc > 2) { // 2: maximum params num
319         WLOGFE("param is too small!");
320         errCode = WMError::WM_ERROR_INVALID_PARAM;
321     }
322     int64_t displayId = static_cast<int64_t>(DISPLAY_ID_INVALID);
323     if (errCode == WMError::WM_OK && !ConvertFromJsValue(engine, info.argv[0], displayId)) {
324         WLOGFE("Failed to convert parameter to displayId");
325         errCode = WMError::WM_ERROR_INVALID_PARAM;
326     }
327     if (displayId < 0 ||
328         SingletonContainer::Get<DisplayManager>().GetDisplayById(static_cast<uint64_t>(displayId)) == nullptr) {
329         WLOGFE("displayId is invalid");
330         errCode = WMError::WM_ERROR_INVALID_PARAM;
331     } else {
332         WLOGFI("displayId %{public}" PRIu64"", static_cast<uint64_t>(displayId));
333     }
334     AsyncTask::CompleteCallback complete =
335         [=](NativeEngine& engine, AsyncTask& task, int32_t status) {
336             if (errCode != WMError::WM_OK) {
337                 task.Reject(engine, CreateJsError(engine, static_cast<int32_t>(errCode), "Invalidate params."));
338                 return;
339             }
340             SingletonContainer::Get<WindowManager>().MinimizeAllAppWindows(static_cast<uint64_t>(displayId));
341             task.Resolve(engine, engine.CreateUndefined());
342             WLOGFI("JsWindowManager::OnMinimizeAll success");
343         };
344     NativeValue* lastParam = (info.argc <= 1) ? nullptr :
345         (info.argv[1]->TypeOf() == NATIVE_FUNCTION ? info.argv[1] : nullptr);
346     NativeValue* result = nullptr;
347     AsyncTask::Schedule(
348         engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
349     return result;
350 }
351 
OnRegisterWindowMangerCallback(NativeEngine & engine,NativeCallbackInfo & info)352 NativeValue* JsWindowManager::OnRegisterWindowMangerCallback(NativeEngine& engine, NativeCallbackInfo& info)
353 {
354     WLOGFI("JsWindowManager::OnRegisterWindowMangerCallback is called");
355     if (info.argc != 2) { // 2: params num
356         WLOGFE("Params not match");
357         return engine.CreateUndefined();
358     }
359     std::string cbType;
360     if (!ConvertFromJsValue(engine, info.argv[0], cbType)) {
361         WLOGFE("Failed to convert parameter to callbackType");
362         return engine.CreateUndefined();
363     }
364     NativeValue* value = info.argv[1];
365     if (!value->IsCallable()) {
366         WLOGFI("JsWindowManager::OnRegisterWindowMangerCallback info->argv[1] is not callable");
367         return engine.CreateUndefined();
368     }
369 
370     registerManager_->RegisterListener(nullptr, cbType, CaseType::CASE_WINDOW_MANAGER, engine, value);
371     WLOGFI("JsWindowManager::OnRegisterWindowMangerCallback end!");
372     return engine.CreateUndefined();
373 }
374 
OnUnregisterWindowManagerCallback(NativeEngine & engine,NativeCallbackInfo & info)375 NativeValue* JsWindowManager::OnUnregisterWindowManagerCallback(NativeEngine& engine, NativeCallbackInfo& info)
376 {
377     WLOGFI("JsWindowManager::OnUnregisterWindowCallback is called");
378     if (info.argc < 1 || info.argc > 2) { // 2: maximum params num
379         WLOGFE("Params not match");
380         return engine.CreateUndefined();
381     }
382     std::string cbType;
383     if (!ConvertFromJsValue(engine, info.argv[0], cbType)) {
384         WLOGFE("Failed to convert parameter to callbackType");
385         return engine.CreateUndefined();
386     }
387     if (info.argc == 1) {
388         registerManager_->UnregisterListener(nullptr, cbType, CaseType::CASE_WINDOW_MANAGER, nullptr);
389     } else {
390         NativeValue* value = info.argv[1];
391         if (!value->IsCallable()) {
392             WLOGFI("JsWindowManager::OnUnregisterWindowManagerCallback info->argv[1] is not callable");
393             return engine.CreateUndefined();
394         }
395         registerManager_->UnregisterListener(nullptr, cbType, CaseType::CASE_WINDOW_MANAGER, value);
396     }
397     WLOGFI("JsWindowManager::OnUnregisterWindowCallback end!");
398     return engine.CreateUndefined();
399 }
400 
GetTopWindowTask(void * contextPtr,NativeEngine & engine,AsyncTask & task)401 static void GetTopWindowTask(void* contextPtr, NativeEngine& engine, AsyncTask& task)
402 {
403     std::string windowName;
404     sptr<Window> window = nullptr;
405     AppExecFwk::Ability* ability = nullptr;
406     bool isOldApi = GetAPI7Ability(engine, ability);
407     if (isOldApi) {
408         if (ability->GetWindow() == nullptr) {
409             task.Reject(engine, CreateJsError(engine,
410                 static_cast<int32_t>(WMError::WM_ERROR_NULLPTR), "JsWindow::onGetTopWindow failed."));
411             WLOGE("JsWindowManager get top windowfailed with null ability");
412             return;
413         }
414         window = Window::GetTopWindowWithId(ability->GetWindow()->GetWindowId());
415     } else {
416         auto context = static_cast<std::weak_ptr<AbilityRuntime::Context>*>(contextPtr);
417         if (contextPtr == nullptr || context == nullptr) {
418             task.Reject(engine, CreateJsError(engine,
419                 static_cast<int32_t>(WMError::WM_ERROR_NULLPTR),
420                 "JsWindow::OnGetTopWindow newAPI failed."));
421             WLOGFE("JsWindowManager::OnGetTopWindow in newApi use with empty context!");
422             return;
423         }
424         window = Window::GetTopWindowWithContext(context->lock());
425     }
426     if (window == nullptr) {
427         task.Reject(engine, CreateJsError(engine,
428             static_cast<int32_t>(WMError::WM_ERROR_NULLPTR), "JsWindowManager::OnGetTopWindow failed."));
429         WLOGFE("JsWindowManager::OnGetTopWindow failed");
430         return;
431     }
432     windowName = window->GetWindowName();
433     std::shared_ptr<NativeReference> jsWindowObj = FindJsWindowObject(windowName);
434     if (jsWindowObj != nullptr && jsWindowObj->Get() != nullptr) {
435         task.Resolve(engine, jsWindowObj->Get());
436     } else {
437         task.Resolve(engine, CreateJsWindowObject(engine, window));
438     }
439     WLOGFI("JsWindowManager::OnGetTopWindow success");
440     return;
441 }
442 
OnGetTopWindow(NativeEngine & engine,NativeCallbackInfo & info)443 NativeValue* JsWindowManager::OnGetTopWindow(NativeEngine& engine, NativeCallbackInfo& info)
444 {
445     WLOGFI("JsWindowManager::OnGetTopWindow is called");
446     WMError errCode = WMError::WM_OK;
447     NativeValue* nativeContext = nullptr;
448     NativeValue* nativeCallback = nullptr;
449     void* contextPtr = nullptr;
450     if (info.argc > 2) { // 2: maximum params num
451         WLOGFE("param not match!");
452         errCode = WMError::WM_ERROR_INVALID_PARAM;
453     } else {
454         if (info.argc > 0 && info.argv[0]->TypeOf() == NATIVE_OBJECT) { // (context, callback?)
455             nativeContext = info.argv[0];
456             nativeCallback = (info.argc == 1) ? nullptr :
457                 (info.argv[1]->TypeOf() == NATIVE_FUNCTION ? info.argv[1] : nullptr);
458         } else { // (callback?)
459             nativeCallback = (info.argc == 0) ? nullptr :
460                 (info.argv[0]->TypeOf() == NATIVE_FUNCTION ? info.argv[0] : nullptr);
461         }
462         GetNativeContext(engine, nativeContext, contextPtr, errCode);
463     }
464 
465     AsyncTask::CompleteCallback complete =
466         [=](NativeEngine& engine, AsyncTask& task, int32_t status) {
467             if (errCode != WMError::WM_OK) {
468                 task.Reject(engine, CreateJsError(engine, static_cast<int32_t>(errCode), "Invalidate params."));
469                 return;
470             }
471             return GetTopWindowTask(contextPtr, engine, task);
472         };
473     NativeValue* result = nullptr;
474     AsyncTask::Schedule(
475         engine, CreateAsyncTaskWithLastParam(engine, nativeCallback, nullptr, std::move(complete), &result));
476     return result;
477 }
478 
OnSetWindowLayoutMode(NativeEngine & engine,NativeCallbackInfo & info)479 NativeValue* JsWindowManager::OnSetWindowLayoutMode(NativeEngine& engine, NativeCallbackInfo& info)
480 {
481     WLOGFI("JsWindowManager::OnSetWindowLayoutMode is called");
482     WMError errCode = WMError::WM_OK;
483     if (info.argc < 2 || info.argc > 3) { // 2: minimum params num; 3: maximum params num
484         WLOGFE("JsWindowManager::OnSetWindowLayoutMode params too small");
485         errCode = WMError::WM_ERROR_INVALID_PARAM;
486     }
487     WindowLayoutMode winLayoutMode = WindowLayoutMode::CASCADE;
488     int64_t displayId = 0;
489     if (errCode == WMError::WM_OK) {
490         NativeNumber* nativeMode = ConvertNativeValueTo<NativeNumber>(info.argv[0]);
491         if (nativeMode == nullptr) {
492             WLOGFE("Failed to convert parameter to windowLayoutMode");
493             errCode = WMError::WM_ERROR_INVALID_PARAM;
494         } else {
495             winLayoutMode = static_cast<WindowLayoutMode>(static_cast<uint32_t>(*nativeMode));
496         }
497 
498         if (!ConvertFromJsValue(engine, info.argv[1], displayId)) {
499             WLOGFE("Failed to convert parameter to displayId");
500             errCode = WMError::WM_ERROR_INVALID_PARAM;
501         }
502     }
503 
504     AsyncTask::CompleteCallback complete =
505         [=](NativeEngine& engine, AsyncTask& task, int32_t status) {
506             if (errCode != WMError::WM_OK) {
507                 task.Reject(engine, CreateJsError(engine, static_cast<int32_t>(errCode), "Invalidate params."));
508                 return;
509             }
510             WMError ret = SingletonContainer::Get<WindowManager>().SetWindowLayoutMode(winLayoutMode,
511                 static_cast<uint64_t>(displayId));
512             if (ret == WMError::WM_OK) {
513                 task.Resolve(engine, engine.CreateUndefined());
514                 WLOGFI("JsWindowManager::OnSetWindowLayoutMode success");
515             } else {
516                 task.Reject(engine, CreateJsError(engine, static_cast<int32_t>(ret), "do failed"));
517             }
518         };
519     // 2: maximum params num; 2: index of callback
520     NativeValue* lastParam = (info.argc <= 2) ? nullptr :
521         (info.argv[2]->TypeOf() == NATIVE_FUNCTION ? info.argv[2] : nullptr);
522     NativeValue* result = nullptr;
523     AsyncTask::Schedule(
524         engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result));
525     return result;
526 }
527 
JsWindowManagerInit(NativeEngine * engine,NativeValue * exportObj)528 NativeValue* JsWindowManagerInit(NativeEngine* engine, NativeValue* exportObj)
529 {
530     WLOGFI("JsWindowManagerInit is called");
531 
532     if (engine == nullptr || exportObj == nullptr) {
533         WLOGFE("JsWindowManagerInit engine or exportObj is nullptr");
534         return nullptr;
535     }
536 
537     NativeObject* object = ConvertNativeValueTo<NativeObject>(exportObj);
538     if (object == nullptr) {
539         WLOGFE("JsWindowManagerInit object is nullptr");
540         return nullptr;
541     }
542 
543     std::unique_ptr<JsWindowManager> jsWinManager = std::make_unique<JsWindowManager>();
544     object->SetNativePointer(jsWinManager.release(), JsWindowManager::Finalizer, nullptr);
545     object->SetProperty("WindowType", WindowTypeInit(engine));
546     object->SetProperty("AvoidAreaType", AvoidAreaTypeInit(engine));
547     object->SetProperty("WindowMode", WindowModeInit(engine));
548     object->SetProperty("ColorSpace", ColorSpaceInit(engine));
549     object->SetProperty("WindowStageEventType", WindowStageEventTypeInit(engine));
550     BindNativeFunction(*engine, *object, "create", JsWindowManager::CreateWindow);
551     BindNativeFunction(*engine, *object, "find", JsWindowManager::FindWindow);
552     BindNativeFunction(*engine, *object, "on", JsWindowManager::RegisterWindowManagerCallback);
553     BindNativeFunction(*engine, *object, "off", JsWindowManager::UnregisterWindowMangerCallback);
554     BindNativeFunction(*engine, *object, "getTopWindow", JsWindowManager::GetTopWindow);
555     BindNativeFunction(*engine, *object, "minimizeAll", JsWindowManager::MinimizeAll);
556     BindNativeFunction(*engine, *object, "setWindowLayoutMode", JsWindowManager::SetWindowLayoutMode);
557     return engine->CreateUndefined();
558 }
559 }  // namespace Rosen
560 }  // namespace OHOS