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_window_stage.h"
17 #include <string>
18 #include "js_runtime_utils.h"
19 #include "js_window.h"
20 #include "js_window_register_manager.h"
21 #include "js_window_utils.h"
22 #include "window_manager_hilog.h"
23 #include "permission.h"
24
25 namespace OHOS {
26 namespace Rosen {
27 using namespace AbilityRuntime;
28 namespace {
29 const int CONTENT_STORAGE_ARG = 2;
30 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "JsWindowStage"};
31 } // namespace
32
33 std::unique_ptr<JsWindowRegisterManager> g_listenerManager = std::make_unique<JsWindowRegisterManager>();
JsWindowStage(const std::shared_ptr<Rosen::WindowScene> & windowScene)34 JsWindowStage::JsWindowStage(const std::shared_ptr<Rosen::WindowScene>& windowScene)
35 : windowScene_(windowScene)
36 {
37 }
38
~JsWindowStage()39 JsWindowStage::~JsWindowStage()
40 {
41 }
42
Finalizer(NativeEngine * engine,void * data,void * hint)43 void JsWindowStage::Finalizer(NativeEngine* engine, void* data, void* hint)
44 {
45 WLOGI("[NAPI]Finalizer");
46 std::unique_ptr<JsWindowStage>(static_cast<JsWindowStage*>(data));
47 }
48
SetUIContent(NativeEngine * engine,NativeCallbackInfo * info)49 NativeValue* JsWindowStage::SetUIContent(NativeEngine* engine, NativeCallbackInfo* info)
50 {
51 WLOGFD("[NAPI]SetUIContent");
52 JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(engine, info);
53 return (me != nullptr) ? me->OnSetUIContent(*engine, *info) : nullptr;
54 }
55
GetMainWindow(NativeEngine * engine,NativeCallbackInfo * info)56 NativeValue* JsWindowStage::GetMainWindow(NativeEngine* engine, NativeCallbackInfo* info)
57 {
58 WLOGFD("[NAPI]GetMainWindow");
59 JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(engine, info);
60 return (me != nullptr) ? me->OnGetMainWindow(*engine, *info) : nullptr;
61 }
62
GetMainWindowSync(NativeEngine * engine,NativeCallbackInfo * info)63 NativeValue* JsWindowStage::GetMainWindowSync(NativeEngine* engine, NativeCallbackInfo* info)
64 {
65 WLOGFD("[NAPI]GetMainWindowSync");
66 JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(engine, info);
67 return (me != nullptr) ? me->OnGetMainWindowSync(*engine, *info) : nullptr;
68 }
69
On(NativeEngine * engine,NativeCallbackInfo * info)70 NativeValue* JsWindowStage::On(NativeEngine* engine, NativeCallbackInfo* info)
71 {
72 WLOGFD("[NAPI]On");
73 JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(engine, info);
74 return (me != nullptr) ? me->OnEvent(*engine, *info) : nullptr;
75 }
76
Off(NativeEngine * engine,NativeCallbackInfo * info)77 NativeValue* JsWindowStage::Off(NativeEngine* engine, NativeCallbackInfo* info)
78 {
79 WLOGFD("[NAPI]Off");
80 JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(engine, info);
81 return (me != nullptr) ? me->OffEvent(*engine, *info) : nullptr;
82 }
83
LoadContent(NativeEngine * engine,NativeCallbackInfo * info)84 NativeValue* JsWindowStage::LoadContent(NativeEngine* engine, NativeCallbackInfo* info)
85 {
86 WLOGFD("[NAPI]LoadContent");
87 JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(engine, info);
88 return (me != nullptr) ? me->OnLoadContent(*engine, *info) : nullptr;
89 }
90
GetWindowMode(NativeEngine * engine,NativeCallbackInfo * info)91 NativeValue* JsWindowStage::GetWindowMode(NativeEngine* engine, NativeCallbackInfo* info)
92 {
93 WLOGFD("[NAPI]GetWindowMode");
94 JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(engine, info);
95 return (me != nullptr) ? me->OnGetWindowMode(*engine, *info) : nullptr;
96 }
97
CreateSubWindow(NativeEngine * engine,NativeCallbackInfo * info)98 NativeValue* JsWindowStage::CreateSubWindow(NativeEngine* engine, NativeCallbackInfo* info)
99 {
100 WLOGFD("[NAPI]CreateSubWindow");
101 JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(engine, info);
102 return (me != nullptr) ? me->OnCreateSubWindow(*engine, *info) : nullptr;
103 }
104
GetSubWindow(NativeEngine * engine,NativeCallbackInfo * info)105 NativeValue* JsWindowStage::GetSubWindow(NativeEngine* engine, NativeCallbackInfo* info)
106 {
107 WLOGFD("[NAPI]GetSubWindow");
108 JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(engine, info);
109 return (me != nullptr) ? me->OnGetSubWindow(*engine, *info) : nullptr;
110 }
111
SetShowOnLockScreen(NativeEngine * engine,NativeCallbackInfo * info)112 NativeValue* JsWindowStage::SetShowOnLockScreen(NativeEngine* engine, NativeCallbackInfo* info)
113 {
114 WLOGFD("[NAPI]SetShowOnLockScreen");
115 JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(engine, info);
116 return (me != nullptr) ? me->OnSetShowOnLockScreen(*engine, *info) : nullptr;
117 }
118
DisableWindowDecor(NativeEngine * engine,NativeCallbackInfo * info)119 NativeValue* JsWindowStage::DisableWindowDecor(NativeEngine* engine, NativeCallbackInfo* info)
120 {
121 WLOGFD("[NAPI]DisableWindowDecor");
122 JsWindowStage* me = CheckParamsAndGetThis<JsWindowStage>(engine, info);
123 return (me != nullptr) ? me->OnDisableWindowDecor(*engine, *info) : nullptr;
124 }
125
OnSetUIContent(NativeEngine & engine,NativeCallbackInfo & info)126 NativeValue* JsWindowStage::OnSetUIContent(NativeEngine& engine, NativeCallbackInfo& info)
127 {
128 if (info.argc < 2) { // 2: minimum param num
129 WLOGFE("[NAPI]Argc is invalid: %{public}zu", info.argc);
130 return engine.CreateUndefined();
131 }
132
133 // Parse info->argv[0] as abilitycontext
134 auto objContext = ConvertNativeValueTo<NativeObject>(info.argv[0]);
135 if (objContext == nullptr) {
136 WLOGFE("[NAPI]Context is nullptr");
137 return engine.CreateUndefined();
138 }
139
140 // Parse info->argv[1] as url
141 std::string contextUrl;
142 if (!ConvertFromJsValue(engine, info.argv[1], contextUrl)) {
143 WLOGFE("[NAPI]Failed to convert parameter to url");
144 return engine.CreateUndefined();
145 }
146
147 auto weakScene = windowScene_.lock();
148 if (weakScene == nullptr || weakScene->GetMainWindow() == nullptr) {
149 WLOGFE("[NAPI]WindowScene is null or window is null");
150 return engine.CreateUndefined();
151 }
152 weakScene->GetMainWindow()->SetUIContent(contextUrl, &engine, info.argv[CONTENT_STORAGE_ARG]);
153 return engine.CreateUndefined();
154 }
155
OnGetMainWindow(NativeEngine & engine,NativeCallbackInfo & info)156 NativeValue* JsWindowStage::OnGetMainWindow(NativeEngine& engine, NativeCallbackInfo& info)
157 {
158 AsyncTask::CompleteCallback complete =
159 [weak = windowScene_](NativeEngine& engine, AsyncTask& task, int32_t status) {
160 auto weakScene = weak.lock();
161 if (weakScene == nullptr) {
162 task.Reject(engine, CreateJsError(engine,
163 static_cast<int32_t>(WmErrorCode::WM_ERROR_STAGE_ABNORMALLY)));
164 WLOGFE("[NAPI]WindowScene_ is nullptr!");
165 return;
166 }
167 auto window = weakScene->GetMainWindow();
168 if (window != nullptr) {
169 task.Resolve(engine, OHOS::Rosen::CreateJsWindowObject(engine, window));
170 WLOGI("[NAPI]Get main window [%{public}u, %{public}s]",
171 window->GetWindowId(), window->GetWindowName().c_str());
172 } else {
173 task.Reject(engine, CreateJsError(engine,
174 static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY),
175 "Get main window failed."));
176 }
177 };
178 NativeValue* callback = (info.argv[0] != nullptr && info.argv[0]->TypeOf() == NATIVE_FUNCTION) ?
179 info.argv[0] : nullptr;
180 NativeValue* result = nullptr;
181 AsyncTask::Schedule("JsWindowStage::OnGetMainWindow",
182 engine, CreateAsyncTaskWithLastParam(engine, callback, nullptr, std::move(complete), &result));
183 return result;
184 }
185
OnGetMainWindowSync(NativeEngine & engine,NativeCallbackInfo & info)186 NativeValue* JsWindowStage::OnGetMainWindowSync(NativeEngine& engine, NativeCallbackInfo& info)
187 {
188 auto weakScene = windowScene_.lock();
189 if (weakScene == nullptr) {
190 WLOGFE("[NAPI]WindowScene is null");
191 engine.Throw(CreateJsError(engine, static_cast<int32_t>(WmErrorCode::WM_ERROR_STAGE_ABNORMALLY)));
192 return engine.CreateUndefined();
193 }
194 auto window = weakScene->GetMainWindow();
195 if (window == nullptr) {
196 WLOGFE("[NAPI]window is null");
197 engine.Throw(CreateJsError(engine, static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY)));
198 return engine.CreateUndefined();
199 }
200
201 return OHOS::Rosen::CreateJsWindowObject(engine, window);
202 }
203
204
OnEvent(NativeEngine & engine,NativeCallbackInfo & info)205 NativeValue* JsWindowStage::OnEvent(NativeEngine& engine, NativeCallbackInfo& info)
206 {
207 auto weakScene = windowScene_.lock();
208 if (weakScene == nullptr) {
209 WLOGFE("[NAPI]Window scene is null");
210 engine.Throw(CreateJsError(engine, static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY)));
211 return engine.CreateUndefined();
212 }
213 if (info.argc < 2) { // 2: minimum param nums
214 WLOGFE("[NAPI]argc is invalid: %{public}zu", info.argc);
215 engine.Throw(CreateJsError(engine, static_cast<int32_t>(WmErrorCode::WM_ERROR_INVALID_PARAM)));
216 return engine.CreateUndefined();
217 }
218
219 // Parse info->argv[0] as string
220 std::string eventString;
221 if (!ConvertFromJsValue(engine, info.argv[0], eventString)) {
222 WLOGFE("[NAPI]Failed to convert parameter to string");
223 engine.Throw(CreateJsError(engine, static_cast<int32_t>(WmErrorCode::WM_ERROR_INVALID_PARAM)));
224 return engine.CreateUndefined();
225 }
226 NativeValue* value = info.argv[1];
227 if (!value->IsCallable()) {
228 WLOGFE("[NAPI]Callback(info->argv[1]) is not callable");
229 engine.Throw(CreateJsError(engine, static_cast<int32_t>(WmErrorCode::WM_ERROR_INVALID_PARAM)));
230 return engine.CreateUndefined();
231 }
232
233 auto window = weakScene->GetMainWindow();
234 if (window == nullptr) {
235 WLOGFE("[NAPI]Get window failed");
236 engine.Throw(CreateJsError(engine, static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY)));
237 return engine.CreateUndefined();
238 }
239 g_listenerManager->RegisterListener(window, eventString, CaseType::CASE_STAGE, engine, value);
240 WLOGI("[NAPI]Window [%{public}u, %{public}s] register event %{public}s",
241 window->GetWindowId(), window->GetWindowName().c_str(), eventString.c_str());
242
243 return engine.CreateUndefined();
244 }
245
OffEvent(NativeEngine & engine,NativeCallbackInfo & info)246 NativeValue* JsWindowStage::OffEvent(NativeEngine& engine, NativeCallbackInfo& info)
247 {
248 auto weakScene = windowScene_.lock();
249 if (weakScene == nullptr) {
250 WLOGFE("[NAPI]Window scene is null");
251 engine.Throw(CreateJsError(engine, static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY)));
252 return engine.CreateUndefined();
253 }
254
255 // Parse info->argv[0] as string
256 std::string eventString;
257 if (!ConvertFromJsValue(engine, info.argv[0], eventString)) {
258 WLOGFE("[NAPI]Failed to convert parameter to string");
259 engine.Throw(CreateJsError(engine, static_cast<int32_t>(WmErrorCode::WM_ERROR_INVALID_PARAM)));
260 return engine.CreateUndefined();
261 }
262 if (eventString.compare("windowStageEvent") != 0) {
263 WLOGFE("[NAPI]Envent %{public}s is invalid", eventString.c_str());
264 engine.Throw(CreateJsError(engine, static_cast<int32_t>(WmErrorCode::WM_ERROR_INVALID_PARAM)));
265 return engine.CreateUndefined();
266 }
267
268 auto window = weakScene->GetMainWindow();
269 if (window == nullptr) {
270 WLOGFE("[NAPI]Get window failed");
271 engine.Throw(CreateJsError(engine, static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY)));
272 return engine.CreateUndefined();
273 }
274 NativeValue* value = nullptr;
275 if (info.argv[1] == nullptr || info.argv[1]->TypeOf() != NATIVE_FUNCTION) {
276 g_listenerManager->UnregisterListener(window, eventString, CaseType::CASE_STAGE, nullptr);
277 } else {
278 g_listenerManager->UnregisterListener(window, eventString, CaseType::CASE_STAGE, info.argv[1]);
279 }
280
281 if (info.argc == 1) {
282 g_listenerManager->UnregisterListener(window, eventString, CaseType::CASE_STAGE, nullptr);
283 } else {
284 value = info.argv[1];
285 if (value != nullptr && value->TypeOf() == NATIVE_FUNCTION) {
286 g_listenerManager->UnregisterListener(window, eventString, CaseType::CASE_STAGE, value);
287 } else {
288 g_listenerManager->UnregisterListener(window, eventString, CaseType::CASE_STAGE, nullptr);
289 }
290 }
291 WLOGI("[NAPI]Window [%{public}u, %{public}s] unregister event %{public}s",
292 window->GetWindowId(), window->GetWindowName().c_str(), eventString.c_str());
293
294 return engine.CreateUndefined();
295 }
296
LoadContentTask(std::shared_ptr<NativeReference> contentStorage,std::string contextUrl,sptr<Window> weakWindow,NativeEngine & engine,AsyncTask & task)297 static void LoadContentTask(std::shared_ptr<NativeReference> contentStorage, std::string contextUrl,
298 sptr<Window> weakWindow, NativeEngine& engine, AsyncTask& task)
299 {
300 NativeValue* nativeStorage = (contentStorage == nullptr) ? nullptr : contentStorage->Get();
301 WMError ret = weakWindow->SetUIContent(contextUrl, &engine, nativeStorage, false);
302 if (ret == WMError::WM_OK) {
303 task.Resolve(engine, engine.CreateUndefined());
304 } else {
305 task.Reject(engine, CreateJsError(engine, static_cast<int32_t>(ret), "Window load content failed"));
306 }
307 WLOGI("[NAPI]Window [%{public}u, %{public}s] load content end, ret = %{public}d",
308 weakWindow->GetWindowId(), weakWindow->GetWindowName().c_str(), ret);
309 return;
310 }
311
OnLoadContent(NativeEngine & engine,NativeCallbackInfo & info)312 NativeValue* JsWindowStage::OnLoadContent(NativeEngine& engine, NativeCallbackInfo& info)
313 {
314 WmErrorCode errCode = WmErrorCode::WM_OK;
315 std::string contextUrl;
316 if (!ConvertFromJsValue(engine, info.argv[0], contextUrl)) {
317 WLOGFE("[NAPI]Failed to convert parameter to context url");
318 errCode = WmErrorCode::WM_ERROR_INVALID_PARAM;
319 }
320 NativeValue* storage = nullptr;
321 NativeValue* callBack = nullptr;
322 NativeValue* value1 = info.argv[1];
323 NativeValue* value2 = info.argv[2]; // 2: param index
324 if (value1->TypeOf() == NATIVE_FUNCTION) {
325 callBack = value1;
326 } else if (value1->TypeOf() == NATIVE_OBJECT) {
327 storage = value1;
328 }
329 if (value2->TypeOf() == NATIVE_FUNCTION) {
330 callBack = value2;
331 }
332 if (errCode == WmErrorCode::WM_ERROR_INVALID_PARAM) {
333 WLOGFE("[NAPI]Window scene is null or get invalid param");
334 engine.Throw(CreateJsError(engine, static_cast<int32_t>(WmErrorCode::WM_ERROR_INVALID_PARAM)));
335 return engine.CreateUndefined();
336 }
337 std::shared_ptr<NativeReference> contentStorage = (storage == nullptr) ? nullptr :
338 std::shared_ptr<NativeReference>(engine.CreateReference(storage, 1));
339 AsyncTask::CompleteCallback complete =
340 [weak = windowScene_, contentStorage, contextUrl](
341 NativeEngine& engine, AsyncTask& task, int32_t status) {
342 auto weakScene = weak.lock();
343 sptr<Window> win = weakScene ? weakScene->GetMainWindow() : nullptr;
344 if (win == nullptr) {
345 task.Reject(engine, CreateJsError(engine,
346 static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY)));
347 WLOGFE("[NAPI]Get window failed");
348 return;
349 }
350 LoadContentTask(contentStorage, contextUrl, win, engine, task);
351 };
352 NativeValue* result = nullptr;
353 AsyncTask::Schedule("JsWindowStage::OnLoadContent",
354 engine, CreateAsyncTaskWithLastParam(engine, callBack, nullptr, std::move(complete), &result));
355 return result;
356 }
357
OnGetWindowMode(NativeEngine & engine,NativeCallbackInfo & info)358 NativeValue* JsWindowStage::OnGetWindowMode(NativeEngine& engine, NativeCallbackInfo& info)
359 {
360 AsyncTask::CompleteCallback complete =
361 [weak = windowScene_](NativeEngine& engine, AsyncTask& task, int32_t status) {
362 auto weakScene = weak.lock();
363 if (weakScene == nullptr) {
364 task.Reject(engine, CreateJsError(engine, static_cast<int32_t>(WMError::WM_ERROR_NULLPTR)));
365 WLOGFE("[NAPI]windowScene_ is nullptr");
366 return;
367 }
368 auto window = weakScene->GetMainWindow();
369 if (window == nullptr) {
370 task.Reject(engine, CreateJsError(engine, static_cast<int32_t>(Rosen::WMError::WM_ERROR_NULLPTR),
371 "Get window failed"));
372 WLOGFE("[NAPI]Get window failed");
373 return;
374 }
375 Rosen::WindowMode mode = window->GetMode();
376 if (NATIVE_TO_JS_WINDOW_MODE_MAP.count(mode) != 0) {
377 task.Resolve(engine, CreateJsValue(engine, NATIVE_TO_JS_WINDOW_MODE_MAP.at(mode)));
378 WLOGI("[NAPI]Window [%{public}u, %{public}s] get mode %{public}u, api mode %{public}u",
379 window->GetWindowId(), window->GetWindowName().c_str(),
380 mode, NATIVE_TO_JS_WINDOW_MODE_MAP.at(mode));
381 } else {
382 task.Resolve(engine, CreateJsValue(engine, mode));
383 WLOGFE("[NAPI]Get mode %{public}u, but not in apimode", mode);
384 }
385 };
386 NativeValue* callback = (info.argv[0]->TypeOf() == NATIVE_FUNCTION) ? info.argv[0] : nullptr;
387 NativeValue* result = nullptr;
388 AsyncTask::Schedule("JsWindowStage::OnGetWindowMode",
389 engine, CreateAsyncTaskWithLastParam(engine, callback, nullptr, std::move(complete), &result));
390 return result;
391 }
392
OnCreateSubWindow(NativeEngine & engine,NativeCallbackInfo & info)393 NativeValue* JsWindowStage::OnCreateSubWindow(NativeEngine& engine, NativeCallbackInfo& info)
394 {
395 WmErrorCode errCode = WmErrorCode::WM_OK;
396 std::string windowName;
397 if (!ConvertFromJsValue(engine, info.argv[0], windowName)) {
398 WLOGFE("[NAPI]Failed to convert parameter to windowName");
399 errCode = WmErrorCode::WM_ERROR_INVALID_PARAM;
400 }
401 if (errCode == WmErrorCode::WM_ERROR_INVALID_PARAM) {
402 WLOGFE("[NAPI]get invalid param");
403 engine.Throw(CreateJsError(engine, static_cast<int32_t>(WmErrorCode::WM_ERROR_INVALID_PARAM)));
404 return engine.CreateUndefined();
405 }
406 AsyncTask::CompleteCallback complete =
407 [weak = windowScene_, windowName](NativeEngine& engine, AsyncTask& task, int32_t status) {
408 auto weakScene = weak.lock();
409 if (weakScene == nullptr) {
410 WLOGFE("[NAPI]Window scene is null");
411 task.Reject(engine, CreateJsError(engine,
412 static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY)));
413 return;
414 }
415 sptr<Rosen::WindowOption> windowOption = new Rosen::WindowOption();
416 windowOption->SetWindowType(Rosen::WindowType::WINDOW_TYPE_APP_SUB_WINDOW);
417 windowOption->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_FLOATING);
418 auto window = weakScene->CreateWindow(windowName, windowOption);
419 if (window == nullptr) {
420 WLOGFE("[NAPI]Get window failed");
421 task.Reject(engine, CreateJsError(engine,
422 static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY), "Get window failed"));
423 return;
424 }
425 task.Resolve(engine, CreateJsWindowObject(engine, window));
426 WLOGI("[NAPI]Create sub window %{public}s end", windowName.c_str());
427 };
428 NativeValue* callback = (info.argv[1] != nullptr && info.argv[1]->TypeOf() == NATIVE_FUNCTION) ?
429 info.argv[1] : nullptr;
430 NativeValue* result = nullptr;
431 AsyncTask::Schedule("JsWindowStage::OnCreateSubWindow",
432 engine, CreateAsyncTaskWithLastParam(engine, callback, nullptr, std::move(complete), &result));
433 return result;
434 }
435
CreateJsSubWindowArrayObject(NativeEngine & engine,std::vector<sptr<Window>> subWinVec)436 static NativeValue* CreateJsSubWindowArrayObject(NativeEngine& engine,
437 std::vector<sptr<Window>> subWinVec)
438 {
439 NativeValue* objValue = engine.CreateArray(subWinVec.size());
440 NativeArray* array = ConvertNativeValueTo<NativeArray>(objValue);
441 if (array == nullptr) {
442 WLOGFE("[NAPI]Failed to convert subWinVec to jsArrayObject");
443 return nullptr;
444 }
445 uint32_t index = 0;
446 for (size_t i = 0; i < subWinVec.size(); i++) {
447 array->SetElement(index++, CreateJsWindowObject(engine, subWinVec[i]));
448 }
449 return objValue;
450 }
451
OnGetSubWindow(NativeEngine & engine,NativeCallbackInfo & info)452 NativeValue* JsWindowStage::OnGetSubWindow(NativeEngine& engine, NativeCallbackInfo& info)
453 {
454 AsyncTask::CompleteCallback complete =
455 [weak = windowScene_](NativeEngine& engine, AsyncTask& task, int32_t status) {
456 auto weakScene = weak.lock();
457 if (weakScene == nullptr) {
458 WLOGFE("[NAPI]Window scene is nullptr");
459 task.Reject(engine, CreateJsError(engine,
460 static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY)));
461 return;
462 }
463 std::vector<sptr<Window>> subWindowVec = weakScene->GetSubWindow();
464 task.Resolve(engine, CreateJsSubWindowArrayObject(engine, subWindowVec));
465 WLOGI("[NAPI]Get sub windows, size = %{public}zu", subWindowVec.size());
466 };
467 NativeValue* callback = (info.argv[0] != nullptr && info.argv[0]->TypeOf() == NATIVE_FUNCTION) ?
468 info.argv[0] : nullptr;
469 NativeValue* result = nullptr;
470 AsyncTask::Schedule("JsWindowStage::OnGetSubWindow",
471 engine, CreateAsyncTaskWithLastParam(engine, callback, nullptr, std::move(complete), &result));
472 return result;
473 }
474
OnSetShowOnLockScreen(NativeEngine & engine,NativeCallbackInfo & info)475 NativeValue* JsWindowStage::OnSetShowOnLockScreen(NativeEngine& engine, NativeCallbackInfo& info)
476 {
477 if (!Permission::IsSystemCalling() && !Permission::IsStartByHdcd()) {
478 WLOGFE("set show on lock screen permission denied!");
479 engine.Throw(CreateJsError(engine, static_cast<int32_t>(WmErrorCode::WM_ERROR_NOT_SYSTEM_APP)));
480 return CreateJsValue(engine, static_cast<int32_t>(WmErrorCode::WM_ERROR_NOT_SYSTEM_APP));
481 }
482 if (info.argc < 1) {
483 WLOGFE("[NAPI]Argc is invalid: %{public}zu", info.argc);
484 engine.Throw(CreateJsError(engine, static_cast<int32_t>(WmErrorCode::WM_ERROR_INVALID_PARAM)));
485 return CreateJsValue(engine, static_cast<int32_t>(WmErrorCode::WM_ERROR_INVALID_PARAM));
486 }
487 auto weakScene = windowScene_.lock();
488 if (weakScene == nullptr || weakScene->GetMainWindow() == nullptr) {
489 WLOGFE("[NAPI]WindowScene is null or window is null");
490 engine.Throw(CreateJsError(engine, static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY)));
491 return CreateJsValue(engine, static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
492 }
493
494 bool showOnLockScreen = false;
495 NativeBoolean* nativeVal = ConvertNativeValueTo<NativeBoolean>(info.argv[0]);
496 if (nativeVal == nullptr) {
497 WLOGFE("[NAPI]Failed to convert parameter to boolean");
498 engine.Throw(CreateJsError(engine, static_cast<int32_t>(WmErrorCode::WM_ERROR_INVALID_PARAM)));
499 return CreateJsValue(engine, static_cast<int32_t>(WmErrorCode::WM_ERROR_INVALID_PARAM));
500 } else {
501 showOnLockScreen = static_cast<bool>(*nativeVal);
502 }
503
504 auto window = weakScene->GetMainWindow();
505 WmErrorCode ret;
506 if (showOnLockScreen) {
507 ret = WM_JS_TO_ERROR_CODE_MAP.at(
508 window->AddWindowFlag(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED));
509 } else {
510 ret = WM_JS_TO_ERROR_CODE_MAP.at(
511 window->RemoveWindowFlag(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED));
512 }
513 WLOGI("[NAPI]Window [%{public}u, %{public}s] SetShowOnLockScreen %{public}u, ret = %{public}u",
514 window->GetWindowId(), window->GetWindowName().c_str(), showOnLockScreen, ret);
515
516 return CreateJsValue(engine, static_cast<int32_t>(ret));
517 }
518
OnDisableWindowDecor(NativeEngine & engine,NativeCallbackInfo & info)519 NativeValue* JsWindowStage::OnDisableWindowDecor(NativeEngine& engine, NativeCallbackInfo& info)
520 {
521 auto weakScene = windowScene_.lock();
522 if (weakScene == nullptr) {
523 WLOGFE("[NAPI]WindowScene is null");
524 return CreateJsValue(engine, static_cast<int32_t>(WmErrorCode::WM_ERROR_STAGE_ABNORMALLY));
525 }
526
527 auto window = weakScene->GetMainWindow();
528 if (window == nullptr) {
529 WLOGFE("[NAPI]Window is null");
530 return CreateJsValue(engine, static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY));
531 }
532 WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(window->DisableAppWindowDecor());
533 if (ret != WmErrorCode::WM_OK) {
534 engine.Throw(CreateJsError(engine, static_cast<int32_t>(ret)));
535 WLOGI("[NAPI]Window [%{public}u, %{public}s] disable app window decor end",
536 window->GetWindowId(), window->GetWindowName().c_str());
537 return engine.CreateUndefined();
538 }
539 return engine.CreateUndefined();
540 }
541
CreateJsWindowStage(NativeEngine & engine,std::shared_ptr<Rosen::WindowScene> windowScene)542 NativeValue* CreateJsWindowStage(NativeEngine& engine, std::shared_ptr<Rosen::WindowScene> windowScene)
543 {
544 WLOGFD("[NAPI]CreateJsWindowStage");
545 NativeValue* objValue = engine.CreateObject();
546 NativeObject* object = ConvertNativeValueTo<NativeObject>(objValue);
547
548 std::unique_ptr<JsWindowStage> jsWindowStage = std::make_unique<JsWindowStage>(windowScene);
549 object->SetNativePointer(jsWindowStage.release(), JsWindowStage::Finalizer, nullptr);
550
551 const char *moduleName = "JsWindowStage";
552 BindNativeFunction(engine,
553 *object, "setUIContent", moduleName, JsWindowStage::SetUIContent);
554 BindNativeFunction(engine,
555 *object, "loadContent", moduleName, JsWindowStage::LoadContent);
556 BindNativeFunction(engine,
557 *object, "getMainWindow", moduleName, JsWindowStage::GetMainWindow);
558 BindNativeFunction(engine,
559 *object, "getMainWindowSync", moduleName, JsWindowStage::GetMainWindowSync);
560 BindNativeFunction(engine,
561 *object, "getWindowMode", moduleName, JsWindowStage::GetWindowMode);
562 BindNativeFunction(engine,
563 *object, "createSubWindow", moduleName, JsWindowStage::CreateSubWindow);
564 BindNativeFunction(engine,
565 *object, "getSubWindow", moduleName, JsWindowStage::GetSubWindow);
566 BindNativeFunction(engine, *object, "on", moduleName, JsWindowStage::On);
567 BindNativeFunction(engine, *object, "off", moduleName, JsWindowStage::Off);
568 BindNativeFunction(engine,
569 *object, "setShowOnLockScreen", moduleName, JsWindowStage::SetShowOnLockScreen);
570 BindNativeFunction(engine,
571 *object, "disableWindowDecor", moduleName, JsWindowStage::DisableWindowDecor);
572
573 return objValue;
574 }
575 } // namespace Rosen
576 } // namespace OHOS
577