mirror of
https://github.com/openharmony/windowmanager.git
synced 2026-07-21 04:25:28 -04:00
Solve the crash issue in WindowInputChannel::HandlePointerEvent
Signed-off-by: maojiangping <maojiangping@huawei.com> Change-Id: I36fb8c7296a087eacdd7ad556c3511c8ef1863d1 Signed-off-by: maojiangping <maojiangping@huawei.com>
This commit is contained in:
@@ -37,7 +37,7 @@ public:
|
||||
|
||||
private:
|
||||
sptr<WindowInputChannel> GetInputChannel(uint32_t windowId);
|
||||
bool initInputListener_ = false;
|
||||
std::mutex mtx_;
|
||||
std::unordered_map<uint32_t, sptr<WindowInputChannel>> windowInputChannels_;
|
||||
std::shared_ptr<MMI::IInputEventConsumer> inputListener_ = nullptr;
|
||||
};
|
||||
|
||||
@@ -33,7 +33,8 @@ public:
|
||||
private:
|
||||
void OnVsync(int64_t timeStamp);
|
||||
bool IsKeyboardEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent) const;
|
||||
std::vector<std::shared_ptr<MMI::PointerEvent>> pointerEventPool_;
|
||||
std::shared_ptr<MMI::PointerEvent> moveEvent_ = nullptr;
|
||||
std::mutex mtx_;
|
||||
sptr<Window> window_;
|
||||
std::shared_ptr<VsyncStation::VsyncCallback> callback_ =
|
||||
std::make_shared<VsyncStation::VsyncCallback>(VsyncStation::VsyncCallback());
|
||||
|
||||
@@ -25,15 +25,15 @@ WM_IMPLEMENT_SINGLE_INSTANCE(InputTransferStation)
|
||||
|
||||
void InputEventListener::OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const
|
||||
{
|
||||
WLOGFI("OnInputEvent: receive keyEvent");
|
||||
if (keyEvent == nullptr) {
|
||||
WLOGE("OnInputEvent receive KeyEvent is nullptr");
|
||||
WLOGFE("KeyEvent is nullptr");
|
||||
return;
|
||||
}
|
||||
uint32_t windowId = static_cast<uint32_t>(keyEvent->GetAgentWindowId());
|
||||
WLOGFI("Receive keyEvent, windowId: %{public}u", windowId);
|
||||
auto channel = InputTransferStation::GetInstance().GetInputChannel(windowId);
|
||||
if (channel == nullptr) {
|
||||
WLOGE("OnInputEvent channel is nullptr");
|
||||
WLOGFE("WindowInputChannel is nullptr");
|
||||
return;
|
||||
}
|
||||
channel->HandleKeyEvent(keyEvent);
|
||||
@@ -41,25 +41,25 @@ void InputEventListener::OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) c
|
||||
|
||||
void InputEventListener::OnInputEvent(std::shared_ptr<MMI::AxisEvent> axisEvent) const
|
||||
{
|
||||
WLOGFI("OnInputEvent: receive axisEvent");
|
||||
if (axisEvent == nullptr) {
|
||||
WLOGE("OnInputEvent receive axisEvent is nullptr");
|
||||
WLOGFE("AxisEvent is nullptr");
|
||||
return;
|
||||
}
|
||||
WLOGFI("Receive axisEvent, windowId: %{public}d", axisEvent->GetAgentWindowId());
|
||||
axisEvent->MarkProcessed();
|
||||
}
|
||||
|
||||
void InputEventListener::OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const
|
||||
{
|
||||
WLOGFI("OnInputEvent: receive pointerEvent");
|
||||
if (pointerEvent == nullptr) {
|
||||
WLOGE("OnInputEvent receive pointerEvent is nullptr");
|
||||
WLOGFE("PointerEvent is nullptr");
|
||||
return;
|
||||
}
|
||||
uint32_t windowId = static_cast<uint32_t>(pointerEvent->GetAgentWindowId());
|
||||
WLOGFI("Receive pointerEvent, windowId: %{public}u", windowId);
|
||||
auto channel = InputTransferStation::GetInstance().GetInputChannel(windowId);
|
||||
if (channel == nullptr) {
|
||||
WLOGE("OnInputEvent channel is nullptr");
|
||||
WLOGFE("WindowInputChannel is nullptr");
|
||||
return;
|
||||
}
|
||||
channel->HandlePointerEvent(pointerEvent);
|
||||
@@ -67,28 +67,29 @@ void InputEventListener::OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointer
|
||||
|
||||
void InputTransferStation::AddInputWindow(const sptr<Window>& window)
|
||||
{
|
||||
WLOGFI("AddInputWindow: add window");
|
||||
uint32_t windowId = window->GetWindowId();
|
||||
WLOGFI("Add input window, windowId: %{public}u", windowId);
|
||||
sptr<WindowInputChannel> inputChannel = new WindowInputChannel(window);
|
||||
std::lock_guard<std::mutex> lock(mtx_);
|
||||
windowInputChannels_.insert(std::make_pair(windowId, inputChannel));
|
||||
if (!initInputListener_) {
|
||||
WLOGFI("init input listener");
|
||||
if (inputListener_ == nullptr) {
|
||||
WLOGFI("Init input listener");
|
||||
std::shared_ptr<MMI::IInputEventConsumer> listener = std::make_shared<InputEventListener>(InputEventListener());
|
||||
MMI::InputManager::GetInstance()->SetWindowInputEventConsumer(listener);
|
||||
inputListener_ = listener;
|
||||
initInputListener_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void InputTransferStation::RemoveInputWindow(const sptr<Window>& window)
|
||||
{
|
||||
WLOGFI("RemoveInputWindow: remove window");
|
||||
uint32_t windowId = window->GetWindowId();
|
||||
WLOGFI("Remove input window, windowId: %{public}u", windowId);
|
||||
std::lock_guard<std::mutex> lock(mtx_);
|
||||
auto iter = windowInputChannels_.find(windowId);
|
||||
if (iter != windowInputChannels_.end()) {
|
||||
windowInputChannels_.erase(windowId);
|
||||
} else {
|
||||
WLOGE("RemoveInputWindow do not find windowId: %{public}d", windowId);
|
||||
WLOGFE("Can not find windowId: %{public}d", windowId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +97,7 @@ void InputTransferStation::SetInputListener(uint32_t windowId, std::shared_ptr<M
|
||||
{
|
||||
auto channel = GetInputChannel(windowId);
|
||||
if (channel == nullptr) {
|
||||
WLOGE("SetInputListener channel is nullptr");
|
||||
WLOGFE("WindowInputChannel is nullptr, windowId: %{public}u", windowId);
|
||||
return;
|
||||
}
|
||||
channel->SetInputListener(listener);
|
||||
@@ -104,9 +105,10 @@ void InputTransferStation::SetInputListener(uint32_t windowId, std::shared_ptr<M
|
||||
|
||||
sptr<WindowInputChannel> InputTransferStation::GetInputChannel(uint32_t windowId)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mtx_);
|
||||
auto iter = windowInputChannels_.find(windowId);
|
||||
if (iter == windowInputChannels_.end()) {
|
||||
WLOGE("GetInputChannel do not find channel according to windowId: %{public}d", windowId);
|
||||
WLOGFE("Can not find channel according to windowId: %{public}d", windowId);
|
||||
return nullptr;
|
||||
}
|
||||
return iter->second;
|
||||
|
||||
@@ -31,17 +31,19 @@ WindowInputChannel::WindowInputChannel(const sptr<Window>& window)
|
||||
void WindowInputChannel::HandleKeyEvent(std::shared_ptr<MMI::KeyEvent>& keyEvent)
|
||||
{
|
||||
if (keyEvent == nullptr) {
|
||||
WLOGE("HandleKeyEvent keyEvent is nullptr");
|
||||
WLOGFE("keyEvent is nullptr");
|
||||
return;
|
||||
}
|
||||
WLOGFI("Receive key event, windowId: %{public}d, keyCode: %{public}d",
|
||||
window_->GetWindowId(), keyEvent->GetKeyCode());
|
||||
bool isKeyboardEvent = IsKeyboardEvent(keyEvent);
|
||||
bool inputMethodHasProcessed = false;
|
||||
if (isKeyboardEvent) {
|
||||
WLOGI("dispatch keyEvent to input method");
|
||||
WLOGFI("dispatch keyEvent to input method");
|
||||
inputMethodHasProcessed = MiscServices::InputMethodController::GetInstance()->dispatchKeyEvent(keyEvent);
|
||||
}
|
||||
if (!isKeyboardEvent || !inputMethodHasProcessed) {
|
||||
WLOGI("dispatch keyEvent to ACE");
|
||||
WLOGFI("dispatch keyEvent to ACE");
|
||||
if (inputListener_ != nullptr) {
|
||||
inputListener_->OnInputEvent(keyEvent);
|
||||
return;
|
||||
@@ -54,7 +56,7 @@ void WindowInputChannel::HandleKeyEvent(std::shared_ptr<MMI::KeyEvent>& keyEvent
|
||||
void WindowInputChannel::HandlePointerEvent(std::shared_ptr<MMI::PointerEvent>& pointerEvent)
|
||||
{
|
||||
if (pointerEvent == nullptr) {
|
||||
WLOGE("HandlePointerEvent pointerEvent is nullptr");
|
||||
WLOGFE("pointerEvent is nullptr");
|
||||
return;
|
||||
}
|
||||
if (inputListener_ != nullptr) {
|
||||
@@ -62,13 +64,21 @@ void WindowInputChannel::HandlePointerEvent(std::shared_ptr<MMI::PointerEvent>&
|
||||
return;
|
||||
}
|
||||
if (pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_MOVE) {
|
||||
if (pointerEventPool_.size() > MAX_INPUT_NUM) {
|
||||
pointerEventPool_.clear();
|
||||
std::shared_ptr<MMI::PointerEvent> pointerEventTemp;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mtx_);
|
||||
pointerEventTemp = moveEvent_;
|
||||
moveEvent_ = pointerEvent;
|
||||
}
|
||||
pointerEventPool_.emplace_back(pointerEvent);
|
||||
VsyncStation::GetInstance().RequestVsync(VsyncStation::CallbackType::CALLBACK_INPUT, callback_);
|
||||
WLOGFI("Receive move event, windowId: %{public}d, action: %{public}d",
|
||||
window_->GetWindowId(), pointerEvent->GetPointerAction());
|
||||
if (pointerEventTemp != nullptr) {
|
||||
pointerEventTemp->MarkProcessed();
|
||||
}
|
||||
} else {
|
||||
WLOGI("HandlePointerEvent cosume non-move, windowId: %{public}d", window_->GetWindowId());
|
||||
WLOGFI("Dispatch non-move event, windowId: %{public}d, action: %{public}d",
|
||||
window_->GetWindowId(), pointerEvent->GetPointerAction());
|
||||
window_->ConsumePointerEvent(pointerEvent);
|
||||
pointerEvent->MarkProcessed();
|
||||
}
|
||||
@@ -76,14 +86,20 @@ void WindowInputChannel::HandlePointerEvent(std::shared_ptr<MMI::PointerEvent>&
|
||||
|
||||
void WindowInputChannel::OnVsync(int64_t timeStamp)
|
||||
{
|
||||
if (pointerEventPool_.empty()) {
|
||||
WLOGE("pointerEventPool_ is empty");
|
||||
std::shared_ptr<MMI::PointerEvent> pointerEvent;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mtx_);
|
||||
pointerEvent = moveEvent_;
|
||||
moveEvent_ = nullptr;
|
||||
}
|
||||
if (pointerEvent == nullptr) {
|
||||
WLOGFE("moveEvent_ is nullptr");
|
||||
return;
|
||||
}
|
||||
auto pointerEvent = pointerEventPool_.back();
|
||||
WLOGFI("Dispatch move event, windowId: %{public}d, action: %{public}d",
|
||||
window_->GetWindowId(), pointerEvent->GetPointerAction());
|
||||
window_->ConsumePointerEvent(pointerEvent);
|
||||
pointerEvent->MarkProcessed();
|
||||
pointerEventPool_.clear();
|
||||
}
|
||||
|
||||
void WindowInputChannel::SetInputListener(std::shared_ptr<MMI::IInputEventConsumer>& listener)
|
||||
@@ -96,7 +112,7 @@ bool WindowInputChannel::IsKeyboardEvent(const std::shared_ptr<MMI::KeyEvent>& k
|
||||
int32_t keyCode = keyEvent->GetKeyCode();
|
||||
bool isKeyFN = (keyCode == MMI::KeyEvent::KEYCODE_FN);
|
||||
bool isKeyboard = (keyCode >= MMI::KeyEvent::KEYCODE_0 && keyCode <= MMI::KeyEvent::KEYCODE_NUMPAD_RIGHT_PAREN);
|
||||
WLOGI("isKeyFN: %{public}d, isKeyboard: %{public}d", isKeyFN, isKeyboard);
|
||||
WLOGFI("isKeyFN: %{public}d, isKeyboard: %{public}d", isKeyFN, isKeyboard);
|
||||
return (isKeyFN || isKeyboard);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user