• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "js_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