• 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 #include "transaction/rs_transaction.h"
31 #include "transaction/rs_transaction_handler.h"
32 #include "transaction/rs_transaction_proxy.h"
33 #include "transaction/rs_sync_transaction_controller.h"
34 #include "transaction/rs_sync_transaction_handler.h"
35 #include "ui/rs_node.h"
36 #include "ui/rs_ui_context.h"
37 #include "ui/rs_ui_director.h"
38 
39 #ifndef ACE_UNITTEST
40 #ifdef ENABLE_STANDARD_INPUT
41 #include "input_method_controller.h"
42 #endif
43 #endif
44 
45 namespace OHOS::Ace::NG {
FindWindowScene(const RefPtr<FrameNode> & targetNode)46 RefPtr<UINode> WindowSceneHelper::FindWindowScene(const RefPtr<FrameNode>& targetNode)
47 {
48     CHECK_NULL_RETURN(targetNode, nullptr);
49 
50     auto container = Container::Current();
51     if (!container || !container->IsSceneBoardWindow() || !container->IsSceneBoardEnabled()) {
52         TAG_LOGD(AceLogTag::ACE_KEYBOARD, "Container nullptr Or not SceneBoardWindow.");
53         return nullptr;
54     }
55 
56     if (targetNode->GetTag() == V2::WINDOW_SCENE_ETS_TAG) {
57         return targetNode;
58     }
59 
60     TAG_LOGD(AceLogTag::ACE_KEYBOARD, "FindWindowScene start.");
61     auto parent = targetNode->GetParent();
62     while (parent && parent->GetTag() != V2::WINDOW_SCENE_ETS_TAG) {
63         parent = parent->GetParent();
64     }
65     CHECK_NULL_RETURN(parent, nullptr);
66     TAG_LOGD(AceLogTag::ACE_KEYBOARD, "FindWindowScene successfully.");
67 
68     return parent;
69 }
70 
GetCurSession(const RefPtr<FrameNode> & focusedFrameNode)71 sptr<Rosen::Session> GetCurSession(const RefPtr<FrameNode>& focusedFrameNode)
72 {
73     auto sceneBoardWindowUINode = WindowSceneHelper::FindWindowScene(focusedFrameNode);
74     if (sceneBoardWindowUINode == nullptr) {
75         TAG_LOGD(AceLogTag::ACE_KEYBOARD, "FindWindowScene failed.");
76         return nullptr;
77     }
78 
79     auto windowSceneFrameNode = AceType::DynamicCast<FrameNode>(sceneBoardWindowUINode);
80     if (windowSceneFrameNode == nullptr) {
81         TAG_LOGD(AceLogTag::ACE_KEYBOARD, "WindowFrameNode to FrameNode failed.");
82         return nullptr;
83     }
84 
85     auto windowScenePattern = windowSceneFrameNode->GetPattern<SystemWindowScene>();
86     if (windowScenePattern == nullptr) {
87         TAG_LOGD(AceLogTag::ACE_KEYBOARD, "windowScenePattern is nullptr.");
88         return nullptr;
89     }
90 
91     return windowScenePattern->GetSession();
92 }
93 
IsWindowScene(const RefPtr<FrameNode> & focusedFrameNode)94 bool WindowSceneHelper::IsWindowScene(const RefPtr<FrameNode>& focusedFrameNode)
95 {
96     auto window2patternSession = GetCurSession(focusedFrameNode);
97     if (window2patternSession == nullptr) {
98         TAG_LOGD(AceLogTag::ACE_KEYBOARD, "The session between window and pattern is nullptr.");
99         return false;
100     }
101 
102     return window2patternSession->GetSessionInfo().isSystem_;
103 }
104 
GetFocusSystemWindowId(const RefPtr<FrameNode> & focusedFrameNode)105 int32_t WindowSceneHelper::GetFocusSystemWindowId(const RefPtr<FrameNode>& focusedFrameNode)
106 {
107     int32_t focusSystemWindowId = 0;
108     bool isWindowScene = IsWindowScene(focusedFrameNode);
109     sptr<Rosen::Session> window2patternSession = GetCurSession(focusedFrameNode);
110     if (window2patternSession == nullptr) {
111         TAG_LOGD(AceLogTag::ACE_KEYBOARD, "The session between window and pattern is nullptr.");
112         return focusSystemWindowId;
113     }
114     if (isWindowScene) {
115         focusSystemWindowId = static_cast<int32_t>(window2patternSession->GetPersistentId());
116         TAG_LOGI(AceLogTag::ACE_KEYBOARD, "Get systemWindowScene id:%{public}d successfully.", focusSystemWindowId);
117     }
118 
119     return focusSystemWindowId;
120 }
121 
GetWindowIdForWindowScene(const RefPtr<FrameNode> & windowSceneNode)122 int32_t WindowSceneHelper::GetWindowIdForWindowScene(const RefPtr<FrameNode>& windowSceneNode)
123 {
124     int32_t windowId = 0;
125     CHECK_NULL_RETURN(windowSceneNode, windowId);
126     if (windowSceneNode->GetTag() != V2::WINDOW_SCENE_ETS_TAG) {
127         return windowId;
128     }
129     auto windowScenePattern = windowSceneNode->GetPattern<SystemWindowScene>();
130     CHECK_NULL_RETURN(windowScenePattern, windowId);
131 
132     auto window2patternSession = windowScenePattern->GetSession();
133     CHECK_NULL_RETURN(window2patternSession, windowId);
134 
135     windowId = static_cast<int32_t>(window2patternSession->GetPersistentId());
136     return windowId;
137 }
138 
IsFocusWindowSceneCloseKeyboard(const RefPtr<FrameNode> & focusedFrameNode)139 bool WindowSceneHelper::IsFocusWindowSceneCloseKeyboard(const RefPtr<FrameNode>& focusedFrameNode)
140 {
141     sptr<Rosen::Session> window2patternSession = GetCurSession(focusedFrameNode);
142     if (window2patternSession == nullptr) {
143         TAG_LOGW(AceLogTag::ACE_KEYBOARD, "The session between window and pattern is nullptr.");
144         return false;
145     }
146 
147     return window2patternSession->GetSCBKeepKeyboardFlag();
148 }
149 
IsWindowSceneCloseKeyboard(const RefPtr<FrameNode> & frameNode)150 void WindowSceneHelper::IsWindowSceneCloseKeyboard(const RefPtr<FrameNode>& frameNode)
151 {
152 #if defined (ENABLE_STANDARD_INPUT)
153     // If focus pattern does not need softkeyboard, close it, in windowScene.
154     auto curPattern = frameNode->GetPattern<NG::Pattern>();
155     CHECK_NULL_VOID(curPattern);
156     bool isNeedKeyBoard = curPattern->NeedSoftKeyboard();
157     auto saveKeyboard = IsFocusWindowSceneCloseKeyboard(frameNode);
158     TAG_LOGI(AceLogTag::ACE_KEYBOARD,
159         "FrameNode(%{public}s/%{public}d) notNeedSoftKeyboard, Keep:%{public}d, Need:%{public}d)",
160         frameNode->GetTag().c_str(), frameNode->GetId(), !saveKeyboard, !isNeedKeyBoard);
161     if (!saveKeyboard && !isNeedKeyBoard) {
162         auto inputMethod = MiscServices::InputMethodController::GetInstance();
163         if (inputMethod) {
164             inputMethod->RequestHideInput(true);
165             inputMethod->Close();
166             TAG_LOGI(AceLogTag::ACE_KEYBOARD, "scbSoftKeyboard Closes Successfully.");
167         }
168     }
169 #endif
170 }
171 
IsCloseKeyboard(const RefPtr<FrameNode> & frameNode)172 void WindowSceneHelper::IsCloseKeyboard(const RefPtr<FrameNode>& frameNode)
173 {
174 #if defined (ENABLE_STANDARD_INPUT)
175     // If focus pattern does not need softkeyboard, close it, not in windowScene.
176     auto curPattern = frameNode->GetPattern<NG::Pattern>();
177     CHECK_NULL_VOID(curPattern);
178     bool isNeedKeyBoard = curPattern->NeedSoftKeyboard();
179     auto saveKeyboard = IsFocusWindowSceneCloseKeyboard(frameNode);
180     TAG_LOGI(AceLogTag::ACE_KEYBOARD,
181         "FrameNode(%{public}s/%{public}d) notNeed SoftKeyboard, Keep:%{public}d, Need:%{public}d)",
182         frameNode->GetTag().c_str(), frameNode->GetId(), !saveKeyboard, !isNeedKeyBoard);
183     if (!saveKeyboard && !isNeedKeyBoard) {
184         auto inputMethod = MiscServices::InputMethodController::GetInstance();
185         if (inputMethod) {
186             inputMethod->RequestHideInput(true);
187             inputMethod->Close();
188             TAG_LOGI(AceLogTag::ACE_KEYBOARD, "SoftKeyboard Closes Successfully.");
189         }
190     }
191 #endif
192 }
193 
CaculatePoint(const RefPtr<FrameNode> & node,const std::shared_ptr<OHOS::MMI::PointerEvent> & pointerEvent)194 void CaculatePoint(const RefPtr<FrameNode>& node, const std::shared_ptr<OHOS::MMI::PointerEvent>& pointerEvent)
195 {
196     CHECK_NULL_VOID(node);
197     CHECK_NULL_VOID(pointerEvent);
198 
199     auto pointerId = pointerEvent->GetPointerId();
200     auto renderContext = node->GetRenderContext();
201     CHECK_NULL_VOID(renderContext);
202     auto rect = renderContext->GetPaintRectWithoutTransform();
203     MMI::PointerEvent::PointerItem item;
204     if (pointerEvent->GetPointerItem(pointerId, item)) {
205         auto windowX = item.GetWindowX();
206         auto windowY = item.GetWindowY();
207         PointF tmp(item.GetWindowX() + rect.GetX(), item.GetWindowY() + rect.GetY());
208         renderContext->GetPointTransform(tmp);
209         item.SetWindowX(static_cast<int32_t>(std::round(tmp.GetX())));
210         item.SetWindowY(static_cast<int32_t>(std::round(tmp.GetY())));
211         if (pointerEvent->GetSourceType() == OHOS::MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
212             // CaculatePoint for double XY Position.
213             PointF tmpPos((NearZero(item.GetWindowXPos()) ? windowX : item.GetWindowXPos()) + rect.GetX(),
214                 (NearZero(item.GetWindowYPos()) ? windowY : item.GetWindowYPos()) + rect.GetY());
215             renderContext->GetPointTransform(tmpPos);
216             item.SetWindowXPos(tmpPos.GetX());
217             item.SetWindowYPos(tmpPos.GetY());
218         }
219         pointerEvent->UpdatePointerItem(pointerId, item);
220     }
221 }
222 
InjectPointerEvent(const RefPtr<FrameNode> & node,const std::shared_ptr<OHOS::MMI::PointerEvent> & pointerEvent)223 void WindowSceneHelper::InjectPointerEvent(
224     const RefPtr<FrameNode>& node, const std::shared_ptr<OHOS::MMI::PointerEvent>& pointerEvent)
225 {
226     if (!pointerEvent) {
227         TAG_LOGE(AceLogTag::ACE_INPUTTRACKING, "InjectPointerEvent pointerEvent is null return.");
228         return;
229     }
230     if (!node) {
231         MMI::InputManager::GetInstance()->MarkProcessed(
232             pointerEvent->GetId(), pointerEvent->GetActionTime(), pointerEvent->IsMarkEnabled());
233         TAG_LOGE(AceLogTag::ACE_INPUTTRACKING, "InjectPointerEvent eventId:%{public}d node is null return.",
234             pointerEvent->GetId());
235         return;
236     }
237 
238     auto container = Container::Current();
239     if (!container) {
240         MMI::InputManager::GetInstance()->MarkProcessed(
241             pointerEvent->GetId(), pointerEvent->GetActionTime(), pointerEvent->IsMarkEnabled());
242         TAG_LOGE(AceLogTag::ACE_INPUTTRACKING, "InjectPointerEvent eventId:%{public}d container is null return.",
243             pointerEvent->GetId());
244         return;
245     }
246     CaculatePoint(node, pointerEvent);
247     auto aceView = AceType::DynamicCast<OHOS::Ace::Platform::AceViewOhos>(container->GetAceView());
248     if (!aceView) {
249         MMI::InputManager::GetInstance()->MarkProcessed(
250             pointerEvent->GetId(), pointerEvent->GetActionTime(), pointerEvent->IsMarkEnabled());
251         TAG_LOGE(AceLogTag::ACE_INPUTTRACKING, "InjectPointerEvent eventId:%{public}d aceView is null return.",
252             pointerEvent->GetId());
253         return;
254     }
255     OHOS::Ace::Platform::AceViewOhos::DispatchTouchEvent(aceView, pointerEvent, node, nullptr, true);
256 }
257 
InjectPointerEventForActionCancel(const std::shared_ptr<OHOS::MMI::PointerEvent> & pointerEvent)258 void WindowSceneHelper::InjectPointerEventForActionCancel(const std::shared_ptr<OHOS::MMI::PointerEvent>& pointerEvent)
259 {
260     if (!pointerEvent) {
261         TAG_LOGE(AceLogTag::ACE_INPUTTRACKING, "InjectPointerEventForActionCancel pointerEvent is null return.");
262         return;
263     }
264 
265     if (pointerEvent->GetPointerAction() != MMI::PointerEvent::POINTER_ACTION_CANCEL) {
266         MMI::InputManager::GetInstance()->MarkProcessed(
267             pointerEvent->GetId(), pointerEvent->GetActionTime(), pointerEvent->IsMarkEnabled());
268         TAG_LOGE(AceLogTag::ACE_INPUTTRACKING, "InjectPointerEventForActionCancel only handle cancel event.");
269         return;
270     }
271 
272     auto container = Container::Current();
273     if (!container) {
274         MMI::InputManager::GetInstance()->MarkProcessed(
275             pointerEvent->GetId(), pointerEvent->GetActionTime(), pointerEvent->IsMarkEnabled());
276         TAG_LOGE(AceLogTag::ACE_INPUTTRACKING,
277             "InjectPointerEventForActionCancel eventId:%{public}d container is null return.", pointerEvent->GetId());
278         return;
279     }
280     auto aceView = AceType::DynamicCast<OHOS::Ace::Platform::AceViewOhos>(container->GetAceView());
281     if (!aceView) {
282         MMI::InputManager::GetInstance()->MarkProcessed(
283             pointerEvent->GetId(), pointerEvent->GetActionTime(), pointerEvent->IsMarkEnabled());
284         TAG_LOGE(AceLogTag::ACE_INPUTTRACKING,
285             "InjectPointerEventForActionCancel eventId:%{public}d aceView is null return.", pointerEvent->GetId());
286         return;
287     }
288     OHOS::Ace::Platform::AceViewOhos::DispatchTouchEvent(aceView, pointerEvent, nullptr, nullptr, true);
289 }
290 
InjectKeyEvent(const std::shared_ptr<OHOS::MMI::KeyEvent> & keyEvent,bool isPreIme)291 bool WindowSceneHelper::InjectKeyEvent(const std::shared_ptr<OHOS::MMI::KeyEvent>& keyEvent, bool isPreIme)
292 {
293     CHECK_NULL_RETURN(keyEvent, false);
294     if (!SystemProperties::GetAceCommercialLogEnabled()) {
295         TAG_LOGI(AceLogTag::ACE_INPUTTRACKING,
296             SEC_PLD(, "KeyEvent Process to inject, eventInfo: id:%{public}d, "
297             "keyEvent info: keyCode is %{public}d, "
298             "keyAction is %{public}d, keyActionTime is %{public}" PRId64),
299             SEC_PARAM(keyEvent->GetId(), keyEvent->GetKeyCode(),
300             keyEvent->GetKeyAction(), keyEvent->GetActionTime()));
301     }
302 
303     auto container = Container::Current();
304     CHECK_NULL_RETURN(container, false);
305     auto aceView = AceType::DynamicCast<OHOS::Ace::Platform::AceViewOhos>(container->GetAceView());
306     CHECK_NULL_RETURN(aceView, false);
307     return OHOS::Ace::Platform::AceViewOhos::DispatchKeyEvent(aceView, keyEvent, isPreIme);
308 }
309 
IsWindowPattern(const RefPtr<FrameNode> & node)310 bool WindowSceneHelper::IsWindowPattern(const RefPtr<FrameNode>& node)
311 {
312     if (!node) {
313         return false;
314     }
315     return node->GetWindowPatternType() > static_cast<uint32_t>(WindowPatternType::SCREEN_SCENE);
316 }
317 
HasWindowSession(const RefPtr<FrameNode> & node)318 bool WindowSceneHelper::HasWindowSession(const RefPtr<FrameNode>& node)
319 {
320     if (!node) {
321         return false;
322     }
323     return node->GetWindowPatternType() > static_cast<uint32_t>(WindowPatternType::TRANSFORM_SCENE);
324 }
325 
IsTransformScene(uint32_t type)326 bool WindowSceneHelper::IsTransformScene(uint32_t type)
327 {
328     return type == static_cast<uint32_t>(WindowPatternType::TRANSFORM_SCENE);
329 }
330 
IsAppOrSubScene(uint32_t type)331 bool WindowSceneHelper::IsAppOrSubScene(uint32_t type)
332 {
333     return type == static_cast<uint32_t>(WindowPatternType::WINDOW_SCENE);
334 }
335 
IsSystemWindowScene(uint32_t type)336 bool WindowSceneHelper::IsSystemWindowScene(uint32_t type)
337 {
338     return type == static_cast<uint32_t>(WindowPatternType::SYSTEM_WINDOW_SCENE);
339 }
340 
IsPanelScene(uint32_t type)341 bool WindowSceneHelper::IsPanelScene(uint32_t type)
342 {
343     return type == static_cast<uint32_t>(WindowPatternType::PANEL_SCENE);
344 }
345 
IsScreenScene(uint32_t type)346 bool WindowSceneHelper::IsScreenScene(uint32_t type)
347 {
348     return type == static_cast<uint32_t>(WindowPatternType::SCREEN_SCENE);
349 }
350 
IsNodeInKeyGuardWindow(const RefPtr<FrameNode> & node)351 bool WindowSceneHelper::IsNodeInKeyGuardWindow(const RefPtr<FrameNode>& node)
352 {
353     auto window2patternSession = GetCurSession(node);
354     if (window2patternSession == nullptr) {
355         TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "The session between window and pattern is nullptr.");
356         return false;
357     }
358 
359     auto sessionWindowType = window2patternSession->GetWindowType();
360     TAG_LOGD(AceLogTag::ACE_SUB_WINDOW, "The windowtype of window scene session is %{public}d", sessionWindowType);
361     return sessionWindowType == Rosen::WindowType::WINDOW_TYPE_KEYGUARD;
362 }
363 
GetRSUIContext(const RefPtr<FrameNode> & frameNode)364 std::shared_ptr<Rosen::RSUIContext> WindowSceneHelper::GetRSUIContext(const RefPtr<FrameNode>& frameNode)
365 {
366     CHECK_NULL_RETURN(frameNode, nullptr);
367     auto pipeline = frameNode->GetContext();
368     CHECK_NULL_RETURN(pipeline, nullptr);
369     auto window = pipeline->GetWindow();
370     CHECK_NULL_RETURN(window, nullptr);
371     auto rsUIDirector = window->GetRSUIDirector();
372     CHECK_NULL_RETURN(rsUIDirector, nullptr);
373     auto rsUIContext = rsUIDirector->GetRSUIContext();
374     TAG_LOGD(AceLogTag::ACE_WINDOW, "%{public}s", RSUIContextToStr(rsUIContext).c_str());
375     return rsUIContext;
376 }
377 
GetRSTransaction(const sptr<Rosen::Session> & session)378 std::shared_ptr<Rosen::RSTransaction> WindowSceneHelper::GetRSTransaction(const sptr<Rosen::Session>& session)
379 {
380     auto rsUIContext = session->GetRSUIContext(__func__);
381     if (rsUIContext) {
382         if (auto rsSyncTransHandler = rsUIContext->GetSyncTransactionHandler()) {
383             return rsSyncTransHandler->GetRSTransaction();
384         }
385     }
386     TAG_LOGD(AceLogTag::ACE_WINDOW, "Use RSSyncTransactionController");
387     return Rosen::RSSyncTransactionController::GetInstance()->GetRSTransaction();
388 }
389 
390 
GetRSTransactionHandler(const RefPtr<FrameNode> & frameNode)391 std::shared_ptr<Rosen::RSTransactionHandler> WindowSceneHelper::GetRSTransactionHandler(
392     const RefPtr<FrameNode>& frameNode)
393 {
394     auto rsUIContext = GetRSUIContext(frameNode);
395     CHECK_NULL_RETURN(rsUIContext, nullptr);
396     return rsUIContext->GetRSTransaction();
397 }
398 
FlushImplicitTransaction(const RefPtr<FrameNode> & frameNode)399 void WindowSceneHelper::FlushImplicitTransaction(const RefPtr<FrameNode>& frameNode)
400 {
401     if (auto transactionHandler = GetRSTransactionHandler(frameNode)) {
402         transactionHandler->FlushImplicitTransaction();
403     } else {
404         TAG_LOGD(AceLogTag::ACE_WINDOW, "RSTransactionHandler is null, use RSTransactionProxy");
405         Rosen::RSTransactionProxy::GetInstance()->FlushImplicitTransaction();
406     }
407 }
408 
RSNodeToStr(const std::shared_ptr<Rosen::RSNode> & rsNode)409 std::string WindowSceneHelper::RSNodeToStr(const std::shared_ptr<Rosen::RSNode>& rsNode)
410 {
411     if (!rsNode) {
412         return "RSNode is null";
413     }
414     std::ostringstream oss;
415     oss << "RSNode [id: " << rsNode->GetId() << "], "
416         << RSUIContextToStr(rsNode->GetRSUIContext());
417     return oss.str();
418 }
419 
RSUIContextToStr(const std::shared_ptr<Rosen::RSUIContext> & rsUIContext)420 std::string WindowSceneHelper::RSUIContextToStr(const std::shared_ptr<Rosen::RSUIContext>& rsUIContext)
421 {
422     if (!rsUIContext) {
423         return "RSUIContext is null";
424     }
425     std::ostringstream oss;
426     oss << "RSUIContext [token: " << rsUIContext->GetToken()
427         << ", tid: "
428         << static_cast<int32_t>(rsUIContext->GetToken() >> 32) // 32: tid's offset position in the token
429         << "]";
430     return oss.str();
431 }
432 } // namespace OHOS::Ace::NG
433