1 /*
2 * Copyright (c) 2021-2022 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 "input_transfer_station.h"
17
18 #include <thread>
19 #include <event_handler.h>
20 #include "window_manager_hilog.h"
21 #include "wm_common_inner.h"
22 #include "gtx_input_event_sender.h"
23 #include <hitrace_meter.h>
24
25 namespace OHOS {
26 namespace Rosen {
27 namespace {
28 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "InputTransferStation"};
29 }
WM_IMPLEMENT_SINGLE_INSTANCE(InputTransferStation)30 WM_IMPLEMENT_SINGLE_INSTANCE(InputTransferStation)
31
32 InputTransferStation::~InputTransferStation()
33 {
34 std::lock_guard<std::mutex> lock(mtx_);
35 destroyed_ = true;
36 }
37
OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const38 void InputEventListener::OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const
39 {
40 if (keyEvent == nullptr) {
41 TLOGE(WmsLogTag::WMS_INPUT_KEY_FLOW, "KeyEvent is nullptr");
42 return;
43 }
44 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "IEL:KeyEvent id:%d", keyEvent->GetId());
45 uint32_t windowId = static_cast<uint32_t>(keyEvent->GetAgentWindowId());
46 static uint32_t eventId = 0;
47 TLOGI(WmsLogTag::WMS_INPUT_KEY_FLOW, "eid:%{public}d,InputId:%{public}d,wid:%{public}u",
48 eventId++, keyEvent->GetId(), windowId);
49 auto channel = InputTransferStation::GetInstance().GetInputChannel(windowId);
50 if (channel == nullptr) {
51 keyEvent->MarkProcessed();
52 TLOGE(WmsLogTag::WMS_INPUT_KEY_FLOW,
53 "WindowInputChannel is nullptr InputTracking id:%{public}d windowId:%{public}u",
54 keyEvent->GetId(), windowId);
55 return;
56 }
57 channel->HandleKeyEvent(keyEvent);
58 }
59
OnInputEvent(std::shared_ptr<MMI::AxisEvent> axisEvent) const60 void InputEventListener::OnInputEvent(std::shared_ptr<MMI::AxisEvent> axisEvent) const
61 {
62 if (axisEvent == nullptr) {
63 TLOGE(WmsLogTag::WMS_INPUT_KEY_FLOW, "AxisEvent is nullptr");
64 return;
65 }
66 TLOGD(WmsLogTag::WMS_INPUT_KEY_FLOW, "Receive axisEvent, windowId: %{public}d", axisEvent->GetAgentWindowId());
67 axisEvent->MarkProcessed();
68 }
69
OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const70 void InputEventListener::OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const
71 {
72 if (pointerEvent == nullptr) {
73 TLOGE(WmsLogTag::WMS_INPUT_KEY_FLOW, "PointerEvent is nullptr");
74 return;
75 }
76 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "IEL:PointerEvent id:%d action:%d",
77 pointerEvent->GetId(), pointerEvent->GetPointerAction());
78 // If handling input event at server, client will receive pointEvent that the winId is -1, intercept log error
79 uint32_t invalidId = static_cast<uint32_t>(-1);
80 uint32_t windowId = static_cast<uint32_t>(pointerEvent->GetAgentWindowId());
81 int32_t action = pointerEvent->GetPointerAction();
82 if (action != MMI::PointerEvent::POINTER_ACTION_MOVE) {
83 static uint32_t eventId = 0;
84 TLOGI(WmsLogTag::WMS_INPUT_KEY_FLOW, "eid:%{public}d,InputId:%{public}d"
85 ",wid:%{public}u,action:%{public}d", eventId++, pointerEvent->GetId(), windowId,
86 pointerEvent->GetPointerAction());
87 }
88 auto channel = InputTransferStation::GetInstance().GetInputChannel(windowId);
89 if (channel == nullptr) {
90 if (windowId != invalidId) {
91 TLOGE(WmsLogTag::WMS_INPUT_KEY_FLOW, "WindowInputChannel is nullptr InputTracking id:%{public}d "
92 "windowId:%{public}u",
93 pointerEvent->GetId(), windowId);
94 }
95 pointerEvent->MarkProcessed();
96 return;
97 }
98 channel->HandlePointerEvent(pointerEvent);
99 GtxInputEventSender::GetInstance().SetTouchEvent(channel->GetWindowRect(), pointerEvent);
100 }
101
AddInputWindow(const sptr<Window> & window)102 void InputTransferStation::AddInputWindow(const sptr<Window>& window)
103 {
104 if (IsRegisterToMMI()) {
105 return;
106 }
107
108 uint32_t windowId = window->GetWindowId();
109 TLOGD(WmsLogTag::WMS_EVENT, "Add input window, windowId: %{public}u", windowId);
110
111 // INPUT_WINDOW_TYPE_SKIPPED should not set input consumer
112 if (INPUT_WINDOW_TYPE_SKIPPED.find(window->GetType()) != INPUT_WINDOW_TYPE_SKIPPED.end()) {
113 TLOGW(WmsLogTag::WMS_EVENT, "skip window for InputConsumer [id:%{public}u, type:%{public}d]",
114 windowId, window->GetType());
115 return;
116 }
117 sptr<WindowInputChannel> inputChannel = new WindowInputChannel(window);
118 std::lock_guard<std::mutex> lock(mtx_);
119 if (destroyed_) {
120 TLOGW(WmsLogTag::WMS_EVENT, "Already destroyed");
121 return;
122 }
123 windowInputChannels_.insert(std::make_pair(windowId, inputChannel));
124 if (inputListener_ == nullptr) {
125 TLOGD(WmsLogTag::WMS_EVENT, "Init input listener, IsMainHandlerAvailable: %{public}u",
126 window->IsMainHandlerAvailable());
127 std::shared_ptr<MMI::IInputEventConsumer> listener = std::make_shared<InputEventListener>(InputEventListener());
128 auto mainEventRunner = AppExecFwk::EventRunner::GetMainEventRunner();
129 if (mainEventRunner != nullptr && window->IsMainHandlerAvailable()) {
130 TLOGD(WmsLogTag::WMS_EVENT, "MainEventRunner is available");
131 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(mainEventRunner);
132 } else {
133 TLOGD(WmsLogTag::WMS_EVENT, "MainEventRunner is not available");
134 eventHandler_ = AppExecFwk::EventHandler::Current();
135 auto curThreadId = std::this_thread::get_id();
136 if (!eventHandler_ || (mainEventRunner != nullptr &&
137 mainEventRunner->GetThreadId() == *(reinterpret_cast<uint64_t*>(&curThreadId)))) {
138 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(
139 AppExecFwk::EventRunner::Create(INPUT_AND_VSYNC_THREAD));
140 }
141 }
142 MMI::InputManager::GetInstance()->SetWindowInputEventConsumer(listener, eventHandler_);
143 TLOGI(WmsLogTag::WMS_EVENT, "SetWindowInputEventConsumer success, windowid:%{public}u", windowId);
144 inputListener_ = listener;
145 }
146 }
147
RemoveInputWindow(uint32_t windowId)148 void InputTransferStation::RemoveInputWindow(uint32_t windowId)
149 {
150 TLOGD(WmsLogTag::WMS_EVENT, "Remove input window, windowId: %{public}u", windowId);
151 sptr<WindowInputChannel> inputChannel = nullptr;
152 {
153 std::lock_guard<std::mutex> lock(mtx_);
154 if (destroyed_) {
155 WLOGFW("Already destroyed");
156 return;
157 }
158 auto iter = windowInputChannels_.find(windowId);
159 if (iter != windowInputChannels_.end()) {
160 inputChannel = iter->second;
161 windowInputChannels_.erase(windowId);
162 }
163 }
164 if (inputChannel != nullptr) {
165 inputChannel->Destroy();
166 } else {
167 TLOGE(WmsLogTag::WMS_EVENT, "Can not find windowId: %{public}u", windowId);
168 }
169 }
170
GetInputChannel(uint32_t windowId)171 sptr<WindowInputChannel> InputTransferStation::GetInputChannel(uint32_t windowId)
172 {
173 std::lock_guard<std::mutex> lock(mtx_);
174 if (destroyed_) {
175 TLOGW(WmsLogTag::WMS_EVENT, "Already destroyed");
176 return nullptr;
177 }
178 auto iter = windowInputChannels_.find(windowId);
179 if (iter == windowInputChannels_.end()) {
180 return nullptr;
181 }
182 return iter->second;
183 }
184 }
185 }
186