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 #include "intention_event_manager.h"
16
17 #include "scene_session.h"
18 #include "session_manager/include/scene_session_manager.h"
19 #include "window_manager_hilog.h"
20
21 namespace OHOS {
22 namespace Rosen {
23 namespace {
24 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "IntentionEventManager" };
25 std::shared_ptr<MMI::PointerEvent> g_lastMouseEvent = nullptr;
26 constexpr int32_t DELAY_TIME = 15;
27 } // namespace
28
IntentionEventManager()29 IntentionEventManager::IntentionEventManager() {}
~IntentionEventManager()30 IntentionEventManager::~IntentionEventManager() {}
31
~InputEventListener()32 IntentionEventManager::InputEventListener::~InputEventListener()
33 {
34 std::lock_guard<std::mutex> guard(mouseEventMutex_);
35 g_lastMouseEvent = nullptr;
36 }
37
EnableInputEventListener(Ace::UIContent * uiContent,std::shared_ptr<AppExecFwk::EventHandler> eventHandler)38 bool IntentionEventManager::EnableInputEventListener(Ace::UIContent* uiContent,
39 std::shared_ptr<AppExecFwk::EventHandler> eventHandler)
40 {
41 if (uiContent == nullptr) {
42 WLOGFE("uiContent is null");
43 return false;
44 }
45 if (eventHandler == nullptr) {
46 WLOGFE("eventHandler is null");
47 return false;
48 }
49 auto listener =
50 std::make_shared<IntentionEventManager::InputEventListener>(uiContent, eventHandler);
51 MMI::InputManager::GetInstance()->SetWindowInputEventConsumer(listener, eventHandler);
52 listener->RegisterWindowFocusChanged();
53 return true;
54 }
55
RegisterWindowFocusChanged()56 void IntentionEventManager::InputEventListener::RegisterWindowFocusChanged()
57 {
58 SceneSessionManager::GetInstance().RegisterWindowFocusChanged(
59 [this](int32_t persistentId, bool isFocused) {
60 WLOGFD("Window focus changed, persistentId:%{public}d, isFocused:%{public}d",
61 persistentId, isFocused);
62 this->ProcessEnterLeaveEvent();
63 }
64 );
65 }
66
ProcessEnterLeaveEvent()67 void IntentionEventManager::InputEventListener::ProcessEnterLeaveEvent()
68 {
69 auto task = [this]() {
70 std::lock_guard<std::mutex> guard(mouseEventMutex_);
71 auto enterSession = SceneSession::GetEnterWindow().promote();
72 if ((enterSession != nullptr) && ((g_lastMouseEvent != nullptr) &&
73 (g_lastMouseEvent->GetButtonId() == MMI::PointerEvent::BUTTON_NONE))) {
74 WLOGFD("Window changed, reissuing enter leave events");
75 auto leaveEvent = std::make_shared<MMI::PointerEvent>(*g_lastMouseEvent);
76 leaveEvent->SetPointerAction(MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW);
77 enterSession->TransferPointerEvent(leaveEvent);
78
79 auto enterEvent = std::make_shared<MMI::PointerEvent>(*g_lastMouseEvent);
80 enterEvent->SetPointerAction(MMI::PointerEvent::POINTER_ACTION_ENTER_WINDOW);
81 if (uiContent_ == nullptr) {
82 WLOGFE("uiContent_ is null");
83 return;
84 }
85 uiContent_->ProcessPointerEvent(enterEvent);
86 }
87 };
88 auto eventHandler = weakEventConsumer_.lock();
89 if (eventHandler == nullptr) {
90 WLOGFE("eventHandler is null");
91 return;
92 }
93 eventHandler->PostTask(std::move(task), DELAY_TIME, AppExecFwk::EventQueue::Priority::IMMEDIATE);
94 }
95
UpdateLastMouseEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const96 void IntentionEventManager::InputEventListener::UpdateLastMouseEvent(
97 std::shared_ptr<MMI::PointerEvent> pointerEvent) const
98 {
99 if (pointerEvent == nullptr) {
100 WLOGFE("pointerEvent is null");
101 return;
102 }
103 if ((pointerEvent->GetSourceType() == MMI::PointerEvent::SOURCE_TYPE_MOUSE) &&
104 (pointerEvent->GetPointerAction() != MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW)) {
105 std::lock_guard<std::mutex> guard(mouseEventMutex_);
106 g_lastMouseEvent = std::make_shared<MMI::PointerEvent>(*pointerEvent);
107 } else if (g_lastMouseEvent != nullptr) {
108 WLOGFD("Clear last mouse event");
109 std::lock_guard<std::mutex> guard(mouseEventMutex_);
110 g_lastMouseEvent = nullptr;
111 SceneSession::ClearEnterWindow();
112 }
113 }
114
OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const115 void IntentionEventManager::InputEventListener::OnInputEvent(
116 std::shared_ptr<MMI::PointerEvent> pointerEvent) const
117 {
118 if (pointerEvent == nullptr) {
119 WLOGFE("pointerEvent is null");
120 return;
121 }
122 if (uiContent_ == nullptr) {
123 WLOGFE("uiContent_ is null");
124 return;
125 }
126
127 int32_t action = pointerEvent->GetPointerAction();
128 if (action == MMI::PointerEvent::POINTER_ACTION_DOWN ||
129 action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
130 int32_t pointerId = pointerEvent->GetPointerId();
131 MMI::PointerEvent::PointerItem pointerItem;
132 if (!pointerEvent->GetPointerItem(pointerId, pointerItem)) {
133 WLOGFE("uiContent_ is null");
134 } else {
135 SceneSessionManager::GetInstance().OnOutsideDownEvent(
136 pointerItem.GetDisplayX(), pointerItem.GetDisplayY());
137 SceneSessionManager::GetInstance().NotifySessionTouchOutside(
138 action, pointerItem.GetDisplayX(), pointerItem.GetDisplayY());
139 }
140 }
141 uiContent_->ProcessPointerEvent(pointerEvent);
142 UpdateLastMouseEvent(pointerEvent);
143 }
144
OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const145 void IntentionEventManager::InputEventListener::OnInputEvent(
146 std::shared_ptr<MMI::KeyEvent> keyEvent) const
147 {
148 auto focusedSessionId = SceneSessionManager::GetInstance().GetFocusedSession();
149 if (focusedSessionId == INVALID_SESSION_ID) {
150 WLOGFE("focusedSessionId is invalid");
151 return;
152 }
153 auto focusedSceneSession = SceneSessionManager::GetInstance().GetSceneSession(focusedSessionId);
154 if (focusedSceneSession == nullptr) {
155 WLOGFE("focusedSceneSession is null");
156 return;
157 }
158 focusedSceneSession->TransferKeyEvent(keyEvent);
159 }
160
OnInputEvent(std::shared_ptr<MMI::AxisEvent> axisEvent) const161 void IntentionEventManager::InputEventListener::OnInputEvent(
162 std::shared_ptr<MMI::AxisEvent> axisEvent) const
163 {
164 if (uiContent_ == nullptr) {
165 WLOGFE("uiContent_ is null");
166 return;
167 }
168 uiContent_->ProcessAxisEvent(axisEvent);
169 }
170 }
171 } // namespace OHOS::Rosen