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 
16 #include "js_err_utils.h"
17 #include "js_window_stage.h"
18 #include "js_window.h"
19 #include "window_manager_hilog.h"
20 #include "permission.h"
21 
22 namespace OHOS {
23 namespace Rosen {
24 using namespace AbilityRuntime;
25 namespace {
26 const int CONTENT_STORAGE_ARG = 2;
27 constexpr size_t INDEX_ZERO = 0;
28 constexpr size_t FOUR_PARAMS_SIZE = 4;
29 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "JsWindowStage"};
30 } // namespace
31 
32 std::unique_ptr<JsWindowRegisterManager> g_listenerManager = std::make_unique<JsWindowRegisterManager>();
JsWindowStage(const std::shared_ptr<Rosen::WindowScene> & windowScene)33 JsWindowStage::JsWindowStage(const std::shared_ptr<Rosen::WindowScene>& windowScene)
34     : windowScene_(windowScene)
35 {
36 }
37 
~JsWindowStage()38 JsWindowStage::~JsWindowStage()
39 {
40 }
41 
Finalizer(napi_env env,void * data,void * hint)42 void JsWindowStage::Finalizer(napi_env env, void* data, void* hint)
43 {
44     WLOGI("[NAPI]Finalizer");
45     std::unique_ptr<JsWindowStage>(static_cast<JsWindowStage*>(data));
46 }
47 
SetUIContent(napi_env env,napi_callback_info info)48 napi_value JsWindowStage::SetUIContent(napi_env env, napi_callback_info info)
49 {
50     WLOGFI("[NAPI]");
51     JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(env, info);
52     return (me != nullptr) ? me->OnSetUIContent(env, info) : nullptr;
53 }
54 
GetMainWindow(napi_env env,napi_callback_info info)55 napi_value JsWindowStage::GetMainWindow(napi_env env, napi_callback_info info)
56 {
57     WLOGFD("[NAPI]GetMainWindow");
58     JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(env, info);
59     return (me != nullptr) ? me->OnGetMainWindow(env, info) : nullptr;
60 }
61 
GetMainWindowSync(napi_env env,napi_callback_info info)62 napi_value JsWindowStage::GetMainWindowSync(napi_env env, napi_callback_info info)
63 {
64     WLOGFD("[NAPI]GetMainWindowSync");
65     JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(env, info);
66     return (me != nullptr) ? me->OnGetMainWindowSync(env, info) : nullptr;
67 }
68 
On(napi_env env,napi_callback_info info)69 napi_value JsWindowStage::On(napi_env env, napi_callback_info info)
70 {
71     WLOGFD("[NAPI]On");
72     JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(env, info);
73     return (me != nullptr) ? me->OnEvent(env, info) : nullptr;
74 }
75 
Off(napi_env env,napi_callback_info info)76 napi_value JsWindowStage::Off(napi_env env, napi_callback_info info)
77 {
78     WLOGFD("[NAPI]Off");
79     JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(env, info);
80     return (me != nullptr) ? me->OffEvent(env, info) : nullptr;
81 }
82 
LoadContent(napi_env env,napi_callback_info info)83 napi_value JsWindowStage::LoadContent(napi_env env, napi_callback_info info)
84 {
85     WLOGFI("[NAPI]");
86     JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(env, info);
87     return (me != nullptr) ? me->OnLoadContent(env, info, false) : nullptr;
88 }
89 
LoadContentByName(napi_env env,napi_callback_info info)90 napi_value JsWindowStage::LoadContentByName(napi_env env, napi_callback_info info)
91 {
92     WLOGFI("[NAPI]");
93     JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(env, info);
94     return (me != nullptr) ? me->OnLoadContent(env, info, true) : nullptr;
95 }
96 
GetWindowMode(napi_env env,napi_callback_info info)97 napi_value JsWindowStage::GetWindowMode(napi_env env, napi_callback_info info)
98 {
99     WLOGFD("[NAPI]GetWindowMode");
100     JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(env, info);
101     return (me != nullptr) ? me->OnGetWindowMode(env, info) : nullptr;
102 }
103 
CreateSubWindow(napi_env env,napi_callback_info info)104 napi_value JsWindowStage::CreateSubWindow(napi_env env, napi_callback_info info)
105 {
106     WLOGFD("[NAPI]CreateSubWindow");
107     JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(env, info);
108     return (me != nullptr) ? me->OnCreateSubWindow(env, info) : nullptr;
109 }
110 
CreateSubWindowWithOptions(napi_env env,napi_callback_info info)111 napi_value JsWindowStage::CreateSubWindowWithOptions(napi_env env, napi_callback_info info)
112 {
113     WLOGFD("[NAPI]CreateSubWindowWithOptions");
114     JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(env, info);
115     return (me != nullptr) ? me->OnCreateSubWindowWithOptions(env, info) : nullptr;
116 }
117 
GetSubWindow(napi_env env,napi_callback_info info)118 napi_value JsWindowStage::GetSubWindow(napi_env env, napi_callback_info info)
119 {
120     WLOGFD("[NAPI]GetSubWindow");
121     JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(env, info);
122     return (me != nullptr) ? me->OnGetSubWindow(env, info) : nullptr;
123 }
124 
SetWindowModal(napi_env env,napi_callback_info info)125 napi_value JsWindowStage::SetWindowModal(napi_env env, napi_callback_info info)
126 {
127     TLOGD(WmsLogTag::WMS_MAIN, "[NAPI]");
128     JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(env, info);
129     return (me != nullptr) ? me->OnSetWindowModal(env, info) : nullptr;
130 }
131 
132 /** @note @window.hierarchy */
SetShowOnLockScreen(napi_env env,napi_callback_info info)133 napi_value JsWindowStage::SetShowOnLockScreen(napi_env env, napi_callback_info info)
134 {
135     WLOGFD("[NAPI]SetShowOnLockScreen");
136     JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(env, info);
137     return (me != nullptr) ? me->OnSetShowOnLockScreen(env, info) : nullptr;
138 }
139 
DisableWindowDecor(napi_env env,napi_callback_info info)140 napi_value JsWindowStage::DisableWindowDecor(napi_env env, napi_callback_info info)
141 {
142     WLOGFD("[NAPI]DisableWindowDecor");
143     JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(env, info);
144     return (me != nullptr) ? me->OnDisableWindowDecor(env, info) : nullptr;
145 }
146 
SetDefaultDensityEnabled(napi_env env,napi_callback_info info)147 napi_value JsWindowStage::SetDefaultDensityEnabled(napi_env env, napi_callback_info info)
148 {
149     TLOGD(WmsLogTag::WMS_LAYOUT, "SetDefaultDensityEnabled");
150     JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(env, info);
151     return (me != nullptr) ? me->OnSetDefaultDensityEnabled(env, info) : nullptr;
152 }
153 
RemoveStartingWindow(napi_env env,napi_callback_info info)154 napi_value JsWindowStage::RemoveStartingWindow(napi_env env, napi_callback_info info)
155 {
156     TLOGD(WmsLogTag::WMS_MAIN, "[NAPI]");
157     JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(env, info);
158     return (me != nullptr) ? me->OnRemoveStartingWindow(env, info) : nullptr;
159 }
160 
SetWindowRectAutoSave(napi_env env,napi_callback_info info)161 napi_value JsWindowStage::SetWindowRectAutoSave(napi_env env, napi_callback_info info)
162 {
163     TLOGD(WmsLogTag::WMS_MAIN, "[NAPI]");
164     JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(env, info);
165     return (me != nullptr) ? me->OnSetWindowRectAutoSave(env, info) : nullptr;
166 }
167 
IsWindowRectAutoSave(napi_env env,napi_callback_info info)168 napi_value JsWindowStage::IsWindowRectAutoSave(napi_env env, napi_callback_info info)
169 {
170     TLOGD(WmsLogTag::WMS_MAIN, "[NAPI]");
171     JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(env, info);
172     return (me != nullptr) ? me->OnIsWindowRectAutoSave(env, info) : nullptr;
173 }
174 
OnSetUIContent(napi_env env,napi_callback_info info)175 napi_value JsWindowStage::OnSetUIContent(napi_env env, napi_callback_info info)
176 {
177     size_t argc = 4;
178     napi_value argv[4] = {nullptr};
179     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
180     if (argc < 2) { // 2: minimum param num
181         WLOGFE("[NAPI]Argc is invalid: %{public}zu", argc);
182         return NapiGetUndefined(env);
183     }
184 
185     // Parse info->argv[0] as abilitycontext
186     auto objContext = argv[0];
187     if (objContext == nullptr) {
188         WLOGFE("[NAPI]Context is nullptr");
189         return NapiGetUndefined(env);
190     }
191 
192     // Parse info->argv[1] as url
193     std::string contextUrl;
194     if (!ConvertFromJsValue(env, argv[1], contextUrl)) {
195         WLOGFE("[NAPI]Failed to convert parameter to url");
196         return NapiGetUndefined(env);
197     }
198 
199     auto weakScene = windowScene_.lock();
200     if (weakScene == nullptr || weakScene->GetMainWindow() == nullptr) {
201         WLOGFE("[NAPI]WindowScene is null or window is null");
202         return NapiGetUndefined(env);
203     }
204     weakScene->GetMainWindow()->NapiSetUIContent(contextUrl, env, argv[CONTENT_STORAGE_ARG]);
205     return NapiGetUndefined(env);
206 }
207 
OnGetMainWindow(napi_env env,napi_callback_info info)208 napi_value JsWindowStage::OnGetMainWindow(napi_env env, napi_callback_info info)
209 {
210     NapiAsyncTask::CompleteCallback complete =
211         [weak = windowScene_](napi_env env, NapiAsyncTask& task, int32_t status) {
212             auto weakScene = weak.lock();
213             if (weakScene == nullptr) {
214                 task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STAGE_ABNORMALLY));
215                 WLOGFE("[NAPI]WindowScene_ is nullptr!");
216                 return;
217             }
218             auto window = weakScene->GetMainWindow();
219             if (window != nullptr) {
220                 task.Resolve(env, OHOS::Rosen::CreateJsWindowObject(env, window));
221                 WLOGI("[NAPI]Get main window [%{public}u, %{public}s]",
222                     window->GetWindowId(), window->GetWindowName().c_str());
223             } else {
224                 task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY,
225                     "Get main window failed."));
226             }
227         };
228     size_t argc = 4;
229     napi_value argv[4] = {nullptr};
230     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
231     napi_value callback = (argv[0] != nullptr && GetType(env, argv[0]) == napi_function) ?
232         argv[0] : nullptr;
233     napi_value result = nullptr;
234     NapiAsyncTask::Schedule("JsWindowStage::OnGetMainWindow",
235         env, CreateAsyncTaskWithLastParam(env, callback, nullptr, std::move(complete), &result));
236     return result;
237 }
238 
OnGetMainWindowSync(napi_env env,napi_callback_info info)239 napi_value JsWindowStage::OnGetMainWindowSync(napi_env env, napi_callback_info info)
240 {
241     auto weakScene = windowScene_.lock();
242     if (weakScene == nullptr) {
243         WLOGFE("[NAPI]WindowScene is null");
244         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STAGE_ABNORMALLY));
245         return NapiGetUndefined(env);
246     }
247     auto window = weakScene->GetMainWindow();
248     if (window == nullptr) {
249         WLOGFE("[NAPI]window is null");
250         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
251         return NapiGetUndefined(env);
252     }
253 
254     return OHOS::Rosen::CreateJsWindowObject(env, window);
255 }
256 
OnEvent(napi_env env,napi_callback_info info)257 napi_value JsWindowStage::OnEvent(napi_env env, napi_callback_info info)
258 {
259     auto weakScene = windowScene_.lock();
260     if (weakScene == nullptr) {
261         WLOGFE("[NAPI]Window scene is null");
262         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
263         return NapiGetUndefined(env);
264     }
265     size_t argc = 4;
266     napi_value argv[4] = {nullptr};
267     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
268     if (argc < 2) { // 2: minimum param nums
269         WLOGFE("[NAPI]argc is invalid: %{public}zu", argc);
270         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
271         return NapiGetUndefined(env);
272     }
273 
274     // Parse argv[0] as string
275     std::string eventString;
276     if (!ConvertFromJsValue(env, argv[0], eventString)) {
277         WLOGFE("[NAPI]Failed to convert parameter to string");
278         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
279         return NapiGetUndefined(env);
280     }
281     napi_value value = argv[1];
282     if (!NapiIsCallable(env, value)) {
283         WLOGFE("[NAPI]Callback(argv[1]) is not callable");
284         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
285         return NapiGetUndefined(env);
286     }
287 
288     auto window = weakScene->GetMainWindow();
289     if (window == nullptr) {
290         WLOGFE("[NAPI]Get window failed");
291         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
292         return NapiGetUndefined(env);
293     }
294     auto ret = g_listenerManager->RegisterListener(window, eventString, CaseType::CASE_STAGE, env, value);
295     if (ret != WmErrorCode::WM_OK) {
296         TLOGE(WmsLogTag::DEFAULT, "register event %{public}s failed, ret = %{public}d", eventString.c_str(), ret);
297         napi_throw(env, JsErrUtils::CreateJsError(env, ret));
298         return NapiGetUndefined(env);
299     }
300     WLOGI("[NAPI]Window [%{public}u, %{public}s] register event %{public}s",
301         window->GetWindowId(), window->GetWindowName().c_str(), eventString.c_str());
302 
303     return NapiGetUndefined(env);
304 }
305 
OffEvent(napi_env env,napi_callback_info info)306 napi_value JsWindowStage::OffEvent(napi_env env, napi_callback_info info)
307 {
308     auto weakScene = windowScene_.lock();
309     if (weakScene == nullptr) {
310         WLOGFE("[NAPI]Window scene is null");
311         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
312         return NapiGetUndefined(env);
313     }
314     size_t argc = 4;
315     napi_value argv[4] = {nullptr};
316     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
317     // Parse argv[0] as string
318     std::string eventString;
319     if (!ConvertFromJsValue(env, argv[0], eventString)) {
320         WLOGFE("[NAPI]Failed to convert parameter to string");
321         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
322         return NapiGetUndefined(env);
323     }
324 
325     auto window = weakScene->GetMainWindow();
326     if (window == nullptr) {
327         WLOGFE("[NAPI]Get window failed");
328         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
329         return NapiGetUndefined(env);
330     }
331     napi_value value = nullptr;
332     WmErrorCode ret = WmErrorCode::WM_OK;
333     if (argc == 1) {
334         ret = g_listenerManager->UnregisterListener(window, eventString, CaseType::CASE_STAGE, env, nullptr);
335     } else {
336         value = argv[1];
337         if (value != nullptr && GetType(env, value) == napi_function) {
338             ret = g_listenerManager->UnregisterListener(window, eventString, CaseType::CASE_STAGE, env, value);
339         } else {
340             ret = g_listenerManager->UnregisterListener(window, eventString, CaseType::CASE_STAGE, env, nullptr);
341         }
342     }
343     if (ret != WmErrorCode::WM_OK) {
344         TLOGE(WmsLogTag::DEFAULT, "unregister event %{public}s failed, ret = %{public}d", eventString.c_str(), ret);
345         napi_throw(env, JsErrUtils::CreateJsError(env, ret));
346         return NapiGetUndefined(env);
347     }
348     WLOGI("[NAPI]Window [%{public}u, %{public}s] unregister event %{public}s",
349         window->GetWindowId(), window->GetWindowName().c_str(), eventString.c_str());
350 
351     return NapiGetUndefined(env);
352 }
353 
LoadContentTask(std::shared_ptr<NativeReference> contentStorage,std::string contextUrl,sptr<Window> weakWindow,napi_env env,NapiAsyncTask & task,bool isLoadedByName)354 static void LoadContentTask(std::shared_ptr<NativeReference> contentStorage, std::string contextUrl,
355     sptr<Window> weakWindow, napi_env env, NapiAsyncTask& task, bool isLoadedByName)
356 {
357     napi_value nativeStorage = (contentStorage == nullptr) ? nullptr : contentStorage->GetNapiValue();
358     WMError ret;
359     if (isLoadedByName) {
360         ret = weakWindow->SetUIContentByName(contextUrl, env, nativeStorage);
361     } else {
362         ret = weakWindow->NapiSetUIContent(contextUrl, env, nativeStorage);
363     }
364     if (ret == WMError::WM_OK) {
365         task.Resolve(env, NapiGetUndefined(env));
366     } else {
367         task.Reject(env, JsErrUtils::CreateJsError(env, WM_JS_TO_ERROR_CODE_MAP.at(ret),
368             "Window load content failed"));
369     }
370     WLOGI("[NAPI]Window [%{public}u, %{public}s] load content end, ret = %{public}d",
371         weakWindow->GetWindowId(), weakWindow->GetWindowName().c_str(), ret);
372     return;
373 }
374 
OnLoadContent(napi_env env,napi_callback_info info,bool isLoadedByName)375 napi_value JsWindowStage::OnLoadContent(napi_env env, napi_callback_info info, bool isLoadedByName)
376 {
377     WmErrorCode errCode = WmErrorCode::WM_OK;
378     std::string contextUrl;
379     size_t argc = 4;
380     napi_value argv[4] = {nullptr};
381     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
382     if (!ConvertFromJsValue(env, argv[0], contextUrl)) {
383         WLOGFE("[NAPI]Failed to convert parameter to context url");
384         errCode = WmErrorCode::WM_ERROR_INVALID_PARAM;
385     }
386     napi_value storage = nullptr;
387     napi_value callBack = nullptr;
388     napi_value value1 = argv[1];
389     napi_value value2 = argv[2]; // 2: param index
390     if (GetType(env, value1) == napi_function) {
391         callBack = value1;
392     } else if (GetType(env, value1) == napi_object) {
393         storage = value1;
394     }
395     if (GetType(env, value2) == napi_function) {
396         callBack = value2;
397     }
398     if (errCode == WmErrorCode::WM_ERROR_INVALID_PARAM) {
399         WLOGFE("[NAPI]Window scene is null or get invalid param");
400         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
401         return NapiGetUndefined(env);
402     }
403 
404     std::shared_ptr<NativeReference> contentStorage = nullptr;
405     if (storage != nullptr) {
406         napi_ref result = nullptr;
407         napi_create_reference(env, storage, 1, &result);
408         contentStorage = std::shared_ptr<NativeReference>(reinterpret_cast<NativeReference*>(result));
409     }
410 
411     NapiAsyncTask::CompleteCallback complete =
412         [weak = windowScene_, contentStorage, contextUrl, isLoadedByName](
413             napi_env env, NapiAsyncTask& task, int32_t status) {
414             auto weakScene = weak.lock();
415             sptr<Window> win = weakScene ? weakScene->GetMainWindow() : nullptr;
416             if (win == nullptr) {
417                 task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
418                 WLOGFE("[NAPI]Get window failed");
419                 return;
420             }
421             LoadContentTask(contentStorage, contextUrl, win, env, task, isLoadedByName);
422         };
423     napi_value result = nullptr;
424     NapiAsyncTask::Schedule("JsWindowStage::OnLoadContent",
425         env, CreateAsyncTaskWithLastParam(env, callBack, nullptr, std::move(complete), &result));
426     return result;
427 }
428 
OnGetWindowMode(napi_env env,napi_callback_info info)429 napi_value JsWindowStage::OnGetWindowMode(napi_env env, napi_callback_info info)
430 {
431     NapiAsyncTask::CompleteCallback complete =
432         [weak = windowScene_](napi_env env, NapiAsyncTask& task, int32_t status) {
433             auto weakScene = weak.lock();
434             if (weakScene == nullptr) {
435                 task.Reject(env, JsErrUtils::CreateJsError(env, WMError::WM_ERROR_NULLPTR));
436                 WLOGFE("[NAPI]windowScene_ is nullptr");
437                 return;
438             }
439             auto window = weakScene->GetMainWindow();
440             if (window == nullptr) {
441                 task.Reject(env, JsErrUtils::CreateJsError(env, WMError::WM_ERROR_NULLPTR, "Get window failed"));
442                 WLOGFE("[NAPI]Get window failed");
443                 return;
444             }
445             Rosen::WindowMode mode = window->GetMode();
446             if (NATIVE_TO_JS_WINDOW_MODE_MAP.count(mode) != 0) {
447                 task.Resolve(env, CreateJsValue(env, NATIVE_TO_JS_WINDOW_MODE_MAP.at(mode)));
448                 WLOGI("[NAPI]Window [%{public}u, %{public}s] get mode %{public}u, api mode %{public}u",
449                     window->GetWindowId(), window->GetWindowName().c_str(),
450                     mode, NATIVE_TO_JS_WINDOW_MODE_MAP.at(mode));
451             } else {
452                 task.Resolve(env, CreateJsValue(env, mode));
453                 WLOGFE("[NAPI]Get mode %{public}u, but not in apimode", mode);
454             }
455         };
456 
457     size_t argc = 4;
458     napi_value argv[4] = {nullptr};
459     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
460     napi_value callback = (GetType(env, argv[0]) == napi_function) ? argv[0] : nullptr;
461     napi_value result = nullptr;
462     NapiAsyncTask::Schedule("JsWindowStage::OnGetWindowMode",
463         env, CreateAsyncTaskWithLastParam(env, callback, nullptr, std::move(complete), &result));
464     return result;
465 }
466 
OnCreateSubWindow(napi_env env,napi_callback_info info)467 napi_value JsWindowStage::OnCreateSubWindow(napi_env env, napi_callback_info info)
468 {
469     WmErrorCode errCode = WmErrorCode::WM_OK;
470     std::string windowName;
471     size_t argc = 4;
472     napi_value argv[4] = {nullptr};
473     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
474     if (!ConvertFromJsValue(env, argv[0], windowName)) {
475         WLOGFE("[NAPI]Failed to convert parameter to windowName");
476         errCode = WmErrorCode::WM_ERROR_INVALID_PARAM;
477     }
478     if (errCode == WmErrorCode::WM_ERROR_INVALID_PARAM) {
479         WLOGFE("[NAPI]get invalid param");
480         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
481         return NapiGetUndefined(env);
482     }
483     NapiAsyncTask::CompleteCallback complete =
484         [weak = windowScene_, windowName](napi_env env, NapiAsyncTask& task, int32_t status) {
485             auto weakScene = weak.lock();
486             if (weakScene == nullptr) {
487                 WLOGFE("[NAPI]Window scene is null");
488                 task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
489                 return;
490             }
491             sptr<Rosen::WindowOption> windowOption = new Rosen::WindowOption();
492             windowOption->SetWindowType(Rosen::WindowType::WINDOW_TYPE_APP_SUB_WINDOW);
493             windowOption->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_FLOATING);
494             auto window = weakScene->CreateWindow(windowName, windowOption);
495             if (window == nullptr) {
496                 WLOGFE("[NAPI]Get window failed");
497                 task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY,
498                     "Get window failed"));
499                 return;
500             }
501             task.Resolve(env, CreateJsWindowObject(env, window));
502             WLOGI("[NAPI]Create sub window %{public}s end", windowName.c_str());
503         };
504     napi_value callback = (argv[1] != nullptr && GetType(env, argv[1]) == napi_function) ? argv[1] : nullptr;
505     napi_value result = nullptr;
506     NapiAsyncTask::Schedule("JsWindowStage::OnCreateSubWindow",
507         env, CreateAsyncTaskWithLastParam(env, callback, nullptr, std::move(complete), &result));
508     return result;
509 }
510 
CreateJsSubWindowArrayObject(napi_env env,std::vector<sptr<Window>> subWinVec)511 static napi_value CreateJsSubWindowArrayObject(napi_env env,
512     std::vector<sptr<Window>> subWinVec)
513 {
514     napi_value arrayValue = nullptr;
515     napi_create_array_with_length(env, subWinVec.size(), &arrayValue);
516     if (arrayValue == nullptr) {
517         WLOGFE("[NAPI]Failed to convert subWinVec to jsArrayObject");
518         return nullptr;
519     }
520     uint32_t index = 0;
521     for (size_t i = 0; i < subWinVec.size(); i++) {
522         napi_set_element(env, arrayValue, index++, CreateJsWindowObject(env, subWinVec[i]));
523     }
524     return arrayValue;
525 }
526 
OnGetSubWindow(napi_env env,napi_callback_info info)527 napi_value JsWindowStage::OnGetSubWindow(napi_env env, napi_callback_info info)
528 {
529     NapiAsyncTask::CompleteCallback complete =
530         [weak = windowScene_](napi_env env, NapiAsyncTask& task, int32_t status) {
531             auto weakScene = weak.lock();
532             if (weakScene == nullptr) {
533                 WLOGFE("[NAPI]Window scene is nullptr");
534                 task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
535                 return;
536             }
537             std::vector<sptr<Window>> subWindowVec = weakScene->GetSubWindow();
538             task.Resolve(env, CreateJsSubWindowArrayObject(env, subWindowVec));
539             WLOGI("[NAPI]Get sub windows, size = %{public}zu", subWindowVec.size());
540         };
541     size_t argc = 4;
542     napi_value argv[4] = {nullptr};
543     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
544     napi_value callback = (argv[0] != nullptr && GetType(env, argv[0]) == napi_function) ? argv[0] : nullptr;
545     napi_value result = nullptr;
546     NapiAsyncTask::Schedule("JsWindowStage::OnGetSubWindow",
547         env, CreateAsyncTaskWithLastParam(env, callback, nullptr, std::move(complete), &result));
548     return result;
549 }
550 
OnSetWindowModal(napi_env env,napi_callback_info info)551 napi_value JsWindowStage::OnSetWindowModal(napi_env env, napi_callback_info info)
552 {
553     auto windowScene = windowScene_.lock();
554     if (windowScene == nullptr) {
555         TLOGE(WmsLogTag::WMS_MAIN, "WindowScene is null");
556         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STAGE_ABNORMALLY));
557         return NapiGetUndefined(env);
558     }
559     auto window = windowScene->GetMainWindow();
560     if (window == nullptr) {
561         TLOGE(WmsLogTag::WMS_MAIN, "window is nullptr");
562         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STAGE_ABNORMALLY));
563         return NapiGetUndefined(env);
564     }
565     if (!window->IsPcOrPadFreeMultiWindowMode()) {
566         TLOGE(WmsLogTag::WMS_MAIN, "device not support");
567         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT));
568         return NapiGetUndefined(env);
569     }
570     size_t argc = FOUR_PARAMS_SIZE;
571     napi_value argv[FOUR_PARAMS_SIZE] = { nullptr };
572     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
573     if (argc != 1) {
574         TLOGE(WmsLogTag::WMS_MAIN, "Argc is invalid: %{public}zu", argc);
575         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
576         return NapiGetUndefined(env);
577     }
578     bool isModal = false;
579     if (!ConvertFromJsValue(env, argv[INDEX_ZERO], isModal)) {
580         TLOGE(WmsLogTag::WMS_MAIN, "Failed to convert parameter to bool");
581         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
582         return NapiGetUndefined(env);
583     }
584     napi_value result = nullptr;
585     std::shared_ptr<NapiAsyncTask> napiAsyncTask = CreateEmptyAsyncTask(env, nullptr, &result);
586     const char* const where = __func__;
587     auto asyncTask = [where, weakWindow = wptr(window), isModal, env, task = napiAsyncTask] {
588         auto window = weakWindow.promote();
589         if (window == nullptr) {
590             TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s failed, window is null", where);
591             task->Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
592             return;
593         }
594         WMError ret = window->SetWindowModal(isModal);
595         if (ret != WMError::WM_OK) {
596             WmErrorCode wmErrorCode = WM_JS_TO_ERROR_CODE_MAP.at(ret);
597             TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s failed, ret is %{public}d", where, wmErrorCode);
598             task->Reject(env, JsErrUtils::CreateJsError(env, wmErrorCode, "Set main window modal failed"));
599             return;
600         }
601         task->Resolve(env, NapiGetUndefined(env));
602         TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s id:%{public}u, name:%{public}s, isModal:%{public}d",
603             where, window->GetWindowId(), window->GetWindowName().c_str(), isModal);
604     };
605     if (napi_status::napi_ok != napi_send_event(env, asyncTask, napi_eprio_high)) {
606         napiAsyncTask->Reject(env,
607             CreateJsError(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY), "send event failed"));
608     }
609     return result;
610 }
611 
OnSetShowOnLockScreen(napi_env env,napi_callback_info info)612 napi_value JsWindowStage::OnSetShowOnLockScreen(napi_env env, napi_callback_info info)
613 {
614     if (!Permission::IsSystemCalling() && !Permission::IsStartByHdcd()) {
615         WLOGFE("set show on lock screen permission denied!");
616         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_NOT_SYSTEM_APP));
617         return CreateJsValue(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_NOT_SYSTEM_APP));
618     }
619 
620     size_t argc = 4;
621     napi_value argv[4] = {nullptr};
622     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
623     if (argc < 1) {
624         WLOGFE("[NAPI]Argc is invalid: %{public}zu", argc);
625         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
626         return CreateJsValue(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_INVALID_PARAM));
627     }
628     auto weakScene = windowScene_.lock();
629     if (weakScene == nullptr || weakScene->GetMainWindow() == nullptr) {
630         WLOGFE("[NAPI]WindowScene is null or window is null");
631         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
632         return CreateJsValue(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
633     }
634 
635     bool showOnLockScreen = false;
636     napi_value nativeVal = argv[0];
637     if (nativeVal == nullptr) {
638         WLOGFE("[NAPI]Failed to convert parameter to boolean");
639         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
640         return CreateJsValue(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_INVALID_PARAM));
641     } else {
642         napi_get_value_bool(env, nativeVal, &showOnLockScreen);
643     }
644 
645     auto window = weakScene->GetMainWindow();
646     WmErrorCode ret;
647     if (showOnLockScreen) {
648         ret = WM_JS_TO_ERROR_CODE_MAP.at(
649             window->AddWindowFlag(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED));
650     } else {
651         ret = WM_JS_TO_ERROR_CODE_MAP.at(
652             window->RemoveWindowFlag(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED));
653     }
654     WLOGI("[NAPI]Window [%{public}u, %{public}s] SetShowOnLockScreen %{public}u, ret = %{public}u",
655         window->GetWindowId(), window->GetWindowName().c_str(), showOnLockScreen, ret);
656 
657     return CreateJsValue(env, static_cast<int32_t>(ret));
658 }
659 
OnDisableWindowDecor(napi_env env,napi_callback_info info)660 napi_value JsWindowStage::OnDisableWindowDecor(napi_env env, napi_callback_info info)
661 {
662     auto weakScene = windowScene_.lock();
663     if (weakScene == nullptr) {
664         WLOGFE("[NAPI]WindowScene is null");
665         return CreateJsValue(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_STAGE_ABNORMALLY));
666     }
667 
668     auto window = weakScene->GetMainWindow();
669     if (window == nullptr) {
670         WLOGFE("[NAPI]Window is null");
671         return CreateJsValue(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
672     }
673     WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(window->DisableAppWindowDecor());
674     if (ret != WmErrorCode::WM_OK) {
675         napi_throw(env, JsErrUtils::CreateJsError(env, ret));
676     WLOGI("[NAPI]Window [%{public}u, %{public}s] disable app window decor end",
677         window->GetWindowId(), window->GetWindowName().c_str());
678         return NapiGetUndefined(env);
679     }
680     return NapiGetUndefined(env);
681 }
682 
OnSetDefaultDensityEnabled(napi_env env,napi_callback_info info)683 napi_value JsWindowStage::OnSetDefaultDensityEnabled(napi_env env, napi_callback_info info)
684 {
685     size_t argc = 4;
686     napi_value argv[4] = {nullptr};
687     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
688     if (argc != 1) {
689         TLOGE(WmsLogTag::WMS_LAYOUT, "Argc is invalid: %{public}zu", argc);
690         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
691         return CreateJsValue(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_INVALID_PARAM));
692     }
693 
694     auto weakScene = windowScene_.lock();
695     if (weakScene == nullptr) {
696         TLOGE(WmsLogTag::WMS_LAYOUT, "WindowScene is null");
697         return CreateJsValue(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_STAGE_ABNORMALLY));
698     }
699 
700     auto window = weakScene->GetMainWindow();
701     if (window == nullptr) {
702         TLOGE(WmsLogTag::WMS_LAYOUT, "Window is null");
703         return CreateJsValue(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
704     }
705 
706     bool enabled = false;
707     if (!ConvertFromJsValue(env, argv[0], enabled)) {
708         TLOGE(WmsLogTag::WMS_LAYOUT, "Failed to convert parameter to boolean");
709         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
710         return CreateJsValue(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_INVALID_PARAM));
711     }
712 
713     WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(window->SetDefaultDensityEnabled(enabled));
714     TLOGI(WmsLogTag::WMS_LAYOUT, "Window [%{public}u,%{public}s] SetDefaultDensityEnabled=%{public}u ret=%{public}u",
715         window->GetWindowId(), window->GetWindowName().c_str(), enabled, ret);
716 
717     return CreateJsValue(env, static_cast<int32_t>(ret));
718 }
719 
OnCreateSubWindowWithOptions(napi_env env,napi_callback_info info)720 napi_value JsWindowStage::OnCreateSubWindowWithOptions(napi_env env, napi_callback_info info)
721 {
722     auto windowScene = windowScene_.lock();
723     if (windowScene == nullptr) {
724         TLOGE(WmsLogTag::WMS_SUB, "WindowScene is null");
725         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STAGE_ABNORMALLY));
726         return NapiGetUndefined(env);
727     }
728     size_t argc = 4;
729     napi_value argv[4] = {nullptr};
730     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
731     std::string windowName;
732     if (!ConvertFromJsValue(env, argv[0], windowName)) {
733         WLOGFE("[NAPI]Failed to convert parameter to windowName");
734         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
735         return NapiGetUndefined(env);
736     }
737     sptr<WindowOption> option = new WindowOption();
738     if (!ParseSubWindowOptions(env, argv[1], option)) {
739         WLOGFE("[NAPI]get invalid options param");
740         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
741         return NapiGetUndefined(env);
742     }
743     if ((option->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_APPLICATION_MODAL)) &&
744         !windowScene->GetMainWindow()->IsPcOrPadFreeMultiWindowMode()) {
745         TLOGE(WmsLogTag::WMS_SUB, "device not support");
746         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT));
747         return NapiGetUndefined(env);
748     }
749 
750     if (option->GetWindowTopmost() && !Permission::IsSystemCalling() && !Permission::IsStartByHdcd()) {
751         TLOGE(WmsLogTag::WMS_SUB, "Modal subwindow has topmost, but no system permission");
752         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_NOT_SYSTEM_APP));
753         return NapiGetUndefined(env);
754     }
755 
756     const char* const where = __func__;
757     NapiAsyncTask::CompleteCallback complete =
758         [where, windowScene, windowName = std::move(windowName), option]
759             (napi_env env, NapiAsyncTask& task, int32_t status) mutable {
760         option->SetWindowType(WindowType::WINDOW_TYPE_APP_SUB_WINDOW);
761         option->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
762         option->SetOnlySupportSceneBoard(true);
763         auto window = windowScene->CreateWindow(windowName, option);
764         if (window == nullptr) {
765             TLOGNE(WmsLogTag::WMS_SUB, "%{public}s [NAPI]Get window failed", where);
766             task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY,
767                 "Get window failed"));
768             return;
769         }
770         task.Resolve(env, CreateJsWindowObject(env, window));
771         TLOGNI(WmsLogTag::WMS_SUB, "%{public}s [NAPI]Create sub window %{public}s end",
772             where, windowName.c_str());
773     };
774     napi_value callback = (argv[2] != nullptr && GetType(env, argv[2]) == napi_function) ? argv[2] : nullptr;
775     napi_value result = nullptr;
776     NapiAsyncTask::Schedule("JsWindowStage::OnCreateSubWindowWithOptions",
777         env, CreateAsyncTaskWithLastParam(env, callback, nullptr, std::move(complete), &result));
778     return result;
779 }
780 
OnRemoveStartingWindow(napi_env env,napi_callback_info info)781 napi_value JsWindowStage::OnRemoveStartingWindow(napi_env env, napi_callback_info info)
782 {
783     auto windowScene = windowScene_.lock();
784     if (windowScene == nullptr) {
785         TLOGE(WmsLogTag::WMS_MAIN, "windowScene is null");
786         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
787         return NapiGetUndefined(env);
788     }
789 
790     const char* const where = __func__;
791     NapiAsyncTask::CompleteCallback complete =
792         [where, windowScene](napi_env env, NapiAsyncTask& task, int32_t status) {
793         auto window = windowScene->GetMainWindow();
794         if (window == nullptr) {
795             TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s [NAPI]Get main window failed", where);
796             task.Reject(env,
797                 JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY, "Get main window failed"));
798             return;
799         }
800         WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(window->NotifyRemoveStartingWindow());
801         if (ret == WmErrorCode::WM_OK) {
802             task.Resolve(env, NapiGetUndefined(env));
803         } else {
804             task.Reject(env, JsErrUtils::CreateJsError(env, ret, "Notify remove starting window failed"));
805         }
806     };
807 
808     size_t argc = FOUR_PARAMS_SIZE;
809     napi_value argv[FOUR_PARAMS_SIZE] = {nullptr};
810     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
811     napi_value lastParam = (argc == 0) ? nullptr :
812         (argv[INDEX_ZERO] != nullptr && GetType(env, argv[INDEX_ZERO]) == napi_function ? argv[INDEX_ZERO] : nullptr);
813     napi_value result = nullptr;
814     NapiAsyncTask::Schedule("JsWindow::OnRemoveStartingWindow",
815         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
816     return result;
817 }
818 
OnSetWindowRectAutoSave(napi_env env,napi_callback_info info)819 napi_value JsWindowStage::OnSetWindowRectAutoSave(napi_env env, napi_callback_info info)
820 {
821     auto windowScene = windowScene_.lock();
822     if (windowScene == nullptr) {
823         TLOGE(WmsLogTag::WMS_MAIN, "WindowScene is null");
824         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
825         return NapiGetUndefined(env);
826     }
827 
828     size_t argc = FOUR_PARAMS_SIZE;
829     napi_value argv[FOUR_PARAMS_SIZE] = { nullptr };
830     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
831     if (argc != 1) { // 1: maximum params num
832         TLOGE(WmsLogTag::WMS_MAIN, "Argc is invalid: %{public}zu", argc);
833         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
834         return NapiGetUndefined(env);
835     }
836     bool enabled = false;
837     if (!ConvertFromJsValue(env, argv[INDEX_ZERO], enabled)) {
838         TLOGE(WmsLogTag::WMS_MAIN, "[NAPI]Failed to convert parameter to enabled");
839         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
840         return NapiGetUndefined(env);
841     }
842 
843     auto window = windowScene->GetMainWindow();
844     const char* const where = __func__;
845     napi_value result = nullptr;
846     std::shared_ptr<NapiAsyncTask> napiAsyncTask = CreateEmptyAsyncTask(env, nullptr, &result);
847     auto asyncTask = [weakWindow = wptr(window), where, env, task = napiAsyncTask, enabled] {
848         auto window = weakWindow.promote();
849         if (window == nullptr) {
850             TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s window is nullptr", where);
851             WmErrorCode wmErroeCode = WM_JS_TO_ERROR_CODE_MAP.at(WMError::WM_ERROR_NULLPTR);
852             task->Reject(env, JsErrUtils::CreateJsError(env, wmErroeCode, "window is nullptr."));
853             return;
854         }
855         WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(window->SetWindowRectAutoSave(enabled));
856         if (ret != WmErrorCode::WM_OK) {
857             TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s enable recover position failed!", where);
858             task->Reject(env, JsErrUtils::CreateJsError(env,
859                 ret, "window recover position failed."));
860         } else {
861             task->Resolve(env, NapiGetUndefined(env));
862         }
863     };
864     if (napi_status::napi_ok != napi_send_event(env, asyncTask, napi_eprio_high)) {
865         napiAsyncTask->Reject(env,
866             CreateJsError(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY), "send event failed"));
867     }
868     return result;
869 }
870 
OnIsWindowRectAutoSave(napi_env env,napi_callback_info info)871 napi_value JsWindowStage::OnIsWindowRectAutoSave(napi_env env, napi_callback_info info)
872 {
873     auto windowScene = windowScene_.lock();
874     if (windowScene == nullptr) {
875         TLOGE(WmsLogTag::WMS_MAIN, "WindowScene is null");
876         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
877         return NapiGetUndefined(env);
878     }
879 
880     auto window = windowScene->GetMainWindow();
881     const char* const where = __func__;
882     napi_value result = nullptr;
883     std::shared_ptr<NapiAsyncTask> napiAsyncTask = CreateEmptyAsyncTask(env, nullptr, &result);
884     auto asyncTask = [weakWindow = wptr(window), where, env, task = napiAsyncTask] {
885         auto window = weakWindow.promote();
886         if (window == nullptr) {
887             TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s Window is nullptr", where);
888             task->Reject(env,
889                 JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY, "Window is nullptr."));
890             return;
891         }
892         bool enabled = false;
893         WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(window->IsWindowRectAutoSave(enabled));
894         if (ret != WmErrorCode::WM_OK) {
895             TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s get the auto-save state of the window rect failed!", where);
896             task->Reject(env, JsErrUtils::CreateJsError(env,
897                 ret, "Window recover position failed."));
898         } else {
899             napi_value jsEnabled = CreateJsValue(env, enabled);
900             task->Resolve(env, jsEnabled);
901         }
902     };
903     if (napi_status::napi_ok != napi_send_event(env, asyncTask, napi_eprio_high)) {
904         napiAsyncTask->Reject(env,
905             CreateJsError(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY), "send event failed"));
906     }
907     return result;
908 }
909 
CreateJsWindowStage(napi_env env,std::shared_ptr<Rosen::WindowScene> windowScene)910 napi_value CreateJsWindowStage(napi_env env, std::shared_ptr<Rosen::WindowScene> windowScene)
911 {
912     WLOGFD("[NAPI]CreateJsWindowStage");
913     napi_value objValue = nullptr;
914     napi_create_object(env, &objValue);
915 
916     std::unique_ptr<JsWindowStage> jsWindowStage = std::make_unique<JsWindowStage>(windowScene);
917     napi_wrap(env, objValue, jsWindowStage.release(), JsWindowStage::Finalizer, nullptr, nullptr);
918 
919     const char* moduleName = "JsWindowStage";
920     BindNativeFunction(env,
921         objValue, "setUIContent", moduleName, JsWindowStage::SetUIContent);
922     BindNativeFunction(env,
923         objValue, "loadContent", moduleName, JsWindowStage::LoadContent);
924     BindNativeFunction(env,
925         objValue, "loadContentByName", moduleName, JsWindowStage::LoadContentByName);
926     BindNativeFunction(env,
927         objValue, "getMainWindow", moduleName, JsWindowStage::GetMainWindow);
928     BindNativeFunction(env,
929         objValue, "getMainWindowSync", moduleName, JsWindowStage::GetMainWindowSync);
930     BindNativeFunction(env,
931         objValue, "getWindowMode", moduleName, JsWindowStage::GetWindowMode);
932     BindNativeFunction(env,
933         objValue, "createSubWindow", moduleName, JsWindowStage::CreateSubWindow);
934     BindNativeFunction(env,
935         objValue, "createSubWindowWithOptions", moduleName, JsWindowStage::CreateSubWindowWithOptions);
936     BindNativeFunction(env,
937         objValue, "getSubWindow", moduleName, JsWindowStage::GetSubWindow);
938     BindNativeFunction(env, objValue, "setWindowModal", moduleName, JsWindowStage::SetWindowModal);
939     BindNativeFunction(env, objValue, "on", moduleName, JsWindowStage::On);
940     BindNativeFunction(env, objValue, "off", moduleName, JsWindowStage::Off);
941     BindNativeFunction(env,
942         objValue, "setShowOnLockScreen", moduleName, JsWindowStage::SetShowOnLockScreen);
943     BindNativeFunction(env,
944         objValue, "disableWindowDecor", moduleName, JsWindowStage::DisableWindowDecor);
945     BindNativeFunction(env,
946         objValue, "setDefaultDensityEnabled", moduleName, JsWindowStage::SetDefaultDensityEnabled);
947     BindNativeFunction(env,
948         objValue, "removeStartingWindow", moduleName, JsWindowStage::RemoveStartingWindow);
949     BindNativeFunction(env,
950         objValue, "setWindowRectAutoSave", moduleName, JsWindowStage::SetWindowRectAutoSave);
951     BindNativeFunction(env,
952         objValue, "isWindowRectAutoSave", moduleName, JsWindowStage::IsWindowRectAutoSave);
953     return objValue;
954 }
955 }  // namespace Rosen
956 }  // namespace OHOS
957