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