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