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