1 /*
2 * Copyright (c) 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 "core/components_ng/pattern/window_scene/helper/window_scene_helper.h"
17
18 #include "input_manager.h"
19
20 #include "adapter/ohos/entrance/ace_view_ohos.h"
21 #include "base/memory/referenced.h"
22 #include "base/utils/utils.h"
23 #include "core/common/container.h"
24 #include "core/components_ng/pattern/window_scene/scene/system_window_scene.h"
25 #include "core/components_v2/inspector/inspector_constants.h"
26 #include "core/components_ng/pattern/text_field/text_field_pattern.h"
27 #include "core/components_ng/pattern/search/search_pattern.h"
28 #include "core/pipeline_ng/pipeline_context.h"
29 #include "session/host/include/session.h"
30
31 #ifndef ACE_UNITTEST
32 #ifdef ENABLE_STANDARD_INPUT
33 #include "input_method_controller.h"
34 #endif
35 #endif
36
37 namespace OHOS::Ace::NG {
FindWindowScene(const RefPtr<FrameNode> & targetNode)38 RefPtr<UINode> WindowSceneHelper::FindWindowScene(const RefPtr<FrameNode>& targetNode)
39 {
40 CHECK_NULL_RETURN(targetNode, nullptr);
41
42 auto container = Container::Current();
43 if (!container || !container->IsScenceBoardWindow() || !container->IsSceneBoardEnabled()) {
44 TAG_LOGD(AceLogTag::ACE_KEYBOARD, "Container nullptr Or not ScenceBoardWindow.");
45 return nullptr;
46 }
47
48 TAG_LOGD(AceLogTag::ACE_KEYBOARD, "FindWindowScene start.");
49 auto parent = targetNode->GetParent();
50 while (parent && parent->GetTag() != V2::WINDOW_SCENE_ETS_TAG) {
51 parent = parent->GetParent();
52 }
53 CHECK_NULL_RETURN(parent, nullptr);
54 TAG_LOGD(AceLogTag::ACE_KEYBOARD, "FindWindowScene successfully.");
55
56 return parent;
57 }
58
GetCurSession(const RefPtr<FrameNode> & focusedFrameNode)59 sptr<Rosen::Session> GetCurSession(const RefPtr<FrameNode>& focusedFrameNode)
60 {
61 auto sceneBoardWindowUINode = WindowSceneHelper::FindWindowScene(focusedFrameNode);
62 if (sceneBoardWindowUINode == nullptr) {
63 TAG_LOGD(AceLogTag::ACE_KEYBOARD, "FindWindowScene failed.");
64 return nullptr;
65 }
66
67 auto windowSceneFrameNode = AceType::DynamicCast<FrameNode>(sceneBoardWindowUINode);
68 if (windowSceneFrameNode == nullptr) {
69 TAG_LOGD(AceLogTag::ACE_KEYBOARD, "WindowFrameNode to FrameNode failed.");
70 return nullptr;
71 }
72
73 auto windowScenePattern = windowSceneFrameNode->GetPattern<SystemWindowScene>();
74 if (windowScenePattern == nullptr) {
75 TAG_LOGD(AceLogTag::ACE_KEYBOARD, "windowScenePattern is nullptr.");
76 return nullptr;
77 }
78
79 return windowScenePattern->GetSession();
80 }
81
IsWindowScene(const RefPtr<FrameNode> & focusedFrameNode)82 bool WindowSceneHelper::IsWindowScene(const RefPtr<FrameNode>& focusedFrameNode)
83 {
84 auto window2patternSession = GetCurSession(focusedFrameNode);
85 if (window2patternSession == nullptr) {
86 TAG_LOGD(AceLogTag::ACE_KEYBOARD, "The session between window and pattern is nullptr.");
87 return false;
88 }
89
90 return window2patternSession->GetSessionInfo().isSystem_;
91 }
92
GetFocusSystemWindowId(const RefPtr<FrameNode> & focusedFrameNode)93 int32_t WindowSceneHelper::GetFocusSystemWindowId(const RefPtr<FrameNode>& focusedFrameNode)
94 {
95 int32_t focusSystemWindowId = 0;
96 bool isWindowScene = IsWindowScene(focusedFrameNode);
97 sptr<Rosen::Session> window2patternSession = GetCurSession(focusedFrameNode);
98 if (window2patternSession == nullptr) {
99 TAG_LOGD(AceLogTag::ACE_KEYBOARD, "The session between window and pattern is nullptr.");
100 return focusSystemWindowId;
101 }
102 if (isWindowScene) {
103 focusSystemWindowId = static_cast<int32_t>(window2patternSession->GetPersistentId());
104 TAG_LOGI(AceLogTag::ACE_KEYBOARD, "Get systemWindowScene id:%{public}d successfully.", focusSystemWindowId);
105 }
106
107 return focusSystemWindowId;
108 }
109
GetWindowIdForWindowScene(const RefPtr<FrameNode> & windowSceneNode)110 int32_t WindowSceneHelper::GetWindowIdForWindowScene(const RefPtr<FrameNode>& windowSceneNode)
111 {
112 int32_t windowId = 0;
113 CHECK_NULL_RETURN(windowSceneNode, windowId);
114 if (windowSceneNode->GetTag() != V2::WINDOW_SCENE_ETS_TAG) {
115 return windowId;
116 }
117 auto windowScenePattern = windowSceneNode->GetPattern<SystemWindowScene>();
118 CHECK_NULL_RETURN(windowScenePattern, windowId);
119
120 auto window2patternSession = windowScenePattern->GetSession();
121 CHECK_NULL_RETURN(window2patternSession, windowId);
122
123 windowId = static_cast<int32_t>(window2patternSession->GetPersistentId());
124 return windowId;
125 }
126
IsFocusWindowSceneCloseKeyboard(const RefPtr<FrameNode> & focusedFrameNode)127 bool WindowSceneHelper::IsFocusWindowSceneCloseKeyboard(const RefPtr<FrameNode>& focusedFrameNode)
128 {
129 sptr<Rosen::Session> window2patternSession = GetCurSession(focusedFrameNode);
130 if (window2patternSession == nullptr) {
131 TAG_LOGW(AceLogTag::ACE_KEYBOARD, "The session between window and pattern is nullptr.");
132 return false;
133 }
134
135 return window2patternSession->GetSCBKeepKeyboardFlag();
136 }
137
IsWindowSceneCloseKeyboard(const RefPtr<FrameNode> & frameNode)138 void WindowSceneHelper::IsWindowSceneCloseKeyboard(const RefPtr<FrameNode>& frameNode)
139 {
140 #if defined (ENABLE_STANDARD_INPUT)
141 // If focus pattern does not need softkeyboard, close it, in windowScene.
142 auto curPattern = frameNode->GetPattern<NG::Pattern>();
143 CHECK_NULL_VOID(curPattern);
144 bool isNeedKeyBoard = curPattern->NeedSoftKeyboard();
145 auto saveKeyboard = IsFocusWindowSceneCloseKeyboard(frameNode);
146 TAG_LOGI(AceLogTag::ACE_KEYBOARD,
147 "FrameNode(%{public}s/%{public}d) notNeedSoftKeyboard, Keep:%{public}d, Need:%{public}d)",
148 frameNode->GetTag().c_str(), frameNode->GetId(), !saveKeyboard, !isNeedKeyBoard);
149 if (!saveKeyboard && !isNeedKeyBoard) {
150 auto inputMethod = MiscServices::InputMethodController::GetInstance();
151 if (inputMethod) {
152 inputMethod->RequestHideInput(true);
153 inputMethod->Close();
154 TAG_LOGI(AceLogTag::ACE_KEYBOARD, "scbSoftKeyboard Closes Successfully.");
155 }
156 }
157 #endif
158 }
159
IsCloseKeyboard(const RefPtr<FrameNode> & frameNode)160 void WindowSceneHelper::IsCloseKeyboard(const RefPtr<FrameNode>& frameNode)
161 {
162 #if defined (ENABLE_STANDARD_INPUT)
163 // If focus pattern does not need softkeyboard, close it, not in windowScene.
164 auto curPattern = frameNode->GetPattern<NG::Pattern>();
165 CHECK_NULL_VOID(curPattern);
166 bool isNeedKeyBoard = curPattern->NeedSoftKeyboard();
167 auto saveKeyboard = IsFocusWindowSceneCloseKeyboard(frameNode);
168 TAG_LOGI(AceLogTag::ACE_KEYBOARD,
169 "FrameNode(%{public}s/%{public}d) notNeed SoftKeyboard, Keep:%{public}d, Need:%{public}d)",
170 frameNode->GetTag().c_str(), frameNode->GetId(), !saveKeyboard, !isNeedKeyBoard);
171 if (!saveKeyboard && !isNeedKeyBoard) {
172 auto inputMethod = MiscServices::InputMethodController::GetInstance();
173 if (inputMethod) {
174 inputMethod->RequestHideInput(true);
175 inputMethod->Close();
176 TAG_LOGI(AceLogTag::ACE_KEYBOARD, "SoftKeyboard Closes Successfully.");
177 }
178 }
179 #endif
180 }
181
CaculatePoint(const RefPtr<FrameNode> & node,const std::shared_ptr<OHOS::MMI::PointerEvent> & pointerEvent)182 void CaculatePoint(const RefPtr<FrameNode>& node, const std::shared_ptr<OHOS::MMI::PointerEvent>& pointerEvent)
183 {
184 CHECK_NULL_VOID(node);
185 CHECK_NULL_VOID(pointerEvent);
186
187 auto pointerId = pointerEvent->GetPointerId();
188 auto renderContext = node->GetRenderContext();
189 CHECK_NULL_VOID(renderContext);
190 auto rect = renderContext->GetPaintRectWithoutTransform();
191 MMI::PointerEvent::PointerItem item;
192 if (pointerEvent->GetPointerItem(pointerId, item)) {
193 PointF tmp(item.GetWindowX() + rect.GetX(), item.GetWindowY() + rect.GetY());
194 renderContext->GetPointTransform(tmp);
195 item.SetWindowX(static_cast<int32_t>(std::round(tmp.GetX())));
196 item.SetWindowY(static_cast<int32_t>(std::round(tmp.GetY())));
197 if (pointerEvent->GetSourceType() == OHOS::MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN &&
198 item.GetToolType() == OHOS::MMI::PointerEvent::TOOL_TYPE_PEN) {
199 // CaculatePoint for double XY Position.
200 PointF tmpPos(item.GetWindowXPos() + rect.GetX(), item.GetWindowYPos() + rect.GetY());
201 renderContext->GetPointTransform(tmpPos);
202 item.SetWindowXPos(tmpPos.GetX());
203 item.SetWindowYPos(tmpPos.GetY());
204 }
205 pointerEvent->UpdatePointerItem(pointerId, item);
206 }
207 }
208
InjectPointerEvent(const RefPtr<FrameNode> & node,const std::shared_ptr<OHOS::MMI::PointerEvent> & pointerEvent)209 void WindowSceneHelper::InjectPointerEvent(
210 const RefPtr<FrameNode>& node, const std::shared_ptr<OHOS::MMI::PointerEvent>& pointerEvent)
211 {
212 if (!pointerEvent) {
213 TAG_LOGE(AceLogTag::ACE_INPUTTRACKING, "InjectPointerEvent pointerEvent is null return.");
214 return;
215 }
216 if (!node) {
217 MMI::InputManager::GetInstance()->MarkProcessed(
218 pointerEvent->GetId(), pointerEvent->GetActionTime(), pointerEvent->IsMarkEnabled());
219 TAG_LOGE(AceLogTag::ACE_INPUTTRACKING, "InjectPointerEvent eventId:%{public}d node is null return.",
220 pointerEvent->GetId());
221 return;
222 }
223
224 auto container = Container::Current();
225 if (!container) {
226 MMI::InputManager::GetInstance()->MarkProcessed(
227 pointerEvent->GetId(), pointerEvent->GetActionTime(), pointerEvent->IsMarkEnabled());
228 TAG_LOGE(AceLogTag::ACE_INPUTTRACKING, "InjectPointerEvent eventId:%{public}d container is null return.",
229 pointerEvent->GetId());
230 return;
231 }
232 CaculatePoint(node, pointerEvent);
233 auto aceView = AceType::DynamicCast<OHOS::Ace::Platform::AceViewOhos>(container->GetAceView());
234 if (!aceView) {
235 MMI::InputManager::GetInstance()->MarkProcessed(
236 pointerEvent->GetId(), pointerEvent->GetActionTime(), pointerEvent->IsMarkEnabled());
237 TAG_LOGE(AceLogTag::ACE_INPUTTRACKING, "InjectPointerEvent eventId:%{public}d aceView is null return.",
238 pointerEvent->GetId());
239 return;
240 }
241 OHOS::Ace::Platform::AceViewOhos::DispatchTouchEvent(aceView, pointerEvent, node, nullptr, true);
242 }
243
InjectPointerEventForActionCancel(const std::shared_ptr<OHOS::MMI::PointerEvent> & pointerEvent)244 void WindowSceneHelper::InjectPointerEventForActionCancel(const std::shared_ptr<OHOS::MMI::PointerEvent>& pointerEvent)
245 {
246 if (!pointerEvent) {
247 TAG_LOGE(AceLogTag::ACE_INPUTTRACKING, "InjectPointerEventForActionCancel pointerEvent is null return.");
248 return;
249 }
250
251 if (pointerEvent->GetPointerAction() != MMI::PointerEvent::POINTER_ACTION_CANCEL) {
252 MMI::InputManager::GetInstance()->MarkProcessed(
253 pointerEvent->GetId(), pointerEvent->GetActionTime(), pointerEvent->IsMarkEnabled());
254 TAG_LOGE(AceLogTag::ACE_INPUTTRACKING, "InjectPointerEventForActionCancel only handle cancel event.");
255 return;
256 }
257
258 auto container = Container::Current();
259 if (!container) {
260 MMI::InputManager::GetInstance()->MarkProcessed(
261 pointerEvent->GetId(), pointerEvent->GetActionTime(), pointerEvent->IsMarkEnabled());
262 TAG_LOGE(AceLogTag::ACE_INPUTTRACKING,
263 "InjectPointerEventForActionCancel eventId:%{public}d container is null return.", pointerEvent->GetId());
264 return;
265 }
266 auto aceView = AceType::DynamicCast<OHOS::Ace::Platform::AceViewOhos>(container->GetAceView());
267 if (!aceView) {
268 MMI::InputManager::GetInstance()->MarkProcessed(
269 pointerEvent->GetId(), pointerEvent->GetActionTime(), pointerEvent->IsMarkEnabled());
270 TAG_LOGE(AceLogTag::ACE_INPUTTRACKING,
271 "InjectPointerEventForActionCancel eventId:%{public}d aceView is null return.", pointerEvent->GetId());
272 return;
273 }
274 OHOS::Ace::Platform::AceViewOhos::DispatchTouchEvent(aceView, pointerEvent, nullptr, nullptr, true);
275 }
276
InjectKeyEvent(const std::shared_ptr<OHOS::MMI::KeyEvent> & keyEvent,bool isPreIme)277 bool WindowSceneHelper::InjectKeyEvent(const std::shared_ptr<OHOS::MMI::KeyEvent>& keyEvent, bool isPreIme)
278 {
279 CHECK_NULL_RETURN(keyEvent, false);
280 if (!SystemProperties::GetAceCommercialLogEnabled()) {
281 TAG_LOGI(AceLogTag::ACE_INPUTTRACKING,
282 SEC_PLD(, "KeyEvent Process to inject, eventInfo: id:%{public}d, "
283 "keyEvent info: keyCode is %{public}d, "
284 "keyAction is %{public}d, keyActionTime is %{public}" PRId64),
285 SEC_PARAM(keyEvent->GetId(), keyEvent->GetKeyCode(),
286 keyEvent->GetKeyAction(), keyEvent->GetActionTime()));
287 }
288
289 auto container = Container::Current();
290 CHECK_NULL_RETURN(container, false);
291 auto aceView = AceType::DynamicCast<OHOS::Ace::Platform::AceViewOhos>(container->GetAceView());
292 CHECK_NULL_RETURN(aceView, false);
293 return OHOS::Ace::Platform::AceViewOhos::DispatchKeyEvent(aceView, keyEvent, isPreIme);
294 }
295
IsWindowPattern(const RefPtr<FrameNode> & node)296 bool WindowSceneHelper::IsWindowPattern(const RefPtr<FrameNode>& node)
297 {
298 if (!node) {
299 return false;
300 }
301 return node->GetWindowPatternType() > static_cast<uint32_t>(WindowPatternType::SCREEN_SCENE);
302 }
303
HasWindowSession(const RefPtr<FrameNode> & node)304 bool WindowSceneHelper::HasWindowSession(const RefPtr<FrameNode>& node)
305 {
306 if (!node) {
307 return false;
308 }
309 return node->GetWindowPatternType() > static_cast<uint32_t>(WindowPatternType::TRANSFORM_SCENE);
310 }
311
IsTransformScene(uint32_t type)312 bool WindowSceneHelper::IsTransformScene(uint32_t type)
313 {
314 return type == static_cast<uint32_t>(WindowPatternType::TRANSFORM_SCENE);
315 }
316
IsAppOrSubScene(uint32_t type)317 bool WindowSceneHelper::IsAppOrSubScene(uint32_t type)
318 {
319 return type == static_cast<uint32_t>(WindowPatternType::WINDOW_SCENE);
320 }
321
IsSystemWindowScene(uint32_t type)322 bool WindowSceneHelper::IsSystemWindowScene(uint32_t type)
323 {
324 return type == static_cast<uint32_t>(WindowPatternType::SYSTEM_WINDOW_SCENE);
325 }
326
IsPanelScene(uint32_t type)327 bool WindowSceneHelper::IsPanelScene(uint32_t type)
328 {
329 return type == static_cast<uint32_t>(WindowPatternType::PANEL_SCENE);
330 }
331
IsScreenScene(uint32_t type)332 bool WindowSceneHelper::IsScreenScene(uint32_t type)
333 {
334 return type == static_cast<uint32_t>(WindowPatternType::SCREEN_SCENE);
335 }
336
IsNodeInKeyGuardWindow(const RefPtr<FrameNode> & node)337 bool WindowSceneHelper::IsNodeInKeyGuardWindow(const RefPtr<FrameNode>& node)
338 {
339 auto window2patternSession = GetCurSession(node);
340 if (window2patternSession == nullptr) {
341 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "The session between window and pattern is nullptr.");
342 return false;
343 }
344
345 auto sessionWindowType = window2patternSession->GetWindowType();
346 TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "The windowtype of window scene session is %{public}d", sessionWindowType);
347 return sessionWindowType == Rosen::WindowType::WINDOW_TYPE_KEYGUARD;
348 }
349 } // namespace OHOS::Ace::NG
350