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 25namespace OHOS { 26namespace Rosen { 27namespace { 28constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "InputTransferStation"}; 29} 30WM_IMPLEMENT_SINGLE_INSTANCE(InputTransferStation) 31 32InputTransferStation::~InputTransferStation() 33{ 34 std::lock_guard<std::mutex> lock(mtx_); 35 destroyed_ = true; 36} 37 38void 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 60void 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 70void 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 102void 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 148void 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 171sptr<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