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) notNeed SoftKeyboard, 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->RequestHideInput();
182 inputMethod->Close();
183 TAG_LOGI(AceLogTag::ACE_KEYBOARD, "SoftKeyboard Closes Successfully.");
184 }
185 }
186 #endif
187 }
188
CaculatePoint(const RefPtr<FrameNode> & node,const std::shared_ptr<OHOS::MMI::PointerEvent> & pointerEvent)189 void CaculatePoint(const RefPtr<FrameNode>& node, const std::shared_ptr<OHOS::MMI::PointerEvent>& pointerEvent)
190 {
191 CHECK_NULL_VOID(node);
192 CHECK_NULL_VOID(pointerEvent);
193
194 auto pointerId = pointerEvent->GetPointerId();
195 auto renderContext = node->GetRenderContext();
196 CHECK_NULL_VOID(renderContext);
197 auto rect = renderContext->GetPaintRectWithoutTransform();
198 MMI::PointerEvent::PointerItem item;
199 if (pointerEvent->GetPointerItem(pointerId, item)) {
200 PointF tmp(item.GetWindowX() + rect.GetX(), item.GetWindowY() + rect.GetY());
201 renderContext->GetPointTransform(tmp);
202 item.SetWindowX(static_cast<int32_t>(std::round(tmp.GetX())));
203 item.SetWindowY(static_cast<int32_t>(std::round(tmp.GetY())));
204 if (pointerEvent->GetSourceType() == OHOS::MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN &&
205 item.GetToolType() == OHOS::MMI::PointerEvent::TOOL_TYPE_PEN) {
206 // CaculatePoint for double XY Position.
207 PointF tmpPos(item.GetWindowXPos() + rect.GetX(), item.GetWindowYPos() + rect.GetY());
208 renderContext->GetPointTransform(tmpPos);
209 item.SetWindowXPos(tmpPos.GetX());
210 item.SetWindowYPos(tmpPos.GetY());
211 }
212 pointerEvent->UpdatePointerItem(pointerId, item);
213 }
214 }
215
InjectPointerEvent(const RefPtr<FrameNode> & node,const std::shared_ptr<OHOS::MMI::PointerEvent> & pointerEvent)216 void WindowSceneHelper::InjectPointerEvent(
217 const RefPtr<FrameNode>& node, const std::shared_ptr<OHOS::MMI::PointerEvent>& pointerEvent)
218 {
219 if (!pointerEvent) {
220 TAG_LOGE(AceLogTag::ACE_INPUTTRACKING, "InjectPointerEvent pointerEvent is null return.");
221 return;
222 }
223 if (!node) {
224 MMI::InputManager::GetInstance()->MarkProcessed(
225 pointerEvent->GetId(), pointerEvent->GetActionTime(), pointerEvent->IsMarkEnabled());
226 TAG_LOGE(AceLogTag::ACE_INPUTTRACKING, "InjectPointerEvent eventId:%{public}d node is null return.",
227 pointerEvent->GetId());
228 return;
229 }
230
231 auto container = Container::Current();
232 if (!container) {
233 MMI::InputManager::GetInstance()->MarkProcessed(
234 pointerEvent->GetId(), pointerEvent->GetActionTime(), pointerEvent->IsMarkEnabled());
235 TAG_LOGE(AceLogTag::ACE_INPUTTRACKING, "InjectPointerEvent eventId:%{public}d container is null return.",
236 pointerEvent->GetId());
237 return;
238 }
239 CaculatePoint(node, pointerEvent);
240 auto aceView = AceType::DynamicCast<OHOS::Ace::Platform::AceViewOhos>(container->GetAceView());
241 if (!aceView) {
242 MMI::InputManager::GetInstance()->MarkProcessed(
243 pointerEvent->GetId(), pointerEvent->GetActionTime(), pointerEvent->IsMarkEnabled());
244 TAG_LOGE(AceLogTag::ACE_INPUTTRACKING, "InjectPointerEvent eventId:%{public}d aceView is null return.",
245 pointerEvent->GetId());
246 return;
247 }
248 OHOS::Ace::Platform::AceViewOhos::DispatchTouchEvent(aceView, pointerEvent, node, nullptr, true);
249 }
250
InjectKeyEvent(const std::shared_ptr<OHOS::MMI::KeyEvent> & keyEvent,bool isPreIme)251 bool WindowSceneHelper::InjectKeyEvent(const std::shared_ptr<OHOS::MMI::KeyEvent>& keyEvent, bool isPreIme)
252 {
253 CHECK_NULL_RETURN(keyEvent, false);
254 if (!SystemProperties::GetAceCommercialLogEnabled()) {
255 TAG_LOGI(AceLogTag::ACE_INPUTTRACKING,
256 SEC_PLD(, "KeyEvent Process to inject, eventInfo: id:%{public}d, "
257 "keyEvent info: keyCode is %{public}d, "
258 "keyAction is %{public}d, keyActionTime is %{public}" PRId64),
259 SEC_PARAM(keyEvent->GetId(), keyEvent->GetKeyCode(),
260 keyEvent->GetKeyAction(), keyEvent->GetActionTime()));
261 }
262
263 auto container = Container::Current();
264 CHECK_NULL_RETURN(container, false);
265 auto aceView = AceType::DynamicCast<OHOS::Ace::Platform::AceViewOhos>(container->GetAceView());
266 CHECK_NULL_RETURN(aceView, false);
267 return OHOS::Ace::Platform::AceViewOhos::DispatchKeyEvent(aceView, keyEvent, isPreIme);
268 }
269
IsWindowPattern(const RefPtr<FrameNode> & node)270 bool WindowSceneHelper::IsWindowPattern(const RefPtr<FrameNode>& node)
271 {
272 if (!node) {
273 return false;
274 }
275 return node->GetWindowPatternType() > static_cast<uint32_t>(WindowPatternType::SCREEN_SCENE);
276 }
277
HasWindowSession(const RefPtr<FrameNode> & node)278 bool WindowSceneHelper::HasWindowSession(const RefPtr<FrameNode>& node)
279 {
280 if (!node) {
281 return false;
282 }
283 return node->GetWindowPatternType() > static_cast<uint32_t>(WindowPatternType::TRANSFORM_SCENE);
284 }
285
IsTransformScene(uint32_t type)286 bool WindowSceneHelper::IsTransformScene(uint32_t type)
287 {
288 return type == static_cast<uint32_t>(WindowPatternType::TRANSFORM_SCENE);
289 }
290
IsSystemWindowScene(uint32_t type)291 bool WindowSceneHelper::IsSystemWindowScene(uint32_t type)
292 {
293 return type == static_cast<uint32_t>(WindowPatternType::SYSTEM_WINDOW_SCENE);
294 }
295
IsPanelScene(uint32_t type)296 bool WindowSceneHelper::IsPanelScene(uint32_t type)
297 {
298 return type == static_cast<uint32_t>(WindowPatternType::PANEL_SCENE);
299 }
300
IsScreenScene(uint32_t type)301 bool WindowSceneHelper::IsScreenScene(uint32_t type)
302 {
303 return type == static_cast<uint32_t>(WindowPatternType::SCREEN_SCENE);
304 }
305 } // namespace OHOS::Ace::NG
306