• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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