• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "js_extension_window.h"
17 
18 #include "js_extension_window_utils.h"
19 #include "js_runtime_utils.h"
20 #include "js_window_utils.h"
21 #include "window_manager_hilog.h"
22 #include "wm_common.h"
23 #include "extension_window.h"
24 
25 namespace OHOS {
26 namespace Rosen {
27 using namespace AbilityRuntime;
28 namespace {
29 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "JsExtensionWindow"};
30 constexpr Rect g_emptyRect = {0, 0, 0, 0};
31 } // namespace
32 
JsExtensionWindow(const std::shared_ptr<Rosen::ExtensionWindow> extensionWindow)33 JsExtensionWindow::JsExtensionWindow(const std::shared_ptr<Rosen::ExtensionWindow> extensionWindow)
34     : extensionWindow_(extensionWindow),
35     extensionRegisterManager_(std::make_unique<JsExtensionWindowRegisterManager>()) {
36 }
37 
~JsExtensionWindow()38 JsExtensionWindow::~JsExtensionWindow() {}
39 
CreateJsExtensionWindow(napi_env env,sptr<Rosen::Window> window)40 napi_value JsExtensionWindow::CreateJsExtensionWindow(napi_env env, sptr<Rosen::Window> window)
41 {
42     WLOGI("JsExtensionWindow CreateJsExtensionWindow");
43     napi_value objValue = nullptr;
44     napi_create_object(env, &objValue);
45 
46     if (env == nullptr || window == nullptr) {
47         WLOGFE("JsExtensionWindow env or window is nullptr");
48         return nullptr;
49     }
50 
51     std::shared_ptr<ExtensionWindow> extensionWindow = std::make_shared<ExtensionWindowImpl>(window);
52     std::unique_ptr<JsExtensionWindow> jsExtensionWindow = std::make_unique<JsExtensionWindow>(extensionWindow);
53     napi_wrap(env, objValue, jsExtensionWindow.release(), JsExtensionWindow::Finalizer, nullptr, nullptr);
54 
55     napi_property_descriptor desc[] = {
56         DECLARE_NAPI_GETTER("properties", JsExtensionWindow::GetProperties)
57     };
58     NAPI_CALL(env, napi_define_properties(env, objValue, sizeof(desc) / sizeof(desc[0]), desc));
59 
60     const char *moduleName = "JsExtensionWindow";
61     BindNativeFunction(env, objValue, "getWindowAvoidArea", moduleName, JsExtensionWindow::GetWindowAvoidArea);
62     BindNativeFunction(env, objValue, "on", moduleName, JsExtensionWindow::RegisterExtensionWindowCallback);
63     BindNativeFunction(env, objValue, "off", moduleName, JsExtensionWindow::UnRegisterExtensionWindowCallback);
64     BindNativeFunction(env, objValue, "hideNonSecureWindows", moduleName, JsExtensionWindow::HideNonSecureWindows);
65 
66     return objValue;
67 }
68 
Finalizer(napi_env env,void * data,void * hint)69 void JsExtensionWindow::Finalizer(napi_env env, void* data, void* hint)
70 {
71     WLOGI("Finalizer is called");
72     std::unique_ptr<JsExtensionWindow>(static_cast<JsExtensionWindow*>(data));
73 }
74 
GetWindowAvoidArea(napi_env env,napi_callback_info info)75 napi_value JsExtensionWindow::GetWindowAvoidArea(napi_env env, napi_callback_info info)
76 {
77     WLOGI("GetWindowAvoidArea is called");
78     JsExtensionWindow* me = CheckParamsAndGetThis<JsExtensionWindow>(env, info);
79     return (me != nullptr) ? me->OnGetWindowAvoidArea(env, info) : nullptr;
80 }
81 
RegisterExtensionWindowCallback(napi_env env,napi_callback_info info)82 napi_value JsExtensionWindow::RegisterExtensionWindowCallback(napi_env env, napi_callback_info info)
83 {
84     WLOGI("RegisterExtensionWindowCallback is called");
85     JsExtensionWindow* me = CheckParamsAndGetThis<JsExtensionWindow>(env, info);
86     return (me != nullptr) ? me->OnRegisterExtensionWindowCallback(env, info) : nullptr;
87 }
88 
UnRegisterExtensionWindowCallback(napi_env env,napi_callback_info info)89 napi_value JsExtensionWindow::UnRegisterExtensionWindowCallback(napi_env env, napi_callback_info info)
90 {
91     WLOGI("UnRegisterExtensionWindowCallback is called");
92     JsExtensionWindow* me = CheckParamsAndGetThis<JsExtensionWindow>(env, info);
93     return (me != nullptr) ? me->OnUnRegisterExtensionWindowCallback(env, info) : nullptr;
94 }
95 
HideNonSecureWindows(napi_env env,napi_callback_info info)96 napi_value JsExtensionWindow::HideNonSecureWindows(napi_env env, napi_callback_info info)
97 {
98     WLOGI("HideNonSecureWindows is called");
99     JsExtensionWindow* me = CheckParamsAndGetThis<JsExtensionWindow>(env, info);
100     return (me != nullptr) ? me->OnHideNonSecureWindows(env, info) : nullptr;
101 }
102 
OnGetWindowAvoidArea(napi_env env,napi_callback_info info)103 napi_value JsExtensionWindow::OnGetWindowAvoidArea(napi_env env, napi_callback_info info)
104 {
105     WLOGI("OnGetWindowAvoidArea is called");
106 
107     WmErrorCode errCode = WmErrorCode::WM_OK;
108     size_t argc = 4;
109     napi_value argv[4] = {nullptr};
110     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
111     if (argc < 1) { // 1: params num
112         return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
113     }
114     AvoidAreaType avoidAreaType = AvoidAreaType::TYPE_SYSTEM;
115     napi_value nativeMode = argv[0];
116     if (nativeMode == nullptr) {
117         errCode = WmErrorCode::WM_ERROR_INVALID_PARAM;
118     } else {
119         uint32_t resultValue = 0;
120         napi_get_value_uint32(env, nativeMode, &resultValue);
121         avoidAreaType = static_cast<AvoidAreaType>(resultValue);
122         errCode = ((avoidAreaType > AvoidAreaType::TYPE_NAVIGATION_INDICATOR) ||
123                    (avoidAreaType < AvoidAreaType::TYPE_SYSTEM)) ?
124                   WmErrorCode::WM_ERROR_INVALID_PARAM : WmErrorCode::WM_OK;
125     }
126     if (errCode == WmErrorCode::WM_ERROR_INVALID_PARAM) {
127         return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
128     }
129 
130     if (extensionWindow_ == nullptr) {
131         WLOGFE("extensionWindow_ is nullptr");
132         napi_throw(env, CreateJsError(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_STAGE_ABNORMALLY)));
133         return CreateJsValue(env, static_cast<int32_t>(WmErrorCode::WM_ERROR_STAGE_ABNORMALLY));
134     }
135     // getAvoidRect by avoidAreaType
136     AvoidArea avoidArea;
137     WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(extensionWindow_->GetAvoidAreaByType(avoidAreaType, avoidArea));
138     if (ret != WmErrorCode::WM_OK) {
139         WLOGFE("OnGetAvoidAreaByType failed");
140         avoidArea.topRect_ = g_emptyRect;
141         avoidArea.leftRect_ = g_emptyRect;
142         avoidArea.rightRect_ = g_emptyRect;
143         avoidArea.bottomRect_ = g_emptyRect;
144     }
145     napi_value avoidAreaObj = ConvertAvoidAreaToJsValue(env, avoidArea, avoidAreaType);
146     if (avoidAreaObj != nullptr) {
147         WLOGI("avoidAreaObj is finish");
148         return avoidAreaObj;
149     } else {
150         WLOGFE("avoidAreaObj is nullptr");
151         return NapiThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY);
152     }
153 }
154 
OnRegisterExtensionWindowCallback(napi_env env,napi_callback_info info)155 napi_value JsExtensionWindow::OnRegisterExtensionWindowCallback(napi_env env, napi_callback_info info)
156 {
157     sptr<Window> windowImpl = extensionWindow_->GetWindow();
158     if (windowImpl == nullptr) {
159         WLOGFE("WindowImpl is nullptr");
160         return NapiThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY);
161     }
162     size_t argc = 4;
163     napi_value argv[4] = {nullptr};
164     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
165     if (argc < 2) { // 2: params num
166         WLOGFE("Argc is invalid: %{public}zu", argc);
167         return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
168     }
169     std::string cbType;
170     if (!ConvertFromJsValue(env, argv[0], cbType)) {
171         WLOGFE("Failed to convert parameter to callbackType");
172         return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
173     }
174     napi_value value = argv[1];
175     if (!NapiIsCallable(env, value)) {
176         WLOGFE("Callback(info->argv[1]) is not callable");
177         return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
178     }
179     WmErrorCode ret = extensionRegisterManager_->RegisterListener(windowImpl, cbType, CaseType::CASE_WINDOW,
180         env, value);
181     if (ret != WmErrorCode::WM_OK) {
182         WLOGFE("Callback(info->argv[1]) is not callable");
183         return NapiThrowError(env, ret);
184     }
185     WLOGI("Register end, window [%{public}u, %{public}s], type = %{public}s",
186           windowImpl->GetWindowId(), windowImpl->GetWindowName().c_str(), cbType.c_str());
187     return NapiGetUndefined(env);
188 }
189 
OnUnRegisterExtensionWindowCallback(napi_env env,napi_callback_info info)190 napi_value JsExtensionWindow::OnUnRegisterExtensionWindowCallback(napi_env env, napi_callback_info info)
191 {
192     sptr<Window> windowImpl = extensionWindow_->GetWindow();
193     if (windowImpl == nullptr) {
194         WLOGFE("windowImpl is nullptr");
195         return NapiThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY);
196     }
197     size_t argc = 4;
198     napi_value argv[4] = {nullptr};
199     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
200     if (argc < 1) {
201         WLOGFE("Argc is invalid: %{public}zu", argc);
202         return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
203     }
204     std::string cbType;
205     if (!ConvertFromJsValue(env, argv[0], cbType)) {
206         WLOGFE("Failed to convert parameter to callbackType");
207         return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
208     }
209 
210     napi_value value = nullptr;
211     WmErrorCode ret = WmErrorCode::WM_OK;
212     if (argc == 1) {
213         ret = extensionRegisterManager_->UnregisterListener(windowImpl, cbType, CaseType::CASE_WINDOW, env, value);
214     } else {
215         value = argv[1];
216         if (value == nullptr || !NapiIsCallable(env, value)) {
217             ret = extensionRegisterManager_->UnregisterListener(windowImpl, cbType, CaseType::CASE_WINDOW,
218                 env, nullptr);
219         } else {
220             ret = extensionRegisterManager_->UnregisterListener(windowImpl, cbType, CaseType::CASE_WINDOW, env, value);
221         }
222     }
223 
224     if (ret != WmErrorCode::WM_OK) {
225         return NapiThrowError(env, ret);
226     }
227     WLOGI("UnRegister end, window [%{public}u, %{public}s], type = %{public}s",
228           windowImpl->GetWindowId(), windowImpl->GetWindowName().c_str(), cbType.c_str());
229     return NapiGetUndefined(env);
230 }
231 
OnHideNonSecureWindows(napi_env env,napi_callback_info info)232 napi_value JsExtensionWindow::OnHideNonSecureWindows(napi_env env, napi_callback_info info)
233 {
234     if (extensionWindow_ == nullptr) {
235         WLOGFE("extensionWindow_ is nullptr");
236         return NapiThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY);
237     }
238     sptr<Window> windowImpl = extensionWindow_->GetWindow();
239     if (windowImpl == nullptr) {
240         WLOGFE("windowImpl is nullptr");
241         return NapiThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY);
242     }
243     size_t argc = 4;
244     napi_value argv[4] = {nullptr};
245     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
246     if (argc < 1) {
247         WLOGFE("Argc is invalid: %{public}zu", argc);
248         return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
249     }
250     bool shouldHide = false;
251     if (!ConvertFromJsValue(env, argv[0], shouldHide)) {
252         WLOGFE("Failed to convert parameter to bool");
253         return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM);
254     }
255 
256     WmErrorCode ret = WmErrorCode::WM_OK;
257     ret = WM_JS_TO_ERROR_CODE_MAP.at(extensionWindow_->HideNonSecureWindows(shouldHide));
258     if (ret != WmErrorCode::WM_OK) {
259         return NapiThrowError(env, ret);
260     }
261     WLOGI("OnHideNonSecureWindows end, window [%{public}u, %{public}s], shouldHide:%{public}u",
262           windowImpl->GetWindowId(), windowImpl->GetWindowName().c_str(), shouldHide);
263     return NapiGetUndefined(env);
264 }
265 
GetProperties(napi_env env,napi_callback_info info)266 napi_value JsExtensionWindow::GetProperties(napi_env env, napi_callback_info info)
267 {
268     WLOGI("GetProperties is called");
269     napi_value jsThis;
270     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &jsThis, nullptr));
271 
272     JsExtensionWindow* jsExtensionWindow = nullptr;
273     NAPI_CALL(env, napi_unwrap(env, jsThis, reinterpret_cast<void**>(&jsExtensionWindow)));
274     if (!jsExtensionWindow || !jsExtensionWindow->extensionWindow_) {
275         WLOGFE("window is nullptr");
276         return nullptr;
277     }
278     sptr<Rosen::Window> window = jsExtensionWindow->extensionWindow_->GetWindow();
279     return CreateJsExtensionWindowPropertiesObject(env, window);
280 }
281 }  // namespace Rosen
282 }  // namespace OHOS
283