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