1 /*
2 * Copyright (c) 2024 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 #include "js_err_utils.h"
16 #include "js_window_manager.h"
17 #include "js_window.h"
18 #include "js_window_utils.h"
19 #include "window_helper.h"
20 #include "window_manager_hilog.h"
21 #include "window_option.h"
22 namespace OHOS {
23 namespace Rosen {
24 using namespace AbilityRuntime;
25 namespace {
26 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "JsWindowManager"};
27 const std::string PIP_WINDOW = "pip_window";
28 }
29
JsWindowManager()30 JsWindowManager::JsWindowManager() : registerManager_(std::make_unique<JsWindowRegisterManager>())
31 {
32 }
33
~JsWindowManager()34 JsWindowManager::~JsWindowManager()
35 {
36 }
37
Finalizer(napi_env env,void * data,void * hint)38 void JsWindowManager::Finalizer(napi_env env, void* data, void* hint)
39 {
40 WLOGI("Finalizer");
41 std::unique_ptr<JsWindowManager>(static_cast<JsWindowManager*>(data));
42 }
43
Create(napi_env env,napi_callback_info info)44 napi_value JsWindowManager::Create(napi_env env, napi_callback_info info)
45 {
46 WLOGI("mock: Create");
47 return nullptr;
48 }
49
CreateWindowNapi(napi_env env,napi_callback_info info)50 napi_value JsWindowManager::CreateWindowNapi(napi_env env, napi_callback_info info)
51 {
52 WLOGI("mock: CreateWindowNapi");
53 return nullptr;
54 }
55
FindWindow(napi_env env,napi_callback_info info)56 napi_value JsWindowManager::FindWindow(napi_env env, napi_callback_info info)
57 {
58 WLOGI("mock: FindWindow");
59 return nullptr;
60 }
61
FindWindowSync(napi_env env,napi_callback_info info)62 napi_value JsWindowManager::FindWindowSync(napi_env env, napi_callback_info info)
63 {
64 WLOGI("mock: FindWindowSync");
65 return nullptr;
66 }
67
RegisterWindowManagerCallback(napi_env env,napi_callback_info info)68 napi_value JsWindowManager::RegisterWindowManagerCallback(napi_env env, napi_callback_info info)
69 {
70 WLOGI("mock: RegisterWindowManagerCallback");
71 return nullptr;
72 }
73
UnregisterWindowMangerCallback(napi_env env,napi_callback_info info)74 napi_value JsWindowManager::UnregisterWindowMangerCallback(napi_env env, napi_callback_info info)
75 {
76 WLOGI("mock: UnregisterWindowMangerCallback");
77 return nullptr;
78 }
79
GetTopWindow(napi_env env,napi_callback_info info)80 napi_value JsWindowManager::GetTopWindow(napi_env env, napi_callback_info info)
81 {
82 WLOGI("mock: GetTopWindow");
83 return nullptr;
84 }
85
86 /** @note @window.hierarchy */
GetLastWindow(napi_env env,napi_callback_info info)87 napi_value JsWindowManager::GetLastWindow(napi_env env, napi_callback_info info)
88 {
89 WLOGI("GetLastWindow");
90 JsWindowManager* me = CheckParamsAndGetThis<JsWindowManager>(env, info);
91 return (me != nullptr) ? me->OnGetLastWindow(env, info) : nullptr;
92 }
93
MinimizeAll(napi_env env,napi_callback_info info)94 napi_value JsWindowManager::MinimizeAll(napi_env env, napi_callback_info info)
95 {
96 WLOGI("mock: MinimizeAll");
97 return nullptr;
98 }
99
ToggleShownStateForAllAppWindows(napi_env env,napi_callback_info info)100 napi_value JsWindowManager::ToggleShownStateForAllAppWindows(napi_env env, napi_callback_info info)
101 {
102 WLOGI("mock: ToggleShownStateForAllAppWindows");
103 return nullptr;
104 }
105
GetAllWindowLayoutInfo(napi_env env,napi_callback_info info)106 napi_value JsWindowManager::GetAllWindowLayoutInfo(napi_env env, napi_callback_info info)
107 {
108 TLOGI(WmsLogTag::WMS_ATTRIBUTE, "mock");
109 return nullptr;
110 }
111
SetWindowLayoutMode(napi_env env,napi_callback_info info)112 napi_value JsWindowManager::SetWindowLayoutMode(napi_env env, napi_callback_info info)
113 {
114 WLOGI("mock: SetWindowLayoutMode");
115 return nullptr;
116 }
117
SetGestureNavigationEnabled(napi_env env,napi_callback_info info)118 napi_value JsWindowManager::SetGestureNavigationEnabled(napi_env env, napi_callback_info info)
119 {
120 WLOGI("mock: SetGestureNavigationEnabled");
121 return nullptr;
122 }
123
SetWaterMarkImage(napi_env env,napi_callback_info info)124 napi_value JsWindowManager::SetWaterMarkImage(napi_env env, napi_callback_info info)
125 {
126 WLOGI("mock: SetWaterMarkImage");
127 return nullptr;
128 }
129
ShiftAppWindowFocus(napi_env env,napi_callback_info info)130 napi_value JsWindowManager::ShiftAppWindowFocus(napi_env env, napi_callback_info info)
131 {
132 WLOGI("mock: ShiftAppWindowFocus");
133 return nullptr;
134 }
135
GetNativeContext(napi_env env,napi_value nativeContext,void * & contextPtr,WMError & errCode)136 static void GetNativeContext(napi_env env, napi_value nativeContext, void*& contextPtr, WMError& errCode)
137 {
138 AppExecFwk::Ability* ability = nullptr;
139 bool isOldApi = GetAPI7Ability(env, ability);
140 WLOGFD("FA mode:%{public}u", isOldApi);
141 if (isOldApi) {
142 return;
143 }
144 if (nativeContext != nullptr) {
145 napi_unwrap(env, nativeContext, &contextPtr);
146 }
147 }
148
GetTopWindowTask(void * contextPtr,napi_env env,napi_value callback,bool newApi)149 static napi_value GetTopWindowTask(void* contextPtr, napi_env env, napi_value callback, bool newApi)
150 {
151 struct TopWindowInfoList {
152 sptr<Window> window = nullptr;
153 };
154 std::shared_ptr<TopWindowInfoList> lists = std::make_shared<TopWindowInfoList>();
155 NapiAsyncTask::ExecuteCallback execute = [lists, newApi, contextPtr]() {
156 if (lists == nullptr) {
157 WLOGFE("lists == nullptr");
158 return;
159 }
160 lists->window = Window::GetTopWindowWithId(0);
161 };
162 NapiAsyncTask::CompleteCallback complete = [lists, newApi](napi_env env, NapiAsyncTask& task, int32_t status) {
163 if (lists == nullptr) {
164 if (newApi) {
165 task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY,
166 "napi abnormal"));
167 } else {
168 task.Reject(env, JsErrUtils::CreateJsError(env, WMError::WM_ERROR_NULLPTR, "napi abnormal"));
169 }
170 return;
171 }
172 if (lists->window == nullptr) {
173 if (newApi) {
174 task.Reject(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY,
175 "Get top window failed"));
176 } else {
177 task.Reject(env, JsErrUtils::CreateJsError(env, WMError::WM_ERROR_NULLPTR, "Get top window failed"));
178 }
179 return;
180 }
181 task.Resolve(env, CreateJsWindowObject(env, lists->window));
182 WLOGD("Get top window success");
183 };
184 napi_value result = nullptr;
185 NapiAsyncTask::Schedule("JsWindowManager::OnGetTopWindow",
186 env, CreateAsyncTaskWithLastParam(env, callback, std::move(execute), std::move(complete), &result));
187 return result;
188 }
189
OnGetLastWindow(napi_env env,napi_callback_info info)190 napi_value JsWindowManager::OnGetLastWindow(napi_env env, napi_callback_info info)
191 {
192 WMError errCode = WMError::WM_OK;
193 napi_value nativeContext = nullptr;
194 napi_value nativeCallback = nullptr;
195 void* contextPtr = nullptr;
196 size_t argc = 4;
197 napi_value argv[4] = {nullptr};
198 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
199 if (argc < 1) {
200 WLOGFE("Argc is invalid: %{public}zu", argc);
201 napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
202 return NapiGetUndefined(env);
203 } else {
204 nativeContext = argv[0];
205 nativeCallback = (argc == 1) ? nullptr : argv[1];
206 GetNativeContext(env, nativeContext, contextPtr, errCode);
207 }
208 if (errCode != WMError::WM_OK) {
209 napi_throw(env, JsErrUtils::CreateJsError(env, WmErrorCode::WM_ERROR_INVALID_PARAM));
210 return NapiGetUndefined(env);
211 }
212
213 return GetTopWindowTask(contextPtr, env, nativeCallback, true);
214 }
215
JsWindowManagerInit(napi_env env,napi_value exportObj)216 napi_value JsWindowManagerInit(napi_env env, napi_value exportObj)
217 {
218 if (env == nullptr || exportObj == nullptr) {
219 WLOGFE("JsWindowManagerInit env or exportObj is nullptr");
220 return nullptr;
221 }
222
223 std::unique_ptr<JsWindowManager> jsWinManager = std::make_unique<JsWindowManager>();
224 napi_wrap(env, exportObj, jsWinManager.release(), JsWindowManager::Finalizer, nullptr, nullptr);
225 napi_set_named_property(env, exportObj, "WindowType", WindowTypeInit(env));
226 napi_set_named_property(env, exportObj, "AvoidAreaType", AvoidAreaTypeInit(env));
227 napi_set_named_property(env, exportObj, "WindowMode", WindowModeInit(env));
228 napi_set_named_property(env, exportObj, "ColorSpace", ColorSpaceInit(env));
229 napi_set_named_property(env, exportObj, "WindowStageEventType", WindowStageEventTypeInit(env));
230 napi_set_named_property(env, exportObj, "WindowEventType", WindowEventTypeInit(env));
231 napi_set_named_property(env, exportObj, "WindowLayoutMode", WindowLayoutModeInit(env));
232 napi_set_named_property(env, exportObj, "Orientation", OrientationInit(env));
233 napi_set_named_property(env, exportObj, "BlurStyle", BlurStyleInit(env));
234 napi_set_named_property(env, exportObj, "WmErrorCode", WindowErrorCodeInit(env));
235 napi_set_named_property(env, exportObj, "WMError", WindowErrorInit(env));
236 napi_set_named_property(env, exportObj, "WindowStatusType", WindowStatusTypeInit(env));
237 napi_set_named_property(env, exportObj, "MaximizePresentation", MaximizePresentationInit(env));
238 const char* moduleName = "JsWindowManager";
239 BindNativeFunction(env, exportObj, "create", moduleName, JsWindowManager::Create);
240 BindNativeFunction(env, exportObj, "createWindow", moduleName, JsWindowManager::CreateWindowNapi);
241 BindNativeFunction(env, exportObj, "find", moduleName, JsWindowManager::FindWindow);
242 BindNativeFunction(env, exportObj, "findWindow", moduleName, JsWindowManager::FindWindowSync);
243 BindNativeFunction(env, exportObj, "on", moduleName, JsWindowManager::RegisterWindowManagerCallback);
244 BindNativeFunction(env, exportObj, "off", moduleName, JsWindowManager::UnregisterWindowMangerCallback);
245 BindNativeFunction(env, exportObj, "getTopWindow", moduleName, JsWindowManager::GetTopWindow);
246 BindNativeFunction(env, exportObj, "getLastWindow", moduleName, JsWindowManager::GetLastWindow);
247 BindNativeFunction(env, exportObj, "minimizeAll", moduleName, JsWindowManager::MinimizeAll);
248 BindNativeFunction(env, exportObj, "toggleShownStateForAllAppWindows", moduleName,
249 JsWindowManager::ToggleShownStateForAllAppWindows);
250 BindNativeFunction(env, exportObj, "getAllWindowLayoutInfo", moduleName, JsWindowManager::GetAllWindowLayoutInfo);
251 BindNativeFunction(env, exportObj, "setWindowLayoutMode", moduleName, JsWindowManager::SetWindowLayoutMode);
252 BindNativeFunction(env, exportObj, "setGestureNavigationEnabled", moduleName,
253 JsWindowManager::SetGestureNavigationEnabled);
254 BindNativeFunction(env, exportObj, "setWaterMarkImage", moduleName, JsWindowManager::SetWaterMarkImage);
255 BindNativeFunction(env, exportObj, "shiftAppWindowFocus", moduleName, JsWindowManager::ShiftAppWindowFocus);
256 return NapiGetUndefined(env);
257 }
258 } // namespace Rosen
259 } // namespace OHOS
260