• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "vsync_station.h"
21 #include "window_manager_hilog.h"
22 #include "wm_common_inner.h"
23 
24 namespace OHOS {
25 namespace Rosen {
26 namespace {
27     constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "InputTransferStation"};
28 }
WM_IMPLEMENT_SINGLE_INSTANCE(InputTransferStation)29 WM_IMPLEMENT_SINGLE_INSTANCE(InputTransferStation)
30 
31 InputTransferStation::~InputTransferStation()
32 {
33     std::lock_guard<std::mutex> lock(mtx_);
34     destroyed_ = true;
35 }
36 
OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const37 void InputEventListener::OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const
38 {
39     if (keyEvent == nullptr) {
40         WLOGFE("KeyEvent is nullptr");
41         return;
42     }
43     uint32_t windowId = static_cast<uint32_t>(keyEvent->GetAgentWindowId());
44     WLOGFI("InputTracking id:%{public}d, Receive keyEvent, windowId:%{public}u",
45         keyEvent->GetId(), windowId);
46     auto channel = InputTransferStation::GetInstance().GetInputChannel(windowId);
47     if (channel == nullptr) {
48         keyEvent->MarkProcessed();
49         WLOGFE("WindowInputChannel is nullptr");
50         return;
51     }
52     channel->HandleKeyEvent(keyEvent);
53 }
54 
OnInputEvent(std::shared_ptr<MMI::AxisEvent> axisEvent) const55 void InputEventListener::OnInputEvent(std::shared_ptr<MMI::AxisEvent> axisEvent) const
56 {
57     if (axisEvent == nullptr) {
58         WLOGFE("AxisEvent is nullptr");
59         return;
60     }
61     WLOGFD("Receive axisEvent, windowId: %{public}d", axisEvent->GetAgentWindowId());
62     axisEvent->MarkProcessed();
63 }
64 
OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const65 void InputEventListener::OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const
66 {
67     if (pointerEvent == nullptr) {
68         WLOGFE("PointerEvent is nullptr");
69         return;
70     }
71     // If handling input event at server, client will receive pointEvent that the winId is -1, intercept log error
72     uint32_t invalidId = static_cast<uint32_t>(-1);
73     uint32_t windowId = static_cast<uint32_t>(pointerEvent->GetAgentWindowId());
74     WLOGFI("InputEventListener::OnInputEvent id:%{public}d, Receive pointerEvent, windowId:%{public}u "
75         "action = %{public}d", pointerEvent->GetId(), windowId, pointerEvent->GetPointerAction());
76     auto channel = InputTransferStation::GetInstance().GetInputChannel(windowId);
77     if (channel == nullptr) {
78         if (windowId != invalidId) {
79             WLOGFE("WindowInputChannel is nullptr");
80         }
81         pointerEvent->MarkProcessed();
82         return;
83     }
84     channel->HandlePointerEvent(pointerEvent);
85 }
86 
AddInputWindow(const sptr<Window> & window)87 void InputTransferStation::AddInputWindow(const sptr<Window>& window)
88 {
89     if (IsRegisterToMMI()) {
90         return;
91     }
92 
93     uint32_t windowId = window->GetWindowId();
94     WLOGFD("Add input window, windowId: %{public}u", windowId);
95 
96     // INPUT_WINDOW_TYPE_SKIPPED should not set input consumer
97     if (INPUT_WINDOW_TYPE_SKIPPED.find(window->GetType()) != INPUT_WINDOW_TYPE_SKIPPED.end()) {
98         WLOGFW("skip window for InputConsumer [id:%{public}u, type:%{public}d]", windowId, window->GetType());
99         return;
100     }
101     sptr<WindowInputChannel> inputChannel = new WindowInputChannel(window);
102     std::lock_guard<std::mutex> lock(mtx_);
103     if (destroyed_) {
104         WLOGFW("Already destroyed");
105         return;
106     }
107     windowInputChannels_.insert(std::make_pair(windowId, inputChannel));
108     if (inputListener_ == nullptr) {
109         WLOGFD("Init input listener, IsMainHandlerAvailable: %{public}u", window->IsMainHandlerAvailable());
110         std::shared_ptr<MMI::IInputEventConsumer> listener = std::make_shared<InputEventListener>(InputEventListener());
111         auto mainEventRunner = AppExecFwk::EventRunner::GetMainEventRunner();
112         if (mainEventRunner != nullptr && window->IsMainHandlerAvailable()) {
113             WLOGFD("MainEventRunner is available");
114             eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(mainEventRunner);
115         } else {
116             WLOGFD("MainEventRunner is not available");
117             eventHandler_ = AppExecFwk::EventHandler::Current();
118             auto curThreadId = std::this_thread::get_id();
119             if (!eventHandler_ || (mainEventRunner != nullptr &&
120                 mainEventRunner->GetThreadId() == *(reinterpret_cast<uint64_t*>(&curThreadId)))) {
121                 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(
122                     AppExecFwk::EventRunner::Create(INPUT_AND_VSYNC_THREAD));
123             }
124             VsyncStation::GetInstance().SetIsMainHandlerAvailable(false);
125             VsyncStation::GetInstance().SetVsyncEventHandler(eventHandler_);
126         }
127         MMI::InputManager::GetInstance()->SetWindowInputEventConsumer(listener, eventHandler_);
128         inputListener_ = listener;
129     }
130 }
131 
RemoveInputWindow(uint32_t windowId)132 void InputTransferStation::RemoveInputWindow(uint32_t windowId)
133 {
134     WLOGFD("Remove input window, windowId: %{public}u", windowId);
135     sptr<WindowInputChannel> inputChannel = nullptr;
136     {
137         std::lock_guard<std::mutex> lock(mtx_);
138         if (destroyed_) {
139             WLOGFW("Already destroyed");
140             return;
141         }
142         auto iter = windowInputChannels_.find(windowId);
143         if (iter != windowInputChannels_.end()) {
144             inputChannel = iter->second;
145             windowInputChannels_.erase(windowId);
146         }
147     }
148     if (inputChannel != nullptr) {
149         inputChannel->Destroy();
150     } else {
151         WLOGFE("Can not find windowId: %{public}u", windowId);
152     }
153 }
154 
GetInputChannel(uint32_t windowId)155 sptr<WindowInputChannel> InputTransferStation::GetInputChannel(uint32_t windowId)
156 {
157     std::lock_guard<std::mutex> lock(mtx_);
158     if (destroyed_) {
159         WLOGFW("Already destroyed");
160         return nullptr;
161     }
162     auto iter = windowInputChannels_.find(windowId);
163     if (iter == windowInputChannels_.end()) {
164         return nullptr;
165     }
166     return iter->second;
167 }
168 }
169 }
170