• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2023 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_extension_window.h"
17 
18 #include "js_extension_window_utils.h"
19 #include "js_runtime_utils.h"
20 #include "js_window_utils.h"
21 #include "js_window.h"
22 #include "window_manager_hilog.h"
23 #include "wm_common.h"
24 #include "extension_window.h"
25 #include "ui_content.h"
26 #include "permission.h"
27 
28 namespace OHOS {
29 namespace Rosen {
30 using namespace AbilityRuntime;
31 namespace {
32 constexpr Rect g_emptyRect = {0, 0, 0, 0};
33 constexpr size_t INDEX_ZERO = 0;
34 constexpr size_t INDEX_ONE = 1;
35 constexpr size_t INDEX_TWO = 2;
36 constexpr size_t ARG_COUNT_ONE = 1;
37 constexpr size_t ARG_COUNT_TWO = 2;
38 constexpr size_t ARG_COUNT_THREE = 3;
39 constexpr size_t FOUR_PARAMS_SIZE = 4;
40 } // namespace
41 
JsExtensionWindow(const std::shared_ptr<Rosen::ExtensionWindow> extensionWindow,int32_t hostWindowId)42 JsExtensionWindow::JsExtensionWindow(
43     const std::shared_ptr<Rosen::ExtensionWindow> extensionWindow,
44     int32_t hostWindowId)
45     : extensionWindow_(extensionWindow), hostWindowId_(hostWindowId),
46     extensionRegisterManager_(std::make_unique<JsExtensionWindowRegisterManager>()) {
47 }
48 
JsExtensionWindow(const std::shared_ptr<Rosen::ExtensionWindow> extensionWindow,sptr<AAFwk::SessionInfo> sessionInfo)49 JsExtensionWindow::JsExtensionWindow(const std::shared_ptr<Rosen::ExtensionWindow> extensionWindow,
50     sptr<AAFwk::SessionInfo> sessionInfo)
51     : extensionWindow_(extensionWindow), hostWindowId_(-1), sessionInfo_(sessionInfo),
52     extensionRegisterManager_(std::make_unique<JsExtensionWindowRegisterManager>()) {
53 }
54 
~JsExtensionWindow()55 JsExtensionWindow::~JsExtensionWindow() {}
56 
CreateJsExtensionWindow(napi_env env,sptr<Rosen::Window> window,int32_t hostWindowId)57 napi_value JsExtensionWindow::CreateJsExtensionWindow(napi_env env, sptr<Rosen::Window> window, int32_t hostWindowId)
58 {
59     TLOGD(WmsLogTag::WMS_UIEXT, "Called.");
60     napi_value objValue = nullptr;
61     napi_create_object(env, &objValue);
62 
63     if (env == nullptr || window == nullptr || objValue == nullptr) {
64         TLOGE(WmsLogTag::WMS_UIEXT, "JsExtensionWindow env or window is nullptr");
65         return nullptr;
66     }
67 
68     std::shared_ptr<ExtensionWindow> extensionWindow = std::make_shared<ExtensionWindowImpl>(window);
69     std::unique_ptr<JsExtensionWindow> jsExtensionWindow =
70         std::make_unique<JsExtensionWindow>(extensionWindow, hostWindowId);
71     napi_wrap(env, objValue, jsExtensionWindow.release(), JsExtensionWindow::Finalizer, nullptr, nullptr);
72 
73     napi_property_descriptor desc[] = {
74         DECLARE_NAPI_GETTER("properties", JsExtensionWindow::GetProperties)
75     };
76     NAPI_CALL(env, napi_define_properties(env, objValue, sizeof(desc) / sizeof(desc[0]), desc));
77 
78     const char *moduleName = "JsExtensionWindow";
79     BindNativeFunction(env, objValue, "getWindowAvoidArea", moduleName, JsExtensionWindow::GetWindowAvoidArea);
80     BindNativeFunction(env, objValue, "on", moduleName, JsExtensionWindow::RegisterExtensionWindowCallback);
81     BindNativeFunction(env, objValue, "off", moduleName, JsExtensionWindow::UnRegisterExtensionWindowCallback);
82     BindNativeFunction(env, objValue, "hideNonSecureWindows", moduleName, JsExtensionWindow::HideNonSecureWindows);
83     BindNativeFunction(env, objValue, "createSubWindowWithOptions", moduleName,
84         JsExtensionWindow::CreateSubWindowWithOptions);
85     BindNativeFunction(env, objValue, "setWaterMarkFlag", moduleName, JsExtensionWindow::SetWaterMarkFlag);
86     BindNativeFunction(env, objValue, "hidePrivacyContentForHost", moduleName,
87                        JsExtensionWindow::HidePrivacyContentForHost);
88     BindNativeFunction(env, objValue, "occupyEvents", moduleName, JsExtensionWindow::OccupyEvents);
89 
90     return objValue;
91 }
92 
CreateJsExtensionWindowObject(napi_env env,sptr<Rosen::Window> window,sptr<AAFwk::SessionInfo> sessionInfo)93 napi_value JsExtensionWindow::CreateJsExtensionWindowObject(napi_env env, sptr<Rosen::Window> window,
94     sptr<AAFwk::SessionInfo> sessionInfo)
95 {
96     TLOGI(WmsLogTag::WMS_UIEXT, "[NAPI]");
97     napi_value objValue = nullptr;
98     napi_create_object(env, &objValue);
99 
100     if (env == nullptr || window == nullptr || objValue == nullptr) {
101         TLOGE(WmsLogTag::WMS_UIEXT, "JsExtensionWindow env or window is nullptr");
102         return nullptr;
103     }
104 
105     std::shared_ptr<ExtensionWindow> extensionWindow = std::make_shared<ExtensionWindowImpl>(window);
106     std::unique_ptr<JsExtensionWindow> jsExtensionWindow = std::make_unique<JsExtensionWindow>(extensionWindow,
107         sessionInfo);
108     napi_wrap(env, objValue, jsExtensionWindow.release(), JsExtensionWindow::Finalizer, nullptr, nullptr);
109 
110     const char *moduleName = "JsExtensionWindow";
111     BindNativeFunction(env, objValue, "on", moduleName, JsExtensionWindow::RegisterExtensionWindowCallback);
112     BindNativeFunction(env, objValue, "off", moduleName, JsExtensionWindow::UnRegisterExtensionWindowCallback);
113     BindNativeFunction(env, objValue, "moveWindowTo", moduleName, JsExtensionWindow::MoveWindowTo);
114     BindNativeFunction(env, objValue, "resize", moduleName, JsExtensionWindow::ResizeWindow);
115     BindNativeFunction(env, objValue, "getUIContext", moduleName, JsExtensionWindow::GetUIContext);
116     BindNativeFunction(env, objValue, "setWindowBrightness", moduleName, JsExtensionWindow::SetWindowBrightness);
117     BindNativeFunction(env, objValue, "setWindowKeepScreenOn", moduleName, JsExtensionWindow::SetWindowKeepScreenOn);
118     BindNativeFunction(env, objValue, "showWindow", moduleName, JsExtensionWindow::ShowWindow);
119     BindNativeFunction(env, objValue, "destroyWindow", moduleName, JsExtensionWindow::DestroyWindow);
120     BindNativeFunction(env, objValue, "loadContent", moduleName, JsExtensionWindow::LoadContent);
121     BindNativeFunction(env, objValue, "loadContentByName", moduleName, JsExtensionWindow::LoadContentByName);
122     BindNativeFunction(env, objValue, "setUIContent", moduleName, JsExtensionWindow::SetUIContent);
123     BindNativeFunction(env, objValue, "isWindowShowing", moduleName, JsExtensionWindow::IsWindowShowingSync);
124     BindNativeFunction(env, objValue, "getWindowProperties", moduleName, JsExtensionWindow::GetWindowPropertiesSync);
125     BindNativeFunction(env, objValue, "getWindowAvoidArea", moduleName, JsExtensionWindow::GetWindowAvoidArea);
126     BindNativeFunction(env, objValue, "setWindowBackgroundColor", moduleName,
127         JsExtensionWindow::SetWindowBackgroundColorSync);
128     BindNativeFunction(env, objValue, "setSpecificSystemBarEnabled", moduleName,
129         JsExtensionWindow::SetSpecificSystemBarEnabled);
130     BindNativeFunction(env, objValue, "setPreferredOrientation", moduleName,
131         JsExtensionWindow::SetPreferredOrientation);
132     BindNativeFunction(env, objValue, "getPreferredOrientation", moduleName,
133         JsExtensionWindow::GetPreferredOrientation);
134     return objValue;
135 }
136 
Finalizer(napi_env env,void * data,void * hint)137 void JsExtensionWindow::Finalizer(napi_env env, void* data, void* hint)
138 {
139     TLOGI(WmsLogTag::WMS_UIEXT, "[NAPI]");
140     std::unique_ptr<JsExtensionWindow>(static_cast<JsExtensionWindow*>(data));
141 }
142 
GetWindowAvoidArea(napi_env env,napi_callback_info info)143 napi_value JsExtensionWindow::GetWindowAvoidArea(napi_env env, napi_callback_info info)
144 {
145     TLOGI(WmsLogTag::WMS_UIEXT, "[NAPI]");
146     JsExtensionWindow* me = CheckParamsAndGetThis<JsExtensionWindow>(env, info);
147     return (me != nullptr) ? me->OnGetWindowAvoidArea(env, info) : nullptr;
148 }
149 
RegisterExtensionWindowCallback(napi_env env,napi_callback_info info)150 napi_value JsExtensionWindow::RegisterExtensionWindowCallback(napi_env env, napi_callback_info info)
151 {
152     TLOGI(WmsLogTag::WMS_UIEXT, "[NAPI]");
153     JsExtensionWindow* me = CheckParamsAndGetThis<JsExtensionWindow>(env, info);
154     return (me != nullptr) ? me->OnRegisterExtensionWindowCallback(env, info) : nullptr;
155 }
156 
UnRegisterExtensionWindowCallback(napi_env env,napi_callback_info info)157 napi_value JsExtensionWindow::UnRegisterExtensionWindowCallback(napi_env env, napi_callback_info info)
158 {
159     TLOGI(WmsLogTag::WMS_UIEXT, "[NAPI]");
160     JsExtensionWindow* me = CheckParamsAndGetThis<JsExtensionWindow>(env, info);
161     return (me != nullptr) ? me->OnUnRegisterExtensionWindowCallback(env, info) : nullptr;
162 }
163 
HideNonSecureWindows(napi_env env,napi_callback_info info)164 napi_value JsExtensionWindow::HideNonSecureWindows(napi_env env, napi_callback_info info)
165 {
166     TLOGI(WmsLogTag::WMS_UIEXT, "[NAPI]");
167     JsExtensionWindow* me = CheckParamsAndGetThis<JsExtensionWindow>(env, info);
168     return (me != nullptr) ? me->OnHideNonSecureWindows(env, info) : nullptr;
169 }
170 
CreateSubWindowWithOptions(napi_env env,napi_callback_info info)171 napi_value JsExtensionWindow::CreateSubWindowWithOptions(napi_env env, napi_callback_info info)
172 {
173     TLOGI(WmsLogTag::WMS_UIEXT, "[NAPI]");
174     JsExtensionWindow* me = CheckParamsAndGetThis<JsExtensionWindow>(env, info);
175     return (me != nullptr) ? me->OnCreateSubWindowWithOptions(env, info) : nullptr;
176 }
177 
SetWaterMarkFlag(napi_env env,napi_callback_info info)178 napi_value JsExtensionWindow::SetWaterMarkFlag(napi_env env, napi_callback_info info)
179 {
180     TLOGI(WmsLogTag::WMS_UIEXT, "[NAPI]");
181     JsExtensionWindow* me = CheckParamsAndGetThis<JsExtensionWindow>(env, info);
182     return (me != nullptr) ? me->OnSetWaterMarkFlag(env, info) : nullptr;
183 }
184 
HidePrivacyContentForHost(napi_env env,napi_callback_info info)185 napi_value JsExtensionWindow::HidePrivacyContentForHost(napi_env env, napi_callback_info info)
186 {
187     TLOGD(WmsLogTag::WMS_UIEXT, "[NAPI]");
188     JsExtensionWindow* me = CheckParamsAndGetThis<JsExtensionWindow>(env, info);
189     return (me != nullptr) ? me->OnHidePrivacyContentForHost(env, info) : nullptr;
190 }
191 
LoadContent(napi_env env,napi_callback_info info)192 napi_value JsExtensionWindow::LoadContent(napi_env env, napi_callback_info info)
193 {
194     TLOGI(WmsLogTag::WMS_UIEXT, "[NAPI]");
195     JsExtensionWindow* me = CheckParamsAndGetThis<JsExtensionWindow>(env, info);
196     return (me != nullptr) ? me->OnLoadContent(env, info, false) : nullptr;
197 }
198 
LoadContentByName(napi_env env,napi_callback_info info)199 napi_value JsExtensionWindow::LoadContentByName(napi_env env, napi_callback_info info)
200 {
201     TLOGI(WmsLogTag::WMS_UIEXT, "[NAPI]");
202     JsExtensionWindow* me = CheckParamsAndGetThis<JsExtensionWindow>(env, info);
203     return (me != nullptr) ? me->OnLoadContent(env, info, true) : nullptr;
204 }
205 
ShowWindow(napi_env env,napi_callback_info info)206 napi_value JsExtensionWindow::ShowWindow(napi_env env, napi_callback_info info)
207 {
208     TLOGI(WmsLogTag::WMS_UIEXT, "[NAPI]");
209     JsExtensionWindow* me = CheckParamsAndGetThis<JsExtensionWindow>(env, info);
210     return (me != nullptr) ? me->OnShowWindow(env, info) : nullptr;
211 }
212 
IsWindowShowingSync(napi_env env,napi_callback_info info)213 napi_value JsExtensionWindow::IsWindowShowingSync(napi_env env, napi_callback_info info)
214 {
215     TLOGI(WmsLogTag::WMS_UIEXT, "[NAPI]");
216     JsExtensionWindow* me = CheckParamsAndGetThis<JsExtensionWindow>(env, info);
217     return (me != nullptr) ? me->OnIsWindowShowingSync(env, info) : nullptr;
218 }
219 
SetUIContent(napi_env env,napi_callback_info info)220 napi_value JsExtensionWindow::SetUIContent(napi_env env, napi_callback_info info)
221 {
222     TLOGI(WmsLogTag::WMS_UIEXT, "[NAPI]");
223     JsExtensionWindow* me = CheckParamsAndGetThis<JsExtensionWindow>(env, info);
224     return (me != nullptr) ? me->OnSetUIContent(env, info) : nullptr;
225 }
226 
DestroyWindow(napi_env env,napi_callback_info info)227 napi_value JsExtensionWindow::DestroyWindow(napi_env env, napi_callback_info info)
228 {
229     TLOGI(WmsLogTag::WMS_UIEXT, "[NAPI]");
230     JsExtensionWindow* me = CheckParamsAndGetThis<JsExtensionWindow>(env, info);
231     return (me != nullptr) ? me->OnDestroyWindow(env, info) : nullptr;
232 }
233 
SetWindowBackgroundColorSync(napi_env env,napi_callback_info info)234 napi_value JsExtensionWindow::SetWindowBackgroundColorSync(napi_env env, napi_callback_info info)
235 {
236     TLOGI(WmsLogTag::WMS_UIEXT, "[NAPI]");
237     JsExtensionWindow* me = CheckParamsAndGetThis<JsExtensionWindow>(env, info);
238     return (me != nullptr) ? me->OnSetWindowBackgroundColorSync(env, info) : nullptr;
239 }
240 
GetWindowPropertiesSync(napi_env env,napi_callback_info info)241 napi_value JsExtensionWindow::GetWindowPropertiesSync(napi_env env, napi_callback_info info)
242 {
243     TLOGD(WmsLogTag::WMS_UIEXT, "[NAPI]");
244     JsExtensionWindow* me = CheckParamsAndGetThis<JsExtensionWindow>(env, info);
245     return (me != nullptr) ? me->OnGetWindowPropertiesSync(env, info) : nullptr;
246 }
247 
MoveWindowTo(napi_env env,napi_callback_info info)248 napi_value JsExtensionWindow::MoveWindowTo(napi_env env, napi_callback_info info)
249 {
250     TLOGD(WmsLogTag::WMS_UIEXT, "[NAPI]");
251     JsExtensionWindow* me = CheckParamsAndGetThis<JsExtensionWindow>(env, info);
252     return (me != nullptr) ? me->OnMoveWindowTo(env, info) : nullptr;
253 }
254 
ResizeWindow(napi_env env,napi_callback_info info)255 napi_value JsExtensionWindow::ResizeWindow(napi_env env, napi_callback_info info)
256 {
257     TLOGI(WmsLogTag::WMS_UIEXT, "[NAPI]");
258     JsExtensionWindow* me = CheckParamsAndGetThis<JsExtensionWindow>(env, info);
259     return (me != nullptr) ? me->OnResizeWindow(env, info) : nullptr;
260 }
261 
SetSpecificSystemBarEnabled(napi_env env,napi_callback_info info)262 napi_value JsExtensionWindow::SetSpecificSystemBarEnabled(napi_env env, napi_callback_info info)
263 {
264     TLOGI(WmsLogTag::WMS_UIEXT, "[NAPI]");
265     JsExtensionWindow* me = CheckParamsAndGetThis<JsExtensionWindow>(env, info);
266     return (me != nullptr) ? me->OnSetSpecificSystemBarEnabled(env, info) : nullptr;
267 }
268 
SetPreferredOrientation(napi_env env,napi_callback_info info)269 napi_value JsExtensionWindow::SetPreferredOrientation(napi_env env, napi_callback_info info)
270 {
271     TLOGD(WmsLogTag::WMS_UIEXT, "[NAPI]");
272     JsExtensionWindow* me = CheckParamsAndGetThis<JsExtensionWindow>(env, info);
273     return (me != nullptr) ? me->OnSetPreferredOrientation(env, info) : nullptr;
274 }
275 
GetPreferredOrientation(napi_env env,napi_callback_info info)276 napi_value JsExtensionWindow::GetPreferredOrientation(napi_env env, napi_callback_info info)
277 {
278     TLOGD(WmsLogTag::WMS_UIEXT, "[NAPI]");
279     JsExtensionWindow* me = CheckParamsAndGetThis<JsExtensionWindow>(env, info);
280     return (me != nullptr) ? me->OnGetPreferredOrientation(env, info) : nullptr;
281 }
282 
GetUIContext(napi_env env,napi_callback_info info)283 napi_value JsExtensionWindow::GetUIContext(napi_env env, napi_callback_info info)
284 {
285     TLOGD(WmsLogTag::WMS_UIEXT, "[NAPI]");
286     JsExtensionWindow* me = CheckParamsAndGetThis<JsExtensionWindow>(env, info);
287     return (me != nullptr) ? me->OnGetUIContext(env, info) : nullptr;
288 }
289 
SetWindowBrightness(napi_env env,napi_callback_info info)290 napi_value JsExtensionWindow::SetWindowBrightness(napi_env env, napi_callback_info info)
291 {
292     TLOGI(WmsLogTag::WMS_UIEXT, "[NAPI]");
293     JsExtensionWindow* me = CheckParamsAndGetThis<JsExtensionWindow>(env, info);
294     return (me != nullptr) ? me->OnSetWindowBrightness(env, info) : nullptr;
295 }
296 
SetWindowKeepScreenOn(napi_env env,napi_callback_info info)297 napi_value JsExtensionWindow::SetWindowKeepScreenOn(napi_env env, napi_callback_info info)
298 {
299     TLOGI(WmsLogTag::WMS_UIEXT, "[NAPI]");
300     JsExtensionWindow* me = CheckParamsAndGetThis<JsExtensionWindow>(env, info);
301     return (me != nullptr) ? me->OnSetWindowKeepScreenOn(env, info) : nullptr;
302 }
303 
OccupyEvents(napi_env env,napi_callback_info info)304 napi_value JsExtensionWindow::OccupyEvents(napi_env env, napi_callback_info info)
305 {
306     JsExtensionWindow* me = CheckParamsAndGetThis<JsExtensionWindow>(env, info);
307     return (me != nullptr) ? me->OnOccupyEvents(env, info) : nullptr;
308 }
309 
GetType(napi_env env,napi_value value)310 napi_valuetype GetType(napi_env env, napi_value value)
311 {
312     napi_valuetype res = napi_undefined;
313     napi_typeof(env, value, &res);
314     return res;
315 }
316 
LoadContentTask(std::shared_ptr<NativeReference> contentStorage,std::string contextUrl,const std::shared_ptr<Rosen::ExtensionWindow> win,napi_env env,NapiAsyncTask & task,sptr<IRemoteObject> parentToken,bool isLoadedByName)317 static void LoadContentTask(std::shared_ptr<NativeReference> contentStorage, std::string contextUrl,
318     const std::shared_ptr<Rosen::ExtensionWindow> win, napi_env env, NapiAsyncTask& task,
319     sptr<IRemoteObject> parentToken, bool isLoadedByName)
320 {
321     napi_value nativeStorage = (contentStorage == nullptr) ? nullptr : contentStorage->GetNapiValue();
322     sptr<Window> windowImpl = win->GetWindow();
323     WMError ret;
324     if (isLoadedByName) {
325         ret = windowImpl->SetUIContentByName(contextUrl, env, nativeStorage);
326     } else {
327         ret = windowImpl->NapiSetUIContent(contextUrl, env, nativeStorage, BackupAndRestoreType::NONE, parentToken);
328     }
329     if (ret == WMError::WM_OK) {
330         task.Resolve(env, NapiGetUndefined(env));
331     } else {
332         task.Reject(env, CreateJsError(env, static_cast<int32_t>(ret), "Window load content failed"));
333     }
334     TLOGI(WmsLogTag::WMS_UIEXT, "Window [%{public}u, %{public}s] end, ret=%{public}d",
335         windowImpl->GetWindowId(), windowImpl->GetWindowName().c_str(), ret);
336 }
337 
OnSetWindowKeepScreenOn(napi_env env,napi_callback_info info)338 napi_value JsExtensionWindow::OnSetWindowKeepScreenOn(napi_env env, napi_callback_info info)
339 {
340     size_t argc = 4;
341     napi_value argv[4] = {nullptr};
342     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
343     napi_value lastParam = (argc <= 1) ? nullptr :
344         ((argv[1] != nullptr && GetType(env, argv[1]) == napi_function) ? argv[1] : nullptr);
345     napi_value result = nullptr;
346     std::shared_ptr<NapiAsyncTask> napiAsyncTask = CreateEmptyAsyncTask(env, lastParam, &result);
347     auto asyncTask = [env, task = napiAsyncTask]() {
348         task->Reject(env,
349             CreateJsError(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT)));
350     };
351     if (napi_status::napi_ok != napi_send_event(env, asyncTask, napi_eprio_high)) {
352         napiAsyncTask->Reject(env, CreateJsError(env,
353             static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY), "send event failed"));
354     }
355     return result;
356 }
357 
OnSetWindowBrightness(napi_env env,napi_callback_info info)358 napi_value JsExtensionWindow::OnSetWindowBrightness(napi_env env, napi_callback_info info)
359 {
360     size_t argc = 4;
361     napi_value argv[4] = {nullptr};
362     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
363     napi_value lastParam = (argc <= 1) ? nullptr :
364         ((argv[1] != nullptr && GetType(env, argv[1]) == napi_function) ? argv[1] : nullptr);
365     napi_value result = nullptr;
366     std::shared_ptr<NapiAsyncTask> napiAsyncTask = CreateEmptyAsyncTask(env, lastParam, &result);
367     auto asyncTask = [env, task = napiAsyncTask]() {
368         task->Reject(env,
369             CreateJsError(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT)));
370     };
371     if (napi_status::napi_ok != napi_send_event(env, asyncTask, napi_eprio_high)) {
372         napiAsyncTask->Reject(env, CreateJsError(env,
373             static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY), "send event failed"));
374     }
375     return result;
376 }
377 
OnGetUIContext(napi_env env,napi_callback_info info)378 napi_value JsExtensionWindow::OnGetUIContext(napi_env env, napi_callback_info info)
379 {
380     return NapiThrowError(env, WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT);
381 }
382 
OnSetPreferredOrientation(napi_env env,napi_callback_info info)383 napi_value JsExtensionWindow::OnSetPreferredOrientation(napi_env env, napi_callback_info info)
384 {
385     size_t argc = 4;
386     napi_value argv[4] = {nullptr};
387     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
388     napi_value lastParam = (argc <= 1) ? nullptr :
389         ((argv[1] != nullptr && GetType(env, argv[1]) == napi_function) ? argv[1] : nullptr);
390     napi_value result = nullptr;
391     std::shared_ptr<NapiAsyncTask> napiAsyncTask = CreateEmptyAsyncTask(env, lastParam, &result);
392     auto asyncTask = [env, task = napiAsyncTask]() {
393         task->Reject(env,
394             CreateJsError(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT)));
395     };
396     if (napi_status::napi_ok != napi_send_event(env, asyncTask, napi_eprio_high)) {
397         napiAsyncTask->Reject(env, CreateJsError(env,
398             static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY), "send event failed"));
399     }
400     return result;
401 }
402 
OnGetPreferredOrientation(napi_env env,napi_callback_info info)403 napi_value JsExtensionWindow::OnGetPreferredOrientation(napi_env env, napi_callback_info info)
404 {
405     return NapiThrowError(env, WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT);
406 }
407 
OnSetSpecificSystemBarEnabled(napi_env env,napi_callback_info info)408 napi_value JsExtensionWindow::OnSetSpecificSystemBarEnabled(napi_env env, napi_callback_info info)
409 {
410     napi_value result = nullptr;
411     std::shared_ptr<NapiAsyncTask> napiAsyncTask = CreateEmptyAsyncTask(env, nullptr, &result);
412     auto asyncTask = [env, task = napiAsyncTask]() {
413         task->Reject(env,
414             CreateJsError(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT)));
415     };
416     if (napi_status::napi_ok != napi_send_event(env, asyncTask, napi_eprio_high)) {
417         napiAsyncTask->Reject(env, CreateJsError(env,
418             static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY), "send event failed"));
419     }
420     return result;
421 }
422 
OnResizeWindow(napi_env env,napi_callback_info info)423 napi_value JsExtensionWindow::OnResizeWindow(napi_env env, napi_callback_info info)
424 {
425     size_t argc = 4;
426     napi_value argv[4] = {nullptr};
427     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
428     napi_value lastParam = (argc <= 2) ? nullptr :
429         ((argv[2] != nullptr && GetType(env, argv[2]) == napi_function) ? argv[2] : nullptr);
430     napi_value result = nullptr;
431     std::shared_ptr<NapiAsyncTask> napiAsyncTask = CreateEmptyAsyncTask(env, lastParam, &result);
432     auto asyncTask = [env, task = napiAsyncTask]() {
433         task->Reject(env,
434             CreateJsError(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT)));
435     };
436     if (napi_status::napi_ok != napi_send_event(env, asyncTask, napi_eprio_high)) {
437         napiAsyncTask->Reject(env, CreateJsError(env,
438             static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY), "send event failed"));
439     }
440     return result;
441 }
442 
OnMoveWindowTo(napi_env env,napi_callback_info info)443 napi_value JsExtensionWindow::OnMoveWindowTo(napi_env env, napi_callback_info info)
444 {
445     size_t argc = 4;
446     napi_value argv[4] = {nullptr};
447     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
448     napi_value lastParam = (argc <= 2) ? nullptr :
449         ((argv[2] != nullptr && GetType(env, argv[2]) == napi_function) ? argv[2] : nullptr);
450     napi_value result = nullptr;
451     std::shared_ptr<NapiAsyncTask> napiAsyncTask = CreateEmptyAsyncTask(env, lastParam, &result);
452     auto asyncTask = [env, task = napiAsyncTask]() {
453         task->Reject(env,
454             CreateJsError(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT)));
455     };
456     if (napi_status::napi_ok != napi_send_event(env, asyncTask, napi_eprio_high)) {
457         napiAsyncTask->Reject(env, CreateJsError(env,
458             static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY), "send event failed"));
459     }
460     return result;
461 }
462 
OnGetWindowPropertiesSync(napi_env env,napi_callback_info info)463 napi_value JsExtensionWindow::OnGetWindowPropertiesSync(napi_env env, napi_callback_info info)
464 {
465     sptr<Window> windowImpl = extensionWindow_->GetWindow();
466     if (windowImpl == nullptr) {
467         TLOGW(WmsLogTag::WMS_UIEXT, "window is nullptr");
468         return NapiThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY);
469     }
470     auto objValue = CreateJsExtensionWindowProperties(env, windowImpl);
471     TLOGI(WmsLogTag::WMS_UIEXT, "Window [%{public}u, %{public}s] get properties end",
472         windowImpl->GetWindowId(), windowImpl->GetWindowName().c_str());
473     if (objValue != nullptr) {
474         return objValue;
475     } else {
476         return NapiThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY);
477     }
478 }
479 
OnSetWindowBackgroundColorSync(napi_env env,napi_callback_info info)480 napi_value JsExtensionWindow::OnSetWindowBackgroundColorSync(napi_env env, napi_callback_info info)
481 {
482     return NapiThrowError(env, WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT);
483 }
484 
OnDestroyWindow(napi_env env,napi_callback_info info)485 napi_value JsExtensionWindow::OnDestroyWindow(napi_env env, napi_callback_info info)
486 {
487     size_t argc = 4;
488     napi_value argv[4] = {nullptr};
489     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
490     napi_value lastParam = (argc == 0) ? nullptr :
491         ((argv[0] != nullptr && GetType(env, argv[0]) == napi_function) ? argv[0] : nullptr);
492     napi_value result = nullptr;
493     std::shared_ptr<NapiAsyncTask> napiAsyncTask = CreateEmptyAsyncTask(env, lastParam, &result);
494     auto asyncTask = [extWindow = extensionWindow_, env, task = napiAsyncTask]() {
495         if (extWindow == nullptr) {
496             TLOGNE(WmsLogTag::WMS_UIEXT, "extensionWindow is null");
497             task->Reject(env,
498                 CreateJsError(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY)));
499             return;
500         }
501         sptr<Window> windowImpl = extWindow->GetWindow();
502         if (windowImpl == nullptr) {
503             TLOGNE(WmsLogTag::WMS_UIEXT, "window is nullptr");
504             task->Reject(env,
505                 CreateJsError(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY)));
506             return;
507         }
508         WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(windowImpl->Destroy());
509         TLOGNI(WmsLogTag::WMS_UIEXT, "Window [%{public}u, %{public}s] destroy end, ret=%{public}d",
510             windowImpl->GetWindowId(), windowImpl->GetWindowName().c_str(), ret);
511         if (ret != WmErrorCode::WM_OK) {
512             task->Reject(env,
513                 CreateJsError(env, static_cast<int32_t>(ret),
514                 "Window destroy failed"));
515             return;
516         }
517         task->Resolve(env, NapiGetUndefined(env));
518     };
519     if (napi_status::napi_ok != napi_send_event(env, asyncTask, napi_eprio_high)) {
520         napiAsyncTask->Reject(env, CreateJsError(env,
521             static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY), "send event failed"));
522     }
523     return result;
524 }
525 
OnIsWindowShowingSync(napi_env env,napi_callback_info info)526 napi_value JsExtensionWindow::OnIsWindowShowingSync(napi_env env, napi_callback_info info)
527 {
528     sptr<Window> windowImpl = extensionWindow_->GetWindow();
529     if (windowImpl == nullptr) {
530         TLOGE(WmsLogTag::WMS_UIEXT, "window is nullptr");
531         return NapiThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY);
532     }
533     bool state = (windowImpl->GetWindowState() == WindowState::STATE_SHOWN);
534     TLOGI(WmsLogTag::WMS_UIEXT, "Window [%{public}u, %{public}s] get show state end, state=%{public}u",
535         windowImpl->GetWindowId(), windowImpl->GetWindowName().c_str(), state);
536     return CreateJsValue(env, state);
537 }
538 
OnShowWindow(napi_env env,napi_callback_info info)539 napi_value JsExtensionWindow::OnShowWindow(napi_env env, napi_callback_info info)
540 {
541     size_t argc = 4;
542     napi_value argv[4] = {nullptr};
543     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
544     napi_value lastParam = (argc == 0) ? nullptr :
545         ((argv[0] != nullptr && GetType(env, argv[0]) == napi_function) ? argv[0] : nullptr);
546     napi_value result = nullptr;
547     std::shared_ptr<NapiAsyncTask> napiAsyncTask = CreateEmptyAsyncTask(env, lastParam, &result);
548     auto asyncTask = [extWindow = extensionWindow_, env, task = napiAsyncTask]() {
549         if (extWindow == nullptr) {
550             TLOGNE(WmsLogTag::WMS_UIEXT, "extensionWindow is null");
551             task->Reject(env, CreateJsError(env,
552                 static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY)));
553             return;
554         }
555         sptr<Window> windowImpl = extWindow->GetWindow();
556         if (windowImpl == nullptr) {
557             TLOGNE(WmsLogTag::WMS_UIEXT, "window is nullptr");
558             task->Reject(env, CreateJsError(env,
559                 static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY)));
560             return;
561         }
562         WMError ret = windowImpl->Show(0, false);
563         if (ret == WMError::WM_OK) {
564             task->Resolve(env, NapiGetUndefined(env));
565         } else {
566             task->Reject(env, CreateJsError(env,
567                 static_cast<int32_t>(WM_JS_TO_ERROR_CODE_MAP.at(ret)), "Window show failed"));
568         }
569         TLOGNI(WmsLogTag::WMS_UIEXT, "Window [%{public}u, %{public}s] show end, ret=%{public}d",
570             windowImpl->GetWindowId(), windowImpl->GetWindowName().c_str(), ret);
571     };
572     if (napi_status::napi_ok != napi_send_event(env, asyncTask, napi_eprio_high)) {
573         napiAsyncTask->Reject(env, CreateJsError(env,
574             static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY), "send event failed"));
575     }
576     return result;
577 }
578 
OnSetUIContent(napi_env env,napi_callback_info info)579 napi_value JsExtensionWindow::OnSetUIContent(napi_env env, napi_callback_info info)
580 {
581     WmErrorCode errCode = WmErrorCode::WM_OK;
582     size_t argc = 4;
583     napi_value argv[4] = {nullptr};
584     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
585     if (argc < 1) { // 2 maximum param num
586         TLOGE(WmsLogTag::WMS_UIEXT, "Argc is invalid: %{public}zu", argc);
587         errCode = WmErrorCode::WM_ERROR_INVALID_PARAM;
588     }
589     std::string contextUrl;
590     if (errCode == WmErrorCode::WM_OK && !ConvertFromJsValue(env, argv[0], contextUrl)) {
591         TLOGE(WmsLogTag::WMS_UIEXT, "Failed to convert parameter to context url");
592         errCode = WmErrorCode::WM_ERROR_INVALID_PARAM;
593     }
594     napi_value lastParam = nullptr;
595     if (argc >= 2) { // 2 param num
596         lastParam = argv[1];
597     }
598     std::shared_ptr<NativeReference> contentStorage = nullptr;
599     if (errCode == WmErrorCode::WM_ERROR_INVALID_PARAM) {
600         return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
601     }
602 
603     sptr<IRemoteObject> parentToken = sessionInfo_->parentToken;
604     napi_value result = nullptr;
605     std::shared_ptr<NapiAsyncTask> napiAsyncTask = CreateEmptyAsyncTask(env, lastParam, &result);
606     auto asyncTask = [extWindow = extensionWindow_, contentStorage, contextUrl, parentToken,
607         env, task = napiAsyncTask]() {
608         if (extWindow == nullptr) {
609             TLOGNE(WmsLogTag::WMS_UIEXT, "Window is nullptr");
610             task->Reject(env,
611                 CreateJsError(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY)));
612             return;
613         }
614         LoadContentTask(contentStorage, contextUrl, extWindow, env, *task, parentToken, false);
615     };
616     if (napi_status::napi_ok != napi_send_event(env, asyncTask, napi_eprio_high)) {
617         napiAsyncTask->Reject(env, CreateJsError(env,
618             static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY), "send event failed"));
619     }
620     return result;
621 }
622 
OnLoadContent(napi_env env,napi_callback_info info,bool isLoadedByName)623 napi_value JsExtensionWindow::OnLoadContent(napi_env env, napi_callback_info info, bool isLoadedByName)
624 {
625     TLOGI(WmsLogTag::WMS_UIEXT, "OnLoadContent is called");
626     WmErrorCode errCode = WmErrorCode::WM_OK;
627     size_t argc = 4;
628     napi_value argv[4] = {nullptr};
629     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
630     std::string contextUrl;
631     if (!ConvertFromJsValue(env, argv[0], contextUrl)) {
632         TLOGI(WmsLogTag::WMS_UIEXT, "Failed to convert parameter to context url");
633         errCode = WmErrorCode::WM_ERROR_INVALID_PARAM;
634     }
635     napi_value storage = nullptr;
636     napi_value lastParam = nullptr;
637     napi_value value1 = argv[1];
638     napi_value value2 = argv[2];
639     if (GetType(env, value1) == napi_function) {
640         lastParam = value1;
641     } else if (GetType(env, value1) == napi_object) {
642         storage = value1;
643     }
644     if (GetType(env, value2) == napi_function) {
645         lastParam = value2;
646     }
647     if (errCode == WmErrorCode::WM_ERROR_INVALID_PARAM) {
648         TLOGI(WmsLogTag::WMS_UIEXT, "Invalid param");
649         napi_throw(env, CreateJsError(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_INVALID_PARAM)));
650         return NapiGetUndefined(env);
651     }
652 
653     std::shared_ptr<NativeReference> contentStorage = nullptr;
654     if (storage != nullptr) {
655         napi_ref result = nullptr;
656         napi_create_reference(env, storage, 1, &result);
657         contentStorage = std::shared_ptr<NativeReference>(reinterpret_cast<NativeReference*>(result));
658     }
659 
660     sptr<IRemoteObject> parentToken = sessionInfo_->parentToken;
661     napi_value result = nullptr;
662     std::shared_ptr<NapiAsyncTask> napiAsyncTask = CreateEmptyAsyncTask(env, lastParam, &result);
663     auto asyncTask = [extWindow = extensionWindow_, contentStorage, contextUrl, parentToken, isLoadedByName,
664         env, task = napiAsyncTask]() {
665         if (extWindow == nullptr) {
666             TLOGNE(WmsLogTag::WMS_UIEXT, "Window is nullptr");
667             task->Reject(env, CreateJsError(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY)));
668             return;
669         }
670         LoadContentTask(contentStorage, contextUrl, extWindow, env, *task, parentToken, isLoadedByName);
671     };
672     if (napi_status::napi_ok != napi_send_event(env, asyncTask, napi_eprio_high)) {
673         napiAsyncTask->Reject(env, CreateJsError(env,
674             static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY), "send event failed"));
675     }
676     return result;
677 }
678 
OnGetWindowAvoidArea(napi_env env,napi_callback_info info)679 napi_value JsExtensionWindow::OnGetWindowAvoidArea(napi_env env, napi_callback_info info)
680 {
681     TLOGD(WmsLogTag::WMS_UIEXT, "OnGetWindowAvoidArea is called");
682 
683     WmErrorCode errCode = WmErrorCode::WM_OK;
684     size_t argc = 4;
685     napi_value argv[4] = {nullptr};
686     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
687     if (argc < 1) { // 1: params num
688         return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
689     }
690     AvoidAreaType avoidAreaType = AvoidAreaType::TYPE_SYSTEM;
691     napi_value nativeMode = argv[0];
692     if (nativeMode == nullptr) {
693         errCode = WmErrorCode::WM_ERROR_INVALID_PARAM;
694     } else {
695         uint32_t resultValue = 0;
696         napi_get_value_uint32(env, nativeMode, &resultValue);
697         avoidAreaType = static_cast<AvoidAreaType>(resultValue);
698         errCode = avoidAreaType >= AvoidAreaType::TYPE_END ?
699                   WmErrorCode::WM_ERROR_INVALID_PARAM : WmErrorCode::WM_OK;
700     }
701     if (errCode == WmErrorCode::WM_ERROR_INVALID_PARAM) {
702         return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
703     }
704 
705     if (extensionWindow_ == nullptr) {
706         TLOGE(WmsLogTag::WMS_UIEXT, "extensionWindow_ is nullptr");
707         napi_throw(env, CreateJsError(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_STAGE_ABNORMALLY)));
708         return CreateJsValue(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_STAGE_ABNORMALLY));
709     }
710     // getAvoidRect by avoidAreaType
711     AvoidArea avoidArea;
712     WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(extensionWindow_->GetAvoidAreaByType(avoidAreaType, avoidArea));
713     if (ret != WmErrorCode::WM_OK) {
714         TLOGE(WmsLogTag::WMS_UIEXT, "OnGetAvoidAreaByType failed");
715         avoidArea.topRect_ = g_emptyRect;
716         avoidArea.leftRect_ = g_emptyRect;
717         avoidArea.rightRect_ = g_emptyRect;
718         avoidArea.bottomRect_ = g_emptyRect;
719     }
720     napi_value avoidAreaObj = ConvertAvoidAreaToJsValue(env, avoidArea, avoidAreaType);
721     if (avoidAreaObj != nullptr) {
722         TLOGI(WmsLogTag::WMS_UIEXT, "avoidAreaObj is finish");
723         return avoidAreaObj;
724     } else {
725         TLOGE(WmsLogTag::WMS_UIEXT, "avoidAreaObj is nullptr");
726         return NapiThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY);
727     }
728 }
729 
OnRegisterRectChangeCallback(napi_env env,size_t argc,napi_value * argv,const sptr<Window> & windowImpl)730 napi_value JsExtensionWindow::OnRegisterRectChangeCallback(napi_env env, size_t argc, napi_value* argv,
731     const sptr<Window>& windowImpl)
732 {
733     if (argc < ARG_COUNT_THREE) {
734         TLOGE(WmsLogTag::WMS_UIEXT, "OnRectChange: argc is invalid: %{public}zu", argc);
735         return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
736     }
737     if (!windowImpl->IsPcWindow()) {
738         TLOGE(WmsLogTag::WMS_UIEXT, "Device is not PC");
739         return NapiThrowError(env, WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT);
740     }
741     uint32_t reasons = 0;
742     if (!ConvertFromJsValue(env, argv[INDEX_ONE], reasons)) {
743         TLOGE(WmsLogTag::WMS_UIEXT, "Failed to convert parameter to rectChangeReasons");
744         return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
745     }
746     if (reasons != static_cast<uint32_t>(ComponentRectChangeReason::HOST_WINDOW_RECT_CHANGE)) {
747         TLOGE(WmsLogTag::WMS_UIEXT, "Unsupported rect change reasons");
748         return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
749     }
750     napi_value cbValue = argv[INDEX_TWO];
751     if (!NapiIsCallable(env, cbValue)) {
752         TLOGE(WmsLogTag::WMS_UIEXT, "Callback(info->argv[2]) is not callable");
753         return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
754     }
755     WmErrorCode ret = extensionRegisterManager_->RegisterListener(windowImpl, RECT_CHANGE, CaseType::CASE_WINDOW,
756         env, cbValue);
757     if (ret != WmErrorCode::WM_OK) {
758         TLOGW(WmsLogTag::WMS_UIEXT, "Failed, window [%{public}u, %{public}s], type=%{public}s, reasons=%{public}u",
759             windowImpl->GetWindowId(), windowImpl->GetWindowName().c_str(), RECT_CHANGE.c_str(), reasons);
760         return NapiThrowError(env, ret);
761     }
762     TLOGI(WmsLogTag::WMS_UIEXT, "Success, window [%{public}u, %{public}s], type=%{public}s, reasons=%{public}u",
763         windowImpl->GetWindowId(), windowImpl->GetWindowName().c_str(), RECT_CHANGE.c_str(), reasons);
764     return NapiGetUndefined(env);
765 }
766 
OnRegisterExtensionWindowCallback(napi_env env,napi_callback_info info)767 napi_value JsExtensionWindow::OnRegisterExtensionWindowCallback(napi_env env, napi_callback_info info)
768 {
769     sptr<Window> windowImpl = extensionWindow_->GetWindow();
770     if (windowImpl == nullptr) {
771         TLOGE(WmsLogTag::WMS_UIEXT, "WindowImpl is nullptr");
772         return NapiThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY);
773     }
774     size_t argc = FOUR_PARAMS_SIZE;
775     napi_value argv[FOUR_PARAMS_SIZE] = {nullptr};
776     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
777     if (argc < ARG_COUNT_TWO) {
778         TLOGE(WmsLogTag::WMS_UIEXT, "Argc is invalid: %{public}zu", argc);
779         return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
780     }
781     std::string cbType;
782     if (!ConvertFromJsValue(env, argv[INDEX_ZERO], cbType)) {
783         TLOGE(WmsLogTag::WMS_UIEXT, "Failed to convert parameter to callbackType");
784         return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
785     }
786     if (cbType == RECT_CHANGE) {
787         return OnRegisterRectChangeCallback(env, argc, argv, windowImpl);
788     }
789     napi_value value = argv[INDEX_ONE];
790     if (!NapiIsCallable(env, value)) {
791         TLOGE(WmsLogTag::WMS_UIEXT, "Callback(info->argv[1]) is not callable");
792         return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
793     }
794     WmErrorCode ret = extensionRegisterManager_->RegisterListener(windowImpl, cbType, CaseType::CASE_WINDOW,
795         env, value);
796     if (ret != WmErrorCode::WM_OK) {
797         TLOGE(WmsLogTag::WMS_UIEXT, "Callback(info->argv[1]) is not callable");
798         return NapiThrowError(env, ret);
799     }
800     TLOGI(WmsLogTag::WMS_UIEXT, "Register end, window [%{public}u, %{public}s], type=%{public}s",
801           windowImpl->GetWindowId(), windowImpl->GetWindowName().c_str(), cbType.c_str());
802     return NapiGetUndefined(env);
803 }
804 
OnUnRegisterExtensionWindowCallback(napi_env env,napi_callback_info info)805 napi_value JsExtensionWindow::OnUnRegisterExtensionWindowCallback(napi_env env, napi_callback_info info)
806 {
807     sptr<Window> windowImpl = extensionWindow_->GetWindow();
808     if (windowImpl == nullptr) {
809         TLOGE(WmsLogTag::WMS_UIEXT, "windowImpl is nullptr");
810         return NapiThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY);
811     }
812     size_t argc = FOUR_PARAMS_SIZE;
813     napi_value argv[FOUR_PARAMS_SIZE] = {nullptr};
814     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
815     if (argc < ARG_COUNT_ONE) {
816         TLOGE(WmsLogTag::WMS_UIEXT, "Argc is invalid: %{public}zu", argc);
817         return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
818     }
819     std::string cbType;
820     if (!ConvertFromJsValue(env, argv[INDEX_ZERO], cbType)) {
821         TLOGE(WmsLogTag::WMS_UIEXT, "Failed to convert parameter to callbackType");
822         return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
823     }
824     if (cbType == RECT_CHANGE) {
825         if (!windowImpl->IsPcWindow()) {
826             TLOGE(WmsLogTag::WMS_UIEXT, "Device is not PC");
827             return NapiThrowError(env, WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT);
828         }
829     }
830 
831     napi_value value = nullptr;
832     WmErrorCode ret = WmErrorCode::WM_OK;
833     if (argc == ARG_COUNT_ONE) {
834         ret = extensionRegisterManager_->UnregisterListener(windowImpl, cbType, CaseType::CASE_WINDOW, env, value);
835     } else {
836         value = argv[INDEX_ONE];
837         if (value == nullptr || !NapiIsCallable(env, value)) {
838             ret = extensionRegisterManager_->UnregisterListener(windowImpl, cbType, CaseType::CASE_WINDOW,
839                 env, nullptr);
840         } else {
841             ret = extensionRegisterManager_->UnregisterListener(windowImpl, cbType, CaseType::CASE_WINDOW, env, value);
842         }
843     }
844 
845     if (ret != WmErrorCode::WM_OK) {
846         return NapiThrowError(env, ret);
847     }
848     TLOGI(WmsLogTag::WMS_UIEXT, "UnRegister end, window [%{public}u, %{public}s], type=%{public}s",
849           windowImpl->GetWindowId(), windowImpl->GetWindowName().c_str(), cbType.c_str());
850     return NapiGetUndefined(env);
851 }
852 
OnHideNonSecureWindows(napi_env env,napi_callback_info info)853 napi_value JsExtensionWindow::OnHideNonSecureWindows(napi_env env, napi_callback_info info)
854 {
855     if (extensionWindow_ == nullptr) {
856         TLOGE(WmsLogTag::WMS_UIEXT, "extensionWindow_ is nullptr");
857         return NapiThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY);
858     }
859     sptr<Window> windowImpl = extensionWindow_->GetWindow();
860     if (windowImpl == nullptr) {
861         TLOGE(WmsLogTag::WMS_UIEXT, "windowImpl is nullptr");
862         return NapiThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY);
863     }
864     size_t argc = 4;
865     napi_value argv[4] = {nullptr};
866     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
867     if (argc < 1) {
868         TLOGE(WmsLogTag::WMS_UIEXT, "Argc is invalid: %{public}zu", argc);
869         return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
870     }
871     bool shouldHide = false;
872     if (!ConvertFromJsValue(env, argv[0], shouldHide)) {
873         TLOGE(WmsLogTag::WMS_UIEXT, "Failed to convert parameter to bool");
874         return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
875     }
876 
877     WmErrorCode ret = WmErrorCode::WM_OK;
878     ret = WM_JS_TO_ERROR_CODE_MAP.at(extensionWindow_->HideNonSecureWindows(shouldHide));
879     if (ret != WmErrorCode::WM_OK) {
880         return NapiThrowError(env, ret);
881     }
882     TLOGI(WmsLogTag::WMS_UIEXT, "end, window [%{public}u, %{public}s], shouldHide:%{public}u",
883           windowImpl->GetWindowId(), windowImpl->GetWindowName().c_str(), shouldHide);
884     return NapiGetUndefined(env);
885 }
886 
OnSetWaterMarkFlag(napi_env env,napi_callback_info info)887 napi_value JsExtensionWindow::OnSetWaterMarkFlag(napi_env env, napi_callback_info info)
888 {
889     if (extensionWindow_ == nullptr) {
890         TLOGE(WmsLogTag::WMS_UIEXT, "extensionWindow_ is nullptr");
891         return NapiThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY);
892     }
893     sptr<Window> windowImpl = extensionWindow_->GetWindow();
894     if (windowImpl == nullptr) {
895         TLOGE(WmsLogTag::WMS_UIEXT, "windowImpl is nullptr");
896         return NapiThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY);
897     }
898     size_t argc = 4;
899     napi_value argv[4] = {nullptr};
900     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
901     if (argc < 1) {
902         TLOGE(WmsLogTag::WMS_UIEXT, "Argc is invalid: %{public}zu", argc);
903         return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
904     }
905     bool isEnable = false;
906     if (!ConvertFromJsValue(env, argv[0], isEnable)) {
907         TLOGE(WmsLogTag::WMS_UIEXT, "Failed to convert parameter to bool");
908         return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
909     }
910 
911     WmErrorCode ret = WmErrorCode::WM_OK;
912     ret = WM_JS_TO_ERROR_CODE_MAP.at(extensionWindow_->SetWaterMarkFlag(isEnable));
913     if (ret != WmErrorCode::WM_OK) {
914         return NapiThrowError(env, ret);
915     }
916     TLOGI(WmsLogTag::WMS_UIEXT, "end, window [%{public}u, %{public}s], isEnable:%{public}u.",
917           windowImpl->GetWindowId(), windowImpl->GetWindowName().c_str(), isEnable);
918     return NapiGetUndefined(env);
919 }
920 
OnHidePrivacyContentForHost(napi_env env,napi_callback_info info)921 napi_value JsExtensionWindow::OnHidePrivacyContentForHost(napi_env env, napi_callback_info info)
922 {
923     if (extensionWindow_ == nullptr) {
924         TLOGE(WmsLogTag::WMS_UIEXT, "extension window is nullptr");
925         return NapiThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY);
926     }
927 
928     sptr<Window> windowImpl = extensionWindow_->GetWindow();
929     if (windowImpl == nullptr) {
930         TLOGE(WmsLogTag::WMS_UIEXT, "windowImpl is nullptr");
931         return NapiThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY);
932     }
933 
934     size_t argc = 4;
935     napi_value argv[4] = {nullptr};
936     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
937     if (argc < 1) {
938         TLOGE(WmsLogTag::WMS_UIEXT, "Argc is invalid: %{public}zu", argc);
939         return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
940     }
941 
942     bool needHide = false;
943     if (!ConvertFromJsValue(env, argv[0], needHide)) {
944         TLOGE(WmsLogTag::WMS_UIEXT, "Failed to convert parameter to bool");
945         return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
946     }
947 
948     auto ret = WM_JS_TO_ERROR_CODE_MAP.at(extensionWindow_->HidePrivacyContentForHost(needHide));
949     if (ret != WmErrorCode::WM_OK) {
950         return NapiThrowError(env, ret);
951     }
952 
953     TLOGI(WmsLogTag::WMS_UIEXT, "finished, window [%{public}u, %{public}s], needHide:%{public}u.",
954           windowImpl->GetWindowId(), windowImpl->GetWindowName().c_str(), needHide);
955 
956     return NapiGetUndefined(env);
957 }
958 
GetProperties(napi_env env,napi_callback_info info)959 napi_value JsExtensionWindow::GetProperties(napi_env env, napi_callback_info info)
960 {
961     TLOGI(WmsLogTag::WMS_UIEXT, "in");
962     napi_value jsThis;
963     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &jsThis, nullptr));
964 
965     JsExtensionWindow* jsExtensionWindow = nullptr;
966     NAPI_CALL(env, napi_unwrap(env, jsThis, reinterpret_cast<void**>(&jsExtensionWindow)));
967     if (!jsExtensionWindow || !jsExtensionWindow->extensionWindow_) {
968         TLOGE(WmsLogTag::WMS_UIEXT, "window is nullptr");
969         return nullptr;
970     }
971     sptr<Rosen::Window> window = jsExtensionWindow->extensionWindow_->GetWindow();
972     return CreateJsExtensionWindowPropertiesObject(env, window);
973 }
974 
OnCreateSubWindowWithOptions(napi_env env,napi_callback_info info)975 napi_value JsExtensionWindow::OnCreateSubWindowWithOptions(napi_env env, napi_callback_info info)
976 {
977     if (extensionWindow_ == nullptr) {
978         TLOGE(WmsLogTag::WMS_UIEXT, "extensionWindow is null");
979         napi_throw(env, CreateJsError(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY)));
980         return NapiGetUndefined(env);
981     }
982     size_t argc = 4;
983     napi_value argv[4] = {nullptr};
984     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
985     std::string windowName;
986     if (!ConvertFromJsValue(env, argv[0], windowName)) {
987         TLOGE(WmsLogTag::WMS_UIEXT, "Failed to convert parameter to windowName");
988         napi_throw(env, CreateJsError(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_INVALID_PARAM)));
989         return NapiGetUndefined(env);
990     }
991     sptr<WindowOption> option = new WindowOption();
992     if (!ParseSubWindowOptions(env, argv[1], option)) {
993         TLOGE(WmsLogTag::WMS_UIEXT, "Get invalid options param");
994         napi_throw(env, CreateJsError(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_INVALID_PARAM)));
995         return NapiGetUndefined(env);
996     }
997     if ((option->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_APPLICATION_MODAL)) &&
998         !extensionWindow_->IsPcOrPadFreeMultiWindowMode()) {
999         TLOGE(WmsLogTag::WMS_SUB, "device not support");
1000         napi_throw(env, CreateJsError(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT)));
1001         return NapiGetUndefined(env);
1002     }
1003     if (option->GetWindowTopmost() && !Permission::IsSystemCalling() && !Permission::IsStartByHdcd()) {
1004         TLOGE(WmsLogTag::WMS_SUB, "Modal subwindow has topmost, but no system permission");
1005         napi_throw(env, CreateJsError(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_NOT_SYSTEM_APP)));
1006         return NapiGetUndefined(env);
1007     }
1008     option->SetParentId(hostWindowId_);
1009     const char* const where = __func__;
1010     napi_value lastParam = (argv[2] != nullptr && GetType(env, argv[2]) == napi_function) ? argv[2] : nullptr;
1011     napi_value result = nullptr;
1012     std::shared_ptr<NapiAsyncTask> napiAsyncTask = CreateEmptyAsyncTask(env, lastParam, &result);
1013     auto asyncTask = [where, extensionWindow = extensionWindow_, windowName = std::move(windowName),
1014         windowOption = option, env, task = napiAsyncTask]() mutable {
1015         auto extWindow = extensionWindow->GetWindow();
1016         if (extWindow == nullptr) {
1017             task->Reject(env, CreateJsError(env,
1018                 static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY), "extension's window is null"));
1019             return;
1020         }
1021         windowOption->SetWindowType(Rosen::WindowType::WINDOW_TYPE_APP_SUB_WINDOW);
1022         windowOption->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_FLOATING);
1023         windowOption->SetOnlySupportSceneBoard(true);
1024         windowOption->SetIsUIExtFirstSubWindow(true);
1025         auto window = Window::Create(windowName, windowOption, extWindow->GetContext());
1026         if (window == nullptr) {
1027             task->Reject(env, CreateJsError(env,
1028                 static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY), "create sub window failed"));
1029             return;
1030         }
1031         if (!window->IsTopmost()) {
1032             extWindow->NotifyModalUIExtensionMayBeCovered(false);
1033         }
1034         task->Resolve(env, CreateJsWindowObject(env, window));
1035         TLOGNI(WmsLogTag::WMS_UIEXT, "%{public}s %{public}s end", where, windowName.c_str());
1036     };
1037     if (napi_status::napi_ok != napi_send_event(env, asyncTask, napi_eprio_high)) {
1038         napiAsyncTask->Reject(env, CreateJsError(env,
1039             static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY), "send event failed"));
1040     }
1041     return result;
1042 }
1043 
OnOccupyEvents(napi_env env,napi_callback_info info)1044 napi_value JsExtensionWindow::OnOccupyEvents(napi_env env, napi_callback_info info)
1045 {
1046     size_t argc = FOUR_PARAMS_SIZE;
1047     napi_value argv[FOUR_PARAMS_SIZE] = {nullptr};
1048     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
1049     napi_value lastParam = (argc <= 1) ? nullptr :
1050         (GetType(env, argv[1]) == napi_function ? argv[1] : nullptr);
1051     napi_value result = nullptr;
1052     std::shared_ptr<NapiAsyncTask> napiAsyncTask = CreateEmptyAsyncTask(env, lastParam, &result);
1053     if (argc < 1) {
1054         TLOGE(WmsLogTag::WMS_UIEXT, "Argc is invalid: %{public}zu", argc);
1055         napiAsyncTask->Reject(env, CreateJsError(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_INVALID_PARAM),
1056             "invalid param"));
1057         return result;
1058     }
1059     int32_t eventFlags = 0;
1060     if (!ConvertFromJsValue(env, argv[0], eventFlags)) {
1061         TLOGE(WmsLogTag::WMS_UIEXT, "Failed to convert parameter to int32_t");
1062         napiAsyncTask->Reject(env, CreateJsError(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_INVALID_PARAM),
1063             "invalid param"));
1064         return result;
1065     }
1066     auto asyncTask = [weakToken = std::weak_ptr<ExtensionWindow>(extensionWindow_), eventFlags, env,
1067         task = napiAsyncTask] {
1068         auto weakWindow = weakToken.lock();
1069         if (weakWindow == nullptr) {
1070             TLOGNE(WmsLogTag::WMS_UIEXT, "window is nullptr");
1071             task->Reject(env, CreateJsError(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY),
1072                 "OnOccupyEvents failed"));
1073             return;
1074         }
1075         auto ret = WM_JS_TO_ERROR_CODE_MAP.at(weakWindow->OccupyEvents(eventFlags));
1076         if (ret == WmErrorCode::WM_OK) {
1077             task->Resolve(env, NapiGetUndefined(env));
1078         } else {
1079             TLOGNE(WmsLogTag::WMS_UIEXT, "OnOccupyEvents failed, code: %{public}d", ret);
1080             task->Reject(env, CreateJsError(env, static_cast<int32_t>(ret), "OnOccupyEvents failed"));
1081         }
1082     };
1083     if (napi_status::napi_ok != napi_send_event(env, asyncTask, napi_eprio_high)) {
1084         TLOGE(WmsLogTag::WMS_UIEXT, "napi_send_event failed");
1085         napiAsyncTask->Reject(env,
1086             CreateJsError(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_STATE_ABNORMALLY), "failed to send event"));
1087     }
1088     return result;
1089 }
1090 
1091 }  // namespace Rosen
1092 }  // namespace OHOS