• 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 
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 
SetCustomDensity(napi_env env,napi_callback_info info)154 napi_value JsWindowStage::SetCustomDensity(napi_env env, napi_callback_info info)
155 {
156     TLOGD(WmsLogTag::WMS_ATTRIBUTE, "[NAPI]");
157     JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(env, info);
158     return (me != nullptr) ? me->OnSetCustomDensity(env, info) : nullptr;
159 }
160 
RemoveStartingWindow(napi_env env,napi_callback_info info)161 napi_value JsWindowStage::RemoveStartingWindow(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->OnRemoveStartingWindow(env, info) : nullptr;
166 }
167 
SetWindowRectAutoSave(napi_env env,napi_callback_info info)168 napi_value JsWindowStage::SetWindowRectAutoSave(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->OnSetWindowRectAutoSave(env, info) : nullptr;
173 }
174 
IsWindowRectAutoSave(napi_env env,napi_callback_info info)175 napi_value JsWindowStage::IsWindowRectAutoSave(napi_env env, napi_callback_info info)
176 {
177     TLOGD(WmsLogTag::WMS_MAIN, "[NAPI]");
178     JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(env, info);
179     return (me != nullptr) ? me->OnIsWindowRectAutoSave(env, info) : nullptr;
180 }
181 
SetSupportedWindowModes(napi_env env,napi_callback_info info)182 napi_value JsWindowStage::SetSupportedWindowModes(napi_env env, napi_callback_info info)
183 {
184     TLOGD(WmsLogTag::WMS_LAYOUT_PC, "[NAPI]");
185     JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(env, info);
186     return (me != nullptr) ? me->OnSetSupportedWindowModes(env, info) : nullptr;
187 }
188 
OnSetUIContent(napi_env env,napi_callback_info info)189 napi_value JsWindowStage::OnSetUIContent(napi_env env, napi_callback_info info)
190 {
191     size_t argc = 4;
192     napi_value argv[4] = {nullptr};
193     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
194     if (argc < 2) { // 2: minimum param num
195         WLOGFE("[NAPI]Argc is invalid: %{public}zu", argc);
196         return NapiGetUndefined(env);
197     }
198 
199     // Parse info->argv[0] as abilitycontext
200     auto objContext = argv[0];
201     if (objContext == nullptr) {
202         WLOGFE("[NAPI]Context is nullptr");
203         return NapiGetUndefined(env);
204     }
205 
206     // Parse info->argv[1] as url
207     std::string contextUrl;
208     if (!ConvertFromJsValue(env, argv[1], contextUrl)) {
209         WLOGFE("[NAPI]Failed to convert parameter to url");
210         return NapiGetUndefined(env);
211     }
212 
213     auto weakScene = windowScene_.lock();
214     if (weakScene == nullptr || weakScene->GetMainWindow() == nullptr) {
215         WLOGFE("[NAPI]WindowScene is null or window is null");
216         return NapiGetUndefined(env);
217     }
218     weakScene->GetMainWindow()->NapiSetUIContent(contextUrl, env, argv[CONTENT_STORAGE_ARG]);
219     return NapiGetUndefined(env);
220 }
221 
OnGetMainWindow(napi_env env,napi_callback_info info)222 napi_value JsWindowStage::OnGetMainWindow(napi_env env, napi_callback_info info)
223 {
224     NapiAsyncTask::CompleteCallback complete =
225         [weak = windowScene_](napi_env env, NapiAsyncTask& task, int32_t status) {
226             auto weakScene = weak.lock();
227             if (weakScene == nullptr) {
228                 task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STAGE_ABNORMALLY));
229                 WLOGFE("[NAPI]WindowScene_ is nullptr!");
230                 return;
231             }
232             auto window = weakScene->GetMainWindow();
233             if (window != nullptr) {
234                 task.Resolve(env, OHOS::Rosen::CreateJsWindowObject(env, window));
235                 WLOGI("[NAPI]Get main window [%{public}u, %{public}s]",
236                     window->GetWindowId(), window->GetWindowName().c_str());
237             } else {
238                 task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY,
239                     "Get main window failed."));
240             }
241         };
242     size_t argc = 4;
243     napi_value argv[4] = {nullptr};
244     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
245     napi_value callback = (argv[0] != nullptr && GetType(env, argv[0]) == napi_function) ?
246         argv[0] : nullptr;
247     napi_value result = nullptr;
248     NapiAsyncTask::Schedule("JsWindowStage::OnGetMainWindow",
249         env, CreateAsyncTaskWithLastParam(env, callback, nullptr, std::move(complete), &result));
250     return result;
251 }
252 
OnGetMainWindowSync(napi_env env,napi_callback_info info)253 napi_value JsWindowStage::OnGetMainWindowSync(napi_env env, napi_callback_info info)
254 {
255     auto weakScene = windowScene_.lock();
256     if (weakScene == nullptr) {
257         WLOGFE("[NAPI]WindowScene is null");
258         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STAGE_ABNORMALLY));
259         return NapiGetUndefined(env);
260     }
261     auto window = weakScene->GetMainWindow();
262     if (window == nullptr) {
263         WLOGFE("[NAPI]window is null");
264         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
265         return NapiGetUndefined(env);
266     }
267 
268     return OHOS::Rosen::CreateJsWindowObject(env, window);
269 }
270 
OnEvent(napi_env env,napi_callback_info info)271 napi_value JsWindowStage::OnEvent(napi_env env, napi_callback_info info)
272 {
273     auto weakScene = windowScene_.lock();
274     if (weakScene == nullptr) {
275         WLOGFE("[NAPI]Window scene is null");
276         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
277         return NapiGetUndefined(env);
278     }
279     size_t argc = 4;
280     napi_value argv[4] = {nullptr};
281     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
282     if (argc < 2) { // 2: minimum param nums
283         WLOGFE("[NAPI]argc is invalid: %{public}zu", argc);
284         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
285         return NapiGetUndefined(env);
286     }
287 
288     // Parse argv[0] as string
289     std::string eventString;
290     if (!ConvertFromJsValue(env, argv[0], eventString)) {
291         WLOGFE("[NAPI]Failed to convert parameter to string");
292         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
293         return NapiGetUndefined(env);
294     }
295     napi_value value = argv[1];
296     if (!NapiIsCallable(env, value)) {
297         WLOGFE("[NAPI]Callback(argv[1]) is not callable");
298         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
299         return NapiGetUndefined(env);
300     }
301 
302     auto window = weakScene->GetMainWindow();
303     if (window == nullptr) {
304         WLOGFE("[NAPI]Get window failed");
305         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
306         return NapiGetUndefined(env);
307     }
308     auto ret = g_listenerManager->RegisterListener(window, eventString, CaseType::CASE_STAGE, env, value);
309     if (ret != WmErrorCode::WM_OK) {
310         TLOGE(WmsLogTag::DEFAULT, "register event %{public}s failed, ret = %{public}d", eventString.c_str(), ret);
311         napi_throw(env, JsErrUtils::CreateJsError(env, ret));
312         return NapiGetUndefined(env);
313     }
314     WLOGI("[NAPI]Window [%{public}u, %{public}s] register event %{public}s",
315         window->GetWindowId(), window->GetWindowName().c_str(), eventString.c_str());
316 
317     return NapiGetUndefined(env);
318 }
319 
OffEvent(napi_env env,napi_callback_info info)320 napi_value JsWindowStage::OffEvent(napi_env env, napi_callback_info info)
321 {
322     auto weakScene = windowScene_.lock();
323     if (weakScene == nullptr) {
324         WLOGFE("[NAPI]Window scene is null");
325         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
326         return NapiGetUndefined(env);
327     }
328     size_t argc = 4;
329     napi_value argv[4] = {nullptr};
330     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
331     // Parse argv[0] as string
332     std::string eventString;
333     if (!ConvertFromJsValue(env, argv[0], eventString)) {
334         WLOGFE("[NAPI]Failed to convert parameter to string");
335         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
336         return NapiGetUndefined(env);
337     }
338 
339     auto window = weakScene->GetMainWindow();
340     if (window == nullptr) {
341         WLOGFE("[NAPI]Get window failed");
342         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
343         return NapiGetUndefined(env);
344     }
345     napi_value value = nullptr;
346     WmErrorCode ret = WmErrorCode::WM_OK;
347     if (argc == 1) {
348         ret = g_listenerManager->UnregisterListener(window, eventString, CaseType::CASE_STAGE, env, nullptr);
349     } else {
350         value = argv[1];
351         if (value != nullptr && GetType(env, value) == napi_function) {
352             ret = g_listenerManager->UnregisterListener(window, eventString, CaseType::CASE_STAGE, env, value);
353         } else {
354             ret = g_listenerManager->UnregisterListener(window, eventString, CaseType::CASE_STAGE, env, nullptr);
355         }
356     }
357     if (ret != WmErrorCode::WM_OK) {
358         TLOGE(WmsLogTag::DEFAULT, "unregister event %{public}s failed, ret = %{public}d", eventString.c_str(), ret);
359         napi_throw(env, JsErrUtils::CreateJsError(env, ret));
360         return NapiGetUndefined(env);
361     }
362     WLOGI("[NAPI]Window [%{public}u, %{public}s] unregister event %{public}s",
363         window->GetWindowId(), window->GetWindowName().c_str(), eventString.c_str());
364 
365     return NapiGetUndefined(env);
366 }
367 
LoadContentTask(std::shared_ptr<NativeReference> contentStorage,std::string contextUrl,sptr<Window> weakWindow,napi_env env,NapiAsyncTask & task,bool isLoadedByName)368 static void LoadContentTask(std::shared_ptr<NativeReference> contentStorage, std::string contextUrl,
369     sptr<Window> weakWindow, napi_env env, NapiAsyncTask& task, bool isLoadedByName)
370 {
371     napi_value nativeStorage = (contentStorage == nullptr) ? nullptr : contentStorage->GetNapiValue();
372     WMError ret;
373     if (isLoadedByName) {
374         ret = weakWindow->SetUIContentByName(contextUrl, env, nativeStorage);
375     } else {
376         ret = weakWindow->NapiSetUIContent(contextUrl, env, nativeStorage);
377     }
378     if (ret == WMError::WM_OK) {
379         task.Resolve(env, NapiGetUndefined(env));
380     } else {
381         task.Reject(env, JsErrUtils::CreateJsError(env, WM_JS_TO_ERROR_CODE_MAP.at(ret),
382             "Window load content failed"));
383     }
384     WLOGI("[NAPI]Window [%{public}u, %{public}s] load content end, ret = %{public}d",
385         weakWindow->GetWindowId(), weakWindow->GetWindowName().c_str(), ret);
386     return;
387 }
388 
OnLoadContent(napi_env env,napi_callback_info info,bool isLoadedByName)389 napi_value JsWindowStage::OnLoadContent(napi_env env, napi_callback_info info, bool isLoadedByName)
390 {
391     WmErrorCode errCode = WmErrorCode::WM_OK;
392     std::string contextUrl;
393     size_t argc = 4;
394     napi_value argv[4] = {nullptr};
395     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
396     if (!ConvertFromJsValue(env, argv[0], contextUrl)) {
397         WLOGFE("[NAPI]Failed to convert parameter to context url");
398         errCode = WmErrorCode::WM_ERROR_INVALID_PARAM;
399     }
400     napi_value storage = nullptr;
401     napi_value callBack = nullptr;
402     napi_value value1 = argv[1];
403     napi_value value2 = argv[2]; // 2: param index
404     if (GetType(env, value1) == napi_function) {
405         callBack = value1;
406     } else if (GetType(env, value1) == napi_object) {
407         storage = value1;
408     }
409     if (GetType(env, value2) == napi_function) {
410         callBack = value2;
411     }
412     if (errCode == WmErrorCode::WM_ERROR_INVALID_PARAM) {
413         WLOGFE("[NAPI]Window scene is null or get invalid param");
414         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
415         return NapiGetUndefined(env);
416     }
417 
418     std::shared_ptr<NativeReference> contentStorage = nullptr;
419     if (storage != nullptr) {
420         napi_ref result = nullptr;
421         napi_create_reference(env, storage, 1, &result);
422         contentStorage = std::shared_ptr<NativeReference>(reinterpret_cast<NativeReference*>(result));
423     }
424 
425     NapiAsyncTask::CompleteCallback complete =
426         [weak = windowScene_, contentStorage, contextUrl, isLoadedByName](
427             napi_env env, NapiAsyncTask& task, int32_t status) {
428             auto weakScene = weak.lock();
429             sptr<Window> win = weakScene ? weakScene->GetMainWindow() : nullptr;
430             if (win == nullptr) {
431                 task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
432                 WLOGFE("[NAPI]Get window failed");
433                 return;
434             }
435             LoadContentTask(contentStorage, contextUrl, win, env, task, isLoadedByName);
436         };
437     napi_value result = nullptr;
438     NapiAsyncTask::Schedule("JsWindowStage::OnLoadContent",
439         env, CreateAsyncTaskWithLastParam(env, callBack, nullptr, std::move(complete), &result));
440     return result;
441 }
442 
OnGetWindowMode(napi_env env,napi_callback_info info)443 napi_value JsWindowStage::OnGetWindowMode(napi_env env, napi_callback_info info)
444 {
445     NapiAsyncTask::CompleteCallback complete =
446         [weak = windowScene_](napi_env env, NapiAsyncTask& task, int32_t status) {
447             auto weakScene = weak.lock();
448             if (weakScene == nullptr) {
449                 task.Reject(env, JsErrUtils::CreateJsError(env, WMError::WM_ERROR_NULLPTR));
450                 WLOGFE("[NAPI]windowScene_ is nullptr");
451                 return;
452             }
453             auto window = weakScene->GetMainWindow();
454             if (window == nullptr) {
455                 task.Reject(env, JsErrUtils::CreateJsError(env, WMError::WM_ERROR_NULLPTR, "Get window failed"));
456                 WLOGFE("[NAPI]Get window failed");
457                 return;
458             }
459             Rosen::WindowMode mode = window->GetMode();
460             if (NATIVE_TO_JS_WINDOW_MODE_MAP.count(mode) != 0) {
461                 task.Resolve(env, CreateJsValue(env, NATIVE_TO_JS_WINDOW_MODE_MAP.at(mode)));
462                 WLOGI("[NAPI]Window [%{public}u, %{public}s] get mode %{public}u, api mode %{public}u",
463                     window->GetWindowId(), window->GetWindowName().c_str(),
464                     mode, NATIVE_TO_JS_WINDOW_MODE_MAP.at(mode));
465             } else {
466                 task.Resolve(env, CreateJsValue(env, mode));
467                 WLOGFE("[NAPI]Get mode %{public}u, but not in apimode", mode);
468             }
469         };
470 
471     size_t argc = 4;
472     napi_value argv[4] = {nullptr};
473     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
474     napi_value callback = (GetType(env, argv[0]) == napi_function) ? argv[0] : nullptr;
475     napi_value result = nullptr;
476     NapiAsyncTask::Schedule("JsWindowStage::OnGetWindowMode",
477         env, CreateAsyncTaskWithLastParam(env, callback, nullptr, std::move(complete), &result));
478     return result;
479 }
480 
OnCreateSubWindow(napi_env env,napi_callback_info info)481 napi_value JsWindowStage::OnCreateSubWindow(napi_env env, napi_callback_info info)
482 {
483     WmErrorCode errCode = WmErrorCode::WM_OK;
484     std::string windowName;
485     size_t argc = 4;
486     napi_value argv[4] = {nullptr};
487     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
488     if (!ConvertFromJsValue(env, argv[0], windowName)) {
489         WLOGFE("[NAPI]Failed to convert parameter to windowName");
490         errCode = WmErrorCode::WM_ERROR_INVALID_PARAM;
491     }
492     if (errCode == WmErrorCode::WM_ERROR_INVALID_PARAM) {
493         WLOGFE("[NAPI]get invalid param");
494         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
495         return NapiGetUndefined(env);
496     }
497     NapiAsyncTask::CompleteCallback complete =
498         [weak = windowScene_, windowName](napi_env env, NapiAsyncTask& task, int32_t status) {
499             auto weakScene = weak.lock();
500             if (weakScene == nullptr) {
501                 WLOGFE("[NAPI]Window scene is null");
502                 task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
503                 return;
504             }
505             sptr<Rosen::WindowOption> windowOption = new Rosen::WindowOption();
506             windowOption->SetWindowType(Rosen::WindowType::WINDOW_TYPE_APP_SUB_WINDOW);
507             windowOption->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_FLOATING);
508             auto window = weakScene->CreateWindow(windowName, windowOption);
509             if (window == nullptr) {
510                 WLOGFE("[NAPI]Get window failed");
511                 task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY,
512                     "Get window failed"));
513                 return;
514             }
515             task.Resolve(env, CreateJsWindowObject(env, window));
516             WLOGI("[NAPI]Create sub window %{public}s end", windowName.c_str());
517         };
518     napi_value callback = (argv[1] != nullptr && GetType(env, argv[1]) == napi_function) ? argv[1] : nullptr;
519     napi_value result = nullptr;
520     NapiAsyncTask::Schedule("JsWindowStage::OnCreateSubWindow",
521         env, CreateAsyncTaskWithLastParam(env, callback, nullptr, std::move(complete), &result));
522     return result;
523 }
524 
CreateJsSubWindowArrayObject(napi_env env,std::vector<sptr<Window>> subWinVec)525 static napi_value CreateJsSubWindowArrayObject(napi_env env,
526     std::vector<sptr<Window>> subWinVec)
527 {
528     napi_value arrayValue = nullptr;
529     napi_create_array_with_length(env, subWinVec.size(), &arrayValue);
530     if (arrayValue == nullptr) {
531         WLOGFE("[NAPI]Failed to convert subWinVec to jsArrayObject");
532         return nullptr;
533     }
534     uint32_t index = 0;
535     for (size_t i = 0; i < subWinVec.size(); i++) {
536         napi_set_element(env, arrayValue, index++, CreateJsWindowObject(env, subWinVec[i]));
537     }
538     return arrayValue;
539 }
540 
OnGetSubWindow(napi_env env,napi_callback_info info)541 napi_value JsWindowStage::OnGetSubWindow(napi_env env, napi_callback_info info)
542 {
543     NapiAsyncTask::CompleteCallback complete =
544         [weak = windowScene_](napi_env env, NapiAsyncTask& task, int32_t status) {
545             auto weakScene = weak.lock();
546             if (weakScene == nullptr) {
547                 WLOGFE("[NAPI]Window scene is nullptr");
548                 task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
549                 return;
550             }
551             std::vector<sptr<Window>> subWindowVec = weakScene->GetSubWindow();
552             task.Resolve(env, CreateJsSubWindowArrayObject(env, subWindowVec));
553             WLOGI("[NAPI]Get sub windows, size = %{public}zu", subWindowVec.size());
554         };
555     size_t argc = 4;
556     napi_value argv[4] = {nullptr};
557     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
558     napi_value callback = (argv[0] != nullptr && GetType(env, argv[0]) == napi_function) ? argv[0] : nullptr;
559     napi_value result = nullptr;
560     NapiAsyncTask::Schedule("JsWindowStage::OnGetSubWindow",
561         env, CreateAsyncTaskWithLastParam(env, callback, nullptr, std::move(complete), &result));
562     return result;
563 }
564 
OnSetWindowModal(napi_env env,napi_callback_info info)565 napi_value JsWindowStage::OnSetWindowModal(napi_env env, napi_callback_info info)
566 {
567     auto windowScene = windowScene_.lock();
568     if (windowScene == nullptr) {
569         TLOGE(WmsLogTag::WMS_MAIN, "WindowScene is null");
570         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STAGE_ABNORMALLY));
571         return NapiGetUndefined(env);
572     }
573     auto window = windowScene->GetMainWindow();
574     if (window == nullptr) {
575         TLOGE(WmsLogTag::WMS_MAIN, "window is nullptr");
576         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STAGE_ABNORMALLY));
577         return NapiGetUndefined(env);
578     }
579     if (!window->IsPcOrPadFreeMultiWindowMode()) {
580         TLOGE(WmsLogTag::WMS_MAIN, "device not support");
581         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT));
582         return NapiGetUndefined(env);
583     }
584     size_t argc = FOUR_PARAMS_SIZE;
585     napi_value argv[FOUR_PARAMS_SIZE] = { nullptr };
586     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
587     if (argc != 1) {
588         TLOGE(WmsLogTag::WMS_MAIN, "Argc is invalid: %{public}zu", argc);
589         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
590         return NapiGetUndefined(env);
591     }
592     bool isModal = false;
593     if (!ConvertFromJsValue(env, argv[INDEX_ZERO], isModal)) {
594         TLOGE(WmsLogTag::WMS_MAIN, "Failed to convert parameter to bool");
595         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
596         return NapiGetUndefined(env);
597     }
598     napi_value result = nullptr;
599     std::shared_ptr<NapiAsyncTask> napiAsyncTask = CreateEmptyAsyncTask(env, nullptr, &result);
600     const char* const where = __func__;
601     auto asyncTask = [where, weakWindow = wptr(window), isModal, env, task = napiAsyncTask] {
602         auto window = weakWindow.promote();
603         if (window == nullptr) {
604             TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s failed, window is null", where);
605             task->Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
606             return;
607         }
608         WMError ret = window->SetWindowModal(isModal);
609         if (ret != WMError::WM_OK) {
610             WmErrorCode wmErrorCode = WM_JS_TO_ERROR_CODE_MAP.at(ret);
611             TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s failed, ret is %{public}d", where, wmErrorCode);
612             task->Reject(env, JsErrUtils::CreateJsError(env, wmErrorCode, "Set main window modal failed"));
613             return;
614         }
615         task->Resolve(env, NapiGetUndefined(env));
616         TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s id:%{public}u, name:%{public}s, isModal:%{public}d",
617             where, window->GetWindowId(), window->GetWindowName().c_str(), isModal);
618     };
619     if (napi_status::napi_ok != napi_send_event(env, asyncTask, napi_eprio_high)) {
620         napiAsyncTask->Reject(env,
621             CreateJsError(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY), "send event failed"));
622     }
623     return result;
624 }
625 
OnSetShowOnLockScreen(napi_env env,napi_callback_info info)626 napi_value JsWindowStage::OnSetShowOnLockScreen(napi_env env, napi_callback_info info)
627 {
628     if (!Permission::IsSystemCalling() && !Permission::IsStartByHdcd()) {
629         WLOGFE("set show on lock screen permission denied!");
630         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_NOT_SYSTEM_APP));
631         return CreateJsValue(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_NOT_SYSTEM_APP));
632     }
633 
634     size_t argc = 4;
635     napi_value argv[4] = {nullptr};
636     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
637     if (argc < 1) {
638         WLOGFE("[NAPI]Argc is invalid: %{public}zu", argc);
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     }
642     auto weakScene = windowScene_.lock();
643     if (weakScene == nullptr || weakScene->GetMainWindow() == nullptr) {
644         WLOGFE("[NAPI]WindowScene is null or window is null");
645         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
646         return CreateJsValue(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
647     }
648 
649     bool showOnLockScreen = false;
650     napi_value nativeVal = argv[0];
651     if (nativeVal == nullptr) {
652         WLOGFE("[NAPI]Failed to convert parameter to boolean");
653         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
654         return CreateJsValue(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_INVALID_PARAM));
655     } else {
656         napi_get_value_bool(env, nativeVal, &showOnLockScreen);
657     }
658 
659     auto window = weakScene->GetMainWindow();
660     WmErrorCode ret;
661     if (showOnLockScreen) {
662         ret = WM_JS_TO_ERROR_CODE_MAP.at(
663             window->AddWindowFlag(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED));
664     } else {
665         ret = WM_JS_TO_ERROR_CODE_MAP.at(
666             window->RemoveWindowFlag(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED));
667     }
668     WLOGI("[NAPI]Window [%{public}u, %{public}s] SetShowOnLockScreen %{public}u, ret = %{public}u",
669         window->GetWindowId(), window->GetWindowName().c_str(), showOnLockScreen, ret);
670 
671     return CreateJsValue(env, static_cast<int32_t>(ret));
672 }
673 
OnDisableWindowDecor(napi_env env,napi_callback_info info)674 napi_value JsWindowStage::OnDisableWindowDecor(napi_env env, napi_callback_info info)
675 {
676     auto weakScene = windowScene_.lock();
677     if (weakScene == nullptr) {
678         WLOGFE("[NAPI]WindowScene is null");
679         return CreateJsValue(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_STAGE_ABNORMALLY));
680     }
681 
682     auto window = weakScene->GetMainWindow();
683     if (window == nullptr) {
684         WLOGFE("[NAPI]Window is null");
685         return CreateJsValue(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
686     }
687     WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(window->DisableAppWindowDecor());
688     if (ret != WmErrorCode::WM_OK) {
689         napi_throw(env, JsErrUtils::CreateJsError(env, ret));
690     WLOGI("[NAPI]Window [%{public}u, %{public}s] disable app window decor end",
691         window->GetWindowId(), window->GetWindowName().c_str());
692         return NapiGetUndefined(env);
693     }
694     return NapiGetUndefined(env);
695 }
696 
OnSetDefaultDensityEnabled(napi_env env,napi_callback_info info)697 napi_value JsWindowStage::OnSetDefaultDensityEnabled(napi_env env, napi_callback_info info)
698 {
699     size_t argc = 4;
700     napi_value argv[4] = {nullptr};
701     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
702     if (argc != 1) {
703         TLOGE(WmsLogTag::WMS_LAYOUT, "Argc is invalid: %{public}zu", argc);
704         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
705         return CreateJsValue(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_INVALID_PARAM));
706     }
707 
708     auto weakScene = windowScene_.lock();
709     if (weakScene == nullptr) {
710         TLOGE(WmsLogTag::WMS_LAYOUT, "WindowScene is null");
711         return CreateJsValue(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_STAGE_ABNORMALLY));
712     }
713 
714     auto window = weakScene->GetMainWindow();
715     if (window == nullptr) {
716         TLOGE(WmsLogTag::WMS_LAYOUT, "Window is null");
717         return CreateJsValue(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
718     }
719 
720     bool enabled = false;
721     if (!ConvertFromJsValue(env, argv[0], enabled)) {
722         TLOGE(WmsLogTag::WMS_LAYOUT, "Failed to convert parameter to boolean");
723         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
724         return CreateJsValue(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_INVALID_PARAM));
725     }
726 
727     WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(window->SetDefaultDensityEnabled(enabled));
728     TLOGI(WmsLogTag::WMS_LAYOUT, "Window [%{public}u,%{public}s] SetDefaultDensityEnabled=%{public}u ret=%{public}u",
729         window->GetWindowId(), window->GetWindowName().c_str(), enabled, ret);
730 
731     return CreateJsValue(env, static_cast<int32_t>(ret));
732 }
733 
OnSetCustomDensity(napi_env env,napi_callback_info info)734 napi_value JsWindowStage::OnSetCustomDensity(napi_env env, napi_callback_info info)
735 {
736     size_t argc = FOUR_PARAMS_SIZE;
737     napi_value argv[FOUR_PARAMS_SIZE] = { nullptr };
738     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
739     if (argc != 1) {
740         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "Argc is invalid: %{public}zu", argc);
741         return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
742     }
743 
744     double density = UNDEFINED_DENSITY;
745     if (!ConvertFromJsValue(env, argv[0], density)) {
746         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "Failed to convert parameter to double");
747         return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
748     }
749 
750     auto windowScene = windowScene_.lock();
751     if (windowScene == nullptr) {
752         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "windowScene is null");
753         return NapiThrowError(env, WmErrorCode::WM_ERROR_STAGE_ABNORMALLY);
754     }
755     auto window = windowScene->GetMainWindow();
756     if (window == nullptr) {
757         TLOGE(WmsLogTag::WMS_ATTRIBUTE, "Window is null");
758         return NapiThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY);
759     }
760 
761     WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(window->SetCustomDensity(density));
762     TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Window [%{public}u,%{public}s] set density=%{public}f, result=%{public}u",
763         window->GetWindowId(), window->GetWindowName().c_str(), density, ret);
764     if (ret != WmErrorCode::WM_OK) {
765         return NapiThrowError(env, ret);
766     }
767     return NapiGetUndefined(env);
768 }
769 
OnCreateSubWindowWithOptions(napi_env env,napi_callback_info info)770 napi_value JsWindowStage::OnCreateSubWindowWithOptions(napi_env env, napi_callback_info info)
771 {
772     auto windowScene = windowScene_.lock();
773     if (windowScene == nullptr) {
774         TLOGE(WmsLogTag::WMS_SUB, "WindowScene is null");
775         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STAGE_ABNORMALLY));
776         return NapiGetUndefined(env);
777     }
778     size_t argc = 4;
779     napi_value argv[4] = {nullptr};
780     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
781     std::string windowName;
782     if (!ConvertFromJsValue(env, argv[0], windowName)) {
783         WLOGFE("[NAPI]Failed to convert parameter to windowName");
784         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
785         return NapiGetUndefined(env);
786     }
787     sptr<WindowOption> option = new WindowOption();
788     if (!ParseSubWindowOptions(env, argv[1], option)) {
789         WLOGFE("[NAPI]get invalid options param");
790         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
791         return NapiGetUndefined(env);
792     }
793     if ((option->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_APPLICATION_MODAL)) &&
794         !windowScene->GetMainWindow()->IsPcOrPadFreeMultiWindowMode()) {
795         TLOGE(WmsLogTag::WMS_SUB, "device not support");
796         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT));
797         return NapiGetUndefined(env);
798     }
799 
800     if (option->GetWindowTopmost() && !Permission::IsSystemCalling() && !Permission::IsStartByHdcd()) {
801         TLOGE(WmsLogTag::WMS_SUB, "Modal subwindow has topmost, but no system permission");
802         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_NOT_SYSTEM_APP));
803         return NapiGetUndefined(env);
804     }
805 
806     const char* const where = __func__;
807     NapiAsyncTask::CompleteCallback complete =
808         [where, windowScene, windowName = std::move(windowName), option]
809             (napi_env env, NapiAsyncTask& task, int32_t status) mutable {
810         option->SetWindowType(WindowType::WINDOW_TYPE_APP_SUB_WINDOW);
811         option->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
812         option->SetOnlySupportSceneBoard(true);
813         auto window = windowScene->CreateWindow(windowName, option);
814         if (window == nullptr) {
815             TLOGNE(WmsLogTag::WMS_SUB, "%{public}s [NAPI]Get window failed", where);
816             task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY,
817                 "Get window failed"));
818             return;
819         }
820         task.Resolve(env, CreateJsWindowObject(env, window));
821         TLOGNI(WmsLogTag::WMS_SUB, "%{public}s [NAPI]Create sub window %{public}s end",
822             where, windowName.c_str());
823     };
824     napi_value callback = (argv[2] != nullptr && GetType(env, argv[2]) == napi_function) ? argv[2] : nullptr;
825     napi_value result = nullptr;
826     NapiAsyncTask::Schedule("JsWindowStage::OnCreateSubWindowWithOptions",
827         env, CreateAsyncTaskWithLastParam(env, callback, nullptr, std::move(complete), &result));
828     return result;
829 }
830 
OnRemoveStartingWindow(napi_env env,napi_callback_info info)831 napi_value JsWindowStage::OnRemoveStartingWindow(napi_env env, napi_callback_info info)
832 {
833     auto windowScene = windowScene_.lock();
834     if (windowScene == nullptr) {
835         TLOGE(WmsLogTag::WMS_MAIN, "windowScene is null");
836         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
837         return NapiGetUndefined(env);
838     }
839 
840     const char* const where = __func__;
841     NapiAsyncTask::CompleteCallback complete =
842         [where, windowScene](napi_env env, NapiAsyncTask& task, int32_t status) {
843         auto window = windowScene->GetMainWindow();
844         if (window == nullptr) {
845             TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s [NAPI]Get main window failed", where);
846             task.Reject(env,
847                 JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY, "Get main window failed"));
848             return;
849         }
850         WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(window->NotifyRemoveStartingWindow());
851         if (ret == WmErrorCode::WM_OK) {
852             task.Resolve(env, NapiGetUndefined(env));
853         } else {
854             task.Reject(env, JsErrUtils::CreateJsError(env, ret, "Notify remove starting window failed"));
855         }
856     };
857 
858     size_t argc = FOUR_PARAMS_SIZE;
859     napi_value argv[FOUR_PARAMS_SIZE] = {nullptr};
860     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
861     napi_value lastParam = (argc == 0) ? nullptr :
862         (argv[INDEX_ZERO] != nullptr && GetType(env, argv[INDEX_ZERO]) == napi_function ? argv[INDEX_ZERO] : nullptr);
863     napi_value result = nullptr;
864     NapiAsyncTask::Schedule("JsWindow::OnRemoveStartingWindow",
865         env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
866     return result;
867 }
868 
OnSetWindowRectAutoSave(napi_env env,napi_callback_info info)869 napi_value JsWindowStage::OnSetWindowRectAutoSave(napi_env env, napi_callback_info info)
870 {
871     auto windowScene = windowScene_.lock();
872     if (windowScene == nullptr) {
873         TLOGE(WmsLogTag::WMS_MAIN, "WindowScene is null");
874         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
875         return NapiGetUndefined(env);
876     }
877 
878     size_t argc = FOUR_PARAMS_SIZE;
879     napi_value argv[FOUR_PARAMS_SIZE] = { nullptr };
880     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
881     if (argc != 1) { // 1: maximum params num
882         TLOGE(WmsLogTag::WMS_MAIN, "Argc is invalid: %{public}zu", argc);
883         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
884         return NapiGetUndefined(env);
885     }
886     bool enabled = false;
887     if (!ConvertFromJsValue(env, argv[INDEX_ZERO], enabled)) {
888         TLOGE(WmsLogTag::WMS_MAIN, "[NAPI]Failed to convert parameter to enabled");
889         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
890         return NapiGetUndefined(env);
891     }
892 
893     auto window = windowScene->GetMainWindow();
894     const char* const where = __func__;
895     napi_value result = nullptr;
896     std::shared_ptr<NapiAsyncTask> napiAsyncTask = CreateEmptyAsyncTask(env, nullptr, &result);
897     auto asyncTask = [weakWindow = wptr(window), where, env, task = napiAsyncTask, enabled] {
898         auto window = weakWindow.promote();
899         if (window == nullptr) {
900             TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s window is nullptr", where);
901             WmErrorCode wmErroeCode = WM_JS_TO_ERROR_CODE_MAP.at(WMError::WM_ERROR_NULLPTR);
902             task->Reject(env, JsErrUtils::CreateJsError(env, wmErroeCode, "window is nullptr."));
903             return;
904         }
905         WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(window->SetWindowRectAutoSave(enabled));
906         if (ret != WmErrorCode::WM_OK) {
907             TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s enable recover position failed!", where);
908             task->Reject(env, JsErrUtils::CreateJsError(env,
909                 ret, "window recover position failed."));
910         } else {
911             task->Resolve(env, NapiGetUndefined(env));
912         }
913     };
914     if (napi_status::napi_ok != napi_send_event(env, asyncTask, napi_eprio_high)) {
915         napiAsyncTask->Reject(env,
916             CreateJsError(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY), "send event failed"));
917     }
918     return result;
919 }
920 
OnSetSupportedWindowModes(napi_env env,napi_callback_info info)921 napi_value JsWindowStage::OnSetSupportedWindowModes(napi_env env, napi_callback_info info)
922 {
923     auto windowScene = windowScene_.lock();
924     if (windowScene == nullptr) {
925         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "WindowScene is null");
926         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
927         return NapiGetUndefined(env);
928     }
929 
930     size_t argc = FOUR_PARAMS_SIZE;
931     napi_value argv[FOUR_PARAMS_SIZE] = { nullptr };
932     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
933     if (argc != 1) { // 1: maximum params num
934         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "Argc is invalid: %{public}zu", argc);
935         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
936         return NapiGetUndefined(env);
937     }
938 
939     if (GetType(env, argv[INDEX_ZERO]) != napi_object) {
940         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "GetType error");
941         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
942         return NapiGetUndefined(env);
943     }
944 
945     std::vector<AppExecFwk::SupportWindowMode> supportedWindowModes;
946     if (!ConvertNativeValueToVector(env, argv[INDEX_ZERO], supportedWindowModes)) {
947         TLOGE(WmsLogTag::WMS_LAYOUT_PC, "ConvertNativeValueToVector failed");
948         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
949         return NapiGetUndefined(env);
950     }
951 
952     auto window = windowScene->GetMainWindow();
953     const char* const where = __func__;
954     napi_value result = nullptr;
955     std::shared_ptr<NapiAsyncTask> napiAsyncTask = CreateEmptyAsyncTask(env, nullptr, &result);
956     auto asyncTask = [weakWindow = wptr(window), supportedWindowModes = std::move(supportedWindowModes), where,
957         env, task = napiAsyncTask] {
958         auto window = weakWindow.promote();
959         if (window == nullptr) {
960             TLOGNE(WmsLogTag::WMS_LAYOUT_PC, "%{public}s window is nullptr", where);
961             WmErrorCode wmErroeCode = WM_JS_TO_ERROR_CODE_MAP.at(WMError::WM_ERROR_NULLPTR);
962             task->Reject(env, JsErrUtils::CreateJsError(env, wmErroeCode, "window is nullptr."));
963             return;
964         }
965         WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(window->SetSupportedWindowModes(supportedWindowModes));
966         if (ret != WmErrorCode::WM_OK) {
967             TLOGNE(WmsLogTag::WMS_LAYOUT_PC, "window [%{public}u, %{public}s] "
968                 "set window support modes failed!", window->GetWindowId(),
969                 window->GetWindowName().c_str());
970             task->Reject(env, JsErrUtils::CreateJsError(env, ret, "set window support modes failed."));
971         } else {
972             TLOGNI(WmsLogTag::WMS_LAYOUT_PC, "window [%{public}u, %{public}s] "
973                 "set window support modes succeed.", window->GetWindowId(),
974                 window->GetWindowName().c_str());
975             task->Resolve(env, NapiGetUndefined(env));
976         }
977     };
978     if (napi_status::napi_ok != napi_send_event(env, std::move(asyncTask), napi_eprio_high)) {
979         napiAsyncTask->Reject(env,
980             CreateJsError(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY), "send event failed"));
981     }
982     return result;
983 }
984 
OnIsWindowRectAutoSave(napi_env env,napi_callback_info info)985 napi_value JsWindowStage::OnIsWindowRectAutoSave(napi_env env, napi_callback_info info)
986 {
987     auto windowScene = windowScene_.lock();
988     if (windowScene == nullptr) {
989         TLOGE(WmsLogTag::WMS_MAIN, "WindowScene is null");
990         napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
991         return NapiGetUndefined(env);
992     }
993 
994     auto window = windowScene->GetMainWindow();
995     const char* const where = __func__;
996     napi_value result = nullptr;
997     std::shared_ptr<NapiAsyncTask> napiAsyncTask = CreateEmptyAsyncTask(env, nullptr, &result);
998     auto asyncTask = [weakWindow = wptr(window), where, env, task = napiAsyncTask] {
999         auto window = weakWindow.promote();
1000         if (window == nullptr) {
1001             TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s Window is nullptr", where);
1002             task->Reject(env,
1003                 JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY, "Window is nullptr."));
1004             return;
1005         }
1006         bool enabled = false;
1007         WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(window->IsWindowRectAutoSave(enabled));
1008         if (ret != WmErrorCode::WM_OK) {
1009             TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s get the auto-save state of the window rect failed!", where);
1010             task->Reject(env, JsErrUtils::CreateJsError(env,
1011                 ret, "Window recover position failed."));
1012         } else {
1013             napi_value jsEnabled = CreateJsValue(env, enabled);
1014             task->Resolve(env, jsEnabled);
1015         }
1016     };
1017     if (napi_status::napi_ok != napi_send_event(env, asyncTask, napi_eprio_high)) {
1018         napiAsyncTask->Reject(env,
1019             CreateJsError(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY), "send event failed"));
1020     }
1021     return result;
1022 }
1023 
CreateJsWindowStage(napi_env env,std::shared_ptr<Rosen::WindowScene> windowScene)1024 napi_value CreateJsWindowStage(napi_env env, std::shared_ptr<Rosen::WindowScene> windowScene)
1025 {
1026     WLOGFD("[NAPI]CreateJsWindowStage");
1027     napi_value objValue = nullptr;
1028     napi_create_object(env, &objValue);
1029 
1030     std::unique_ptr<JsWindowStage> jsWindowStage = std::make_unique<JsWindowStage>(windowScene);
1031     napi_wrap(env, objValue, jsWindowStage.release(), JsWindowStage::Finalizer, nullptr, nullptr);
1032 
1033     const char* moduleName = "JsWindowStage";
1034     BindNativeFunction(env,
1035         objValue, "setUIContent", moduleName, JsWindowStage::SetUIContent);
1036     BindNativeFunction(env,
1037         objValue, "loadContent", moduleName, JsWindowStage::LoadContent);
1038     BindNativeFunction(env,
1039         objValue, "loadContentByName", moduleName, JsWindowStage::LoadContentByName);
1040     BindNativeFunction(env,
1041         objValue, "getMainWindow", moduleName, JsWindowStage::GetMainWindow);
1042     BindNativeFunction(env,
1043         objValue, "getMainWindowSync", moduleName, JsWindowStage::GetMainWindowSync);
1044     BindNativeFunction(env,
1045         objValue, "getWindowMode", moduleName, JsWindowStage::GetWindowMode);
1046     BindNativeFunction(env,
1047         objValue, "createSubWindow", moduleName, JsWindowStage::CreateSubWindow);
1048     BindNativeFunction(env,
1049         objValue, "createSubWindowWithOptions", moduleName, JsWindowStage::CreateSubWindowWithOptions);
1050     BindNativeFunction(env,
1051         objValue, "getSubWindow", moduleName, JsWindowStage::GetSubWindow);
1052     BindNativeFunction(env, objValue, "setWindowModal", moduleName, JsWindowStage::SetWindowModal);
1053     BindNativeFunction(env, objValue, "on", moduleName, JsWindowStage::On);
1054     BindNativeFunction(env, objValue, "off", moduleName, JsWindowStage::Off);
1055     BindNativeFunction(env,
1056         objValue, "setShowOnLockScreen", moduleName, JsWindowStage::SetShowOnLockScreen);
1057     BindNativeFunction(env,
1058         objValue, "disableWindowDecor", moduleName, JsWindowStage::DisableWindowDecor);
1059     BindNativeFunction(env,
1060         objValue, "setDefaultDensityEnabled", moduleName, JsWindowStage::SetDefaultDensityEnabled);
1061     BindNativeFunction(env,
1062         objValue, "setCustomDensity", moduleName, JsWindowStage::SetCustomDensity);
1063     BindNativeFunction(env,
1064         objValue, "removeStartingWindow", moduleName, JsWindowStage::RemoveStartingWindow);
1065     BindNativeFunction(env,
1066         objValue, "setWindowRectAutoSave", moduleName, JsWindowStage::SetWindowRectAutoSave);
1067     BindNativeFunction(env,
1068         objValue, "isWindowRectAutoSave", moduleName, JsWindowStage::IsWindowRectAutoSave);
1069     BindNativeFunction(env,
1070         objValue, "setSupportedWindowModes", moduleName, JsWindowStage::SetSupportedWindowModes);
1071     return objValue;
1072 }
1073 }  // namespace Rosen
1074 }  // namespace OHOS
1075