• 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     WLOGFD("Receive keyEvent, windowId: %{public}u", windowId);
45     auto channel = InputTransferStation::GetInstance().GetInputChannel(windowId);
46     if (channel == nullptr) {
47         WLOGFE("WindowInputChannel is nullptr");
48         return;
49     }
50     channel->HandleKeyEvent(keyEvent);
51 }
52 
OnInputEvent(std::shared_ptr<MMI::AxisEvent> axisEvent) const53 void InputEventListener::OnInputEvent(std::shared_ptr<MMI::AxisEvent> axisEvent) const
54 {
55     if (axisEvent == nullptr) {
56         WLOGFE("AxisEvent is nullptr");
57         return;
58     }
59     WLOGFD("Receive axisEvent, windowId: %{public}d", axisEvent->GetAgentWindowId());
60     axisEvent->MarkProcessed();
61 }
62 
OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const63 void InputEventListener::OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const
64 {
65     if (pointerEvent == nullptr) {
66         WLOGFE("PointerEvent is nullptr");
67         return;
68     }
69     // If handling input event at server, client will receive pointEvent that the winId is -1, intercept log error
70     uint32_t invalidId = static_cast<uint32_t>(-1);
71     uint32_t windowId = static_cast<uint32_t>(pointerEvent->GetAgentWindowId());
72     WLOGFD("Receive pointerEvent, windowId: %{public}u", windowId);
73     auto channel = InputTransferStation::GetInstance().GetInputChannel(windowId);
74     if (channel == nullptr) {
75         if (windowId != invalidId) {
76             WLOGFE("WindowInputChannel is nullptr");
77         }
78         pointerEvent->MarkProcessed();
79         return;
80     }
81     channel->HandlePointerEvent(pointerEvent);
82 }
83 
AddInputWindow(const sptr<Window> & window)84 void InputTransferStation::AddInputWindow(const sptr<Window>& window)
85 {
86     uint32_t windowId = window->GetWindowId();
87     WLOGFD("Add input window, windowId: %{public}u", windowId);
88 
89     // INPUT_WINDOW_TYPE_SKIPPED should not set input consumer
90     if (INPUT_WINDOW_TYPE_SKIPPED.find(window->GetType()) != INPUT_WINDOW_TYPE_SKIPPED.end()) {
91         WLOGFW("skip window for InputConsumer [id:%{public}u, type:%{public}d]", windowId, window->GetType());
92         return;
93     }
94     sptr<WindowInputChannel> inputChannel = new WindowInputChannel(window);
95     std::lock_guard<std::mutex> lock(mtx_);
96     if (destroyed_) {
97         WLOGFW("Already destroyed");
98         return;
99     }
100     windowInputChannels_.insert(std::make_pair(windowId, inputChannel));
101     if (inputListener_ == nullptr) {
102         WLOGFD("Init input listener, IsMainHandlerAvailable: %{public}u", window->IsMainHandlerAvailable());
103         std::shared_ptr<MMI::IInputEventConsumer> listener = std::make_shared<InputEventListener>(InputEventListener());
104         auto mainEventRunner = AppExecFwk::EventRunner::GetMainEventRunner();
105         if (mainEventRunner != nullptr && window->IsMainHandlerAvailable()) {
106             WLOGFD("MainEventRunner is available");
107             eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(mainEventRunner);
108         } else {
109             WLOGFD("MainEventRunner is not available");
110             eventHandler_ = AppExecFwk::EventHandler::Current();
111             auto curThreadId = std::this_thread::get_id();
112             if (!eventHandler_ || (mainEventRunner != nullptr &&
113                 mainEventRunner->GetThreadId() == *(reinterpret_cast<uint64_t*>(&curThreadId)))) {
114                 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(
115                     AppExecFwk::EventRunner::Create(INPUT_AND_VSYNC_THREAD));
116             }
117             VsyncStation::GetInstance().SetIsMainHandlerAvailable(false);
118             VsyncStation::GetInstance().SetVsyncEventHandler(eventHandler_);
119         }
120         MMI::InputManager::GetInstance()->SetWindowInputEventConsumer(listener, eventHandler_);
121         inputListener_ = listener;
122     }
123 }
124 
RemoveInputWindow(uint32_t windowId)125 void InputTransferStation::RemoveInputWindow(uint32_t windowId)
126 {
127     WLOGFD("Remove input window, windowId: %{public}u", windowId);
128     sptr<WindowInputChannel> inputChannel = nullptr;
129     {
130         std::lock_guard<std::mutex> lock(mtx_);
131         if (destroyed_) {
132             WLOGFW("Already destroyed");
133             return;
134         }
135         auto iter = windowInputChannels_.find(windowId);
136         if (iter != windowInputChannels_.end()) {
137             inputChannel = iter->second;
138             windowInputChannels_.erase(windowId);
139         }
140     }
141     if (inputChannel != nullptr) {
142         inputChannel->Destroy();
143     } else {
144         WLOGFE("Can not find windowId: %{public}u", windowId);
145     }
146 }
147 
GetInputChannel(uint32_t windowId)148 sptr<WindowInputChannel> InputTransferStation::GetInputChannel(uint32_t windowId)
149 {
150     std::lock_guard<std::mutex> lock(mtx_);
151     if (destroyed_) {
152         WLOGFW("Already destroyed");
153         return nullptr;
154     }
155     auto iter = windowInputChannels_.find(windowId);
156     if (iter == windowInputChannels_.end()) {
157         return nullptr;
158     }
159     return iter->second;
160 }
161 }
162 }
163