• 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     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