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