1e0dac50fSopenharmony_ci/* 2e0dac50fSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3e0dac50fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4e0dac50fSopenharmony_ci * you may not use this file except in compliance with the License. 5e0dac50fSopenharmony_ci * You may obtain a copy of the License at 6e0dac50fSopenharmony_ci * 7e0dac50fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8e0dac50fSopenharmony_ci * 9e0dac50fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10e0dac50fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11e0dac50fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12e0dac50fSopenharmony_ci * See the License for the specific language governing permissions and 13e0dac50fSopenharmony_ci * limitations under the License. 14e0dac50fSopenharmony_ci */ 15e0dac50fSopenharmony_ci 16e0dac50fSopenharmony_ci#include "window_input_channel.h" 17e0dac50fSopenharmony_ci#ifdef IMF_ENABLE 18e0dac50fSopenharmony_ci#include <input_method_controller.h> 19e0dac50fSopenharmony_ci#endif // IMF_ENABLE 20e0dac50fSopenharmony_ci#include "window_manager_hilog.h" 21e0dac50fSopenharmony_ci#include "window_helper.h" 22e0dac50fSopenharmony_ci 23e0dac50fSopenharmony_cinamespace OHOS { 24e0dac50fSopenharmony_cinamespace Rosen { 25e0dac50fSopenharmony_cinamespace { 26e0dac50fSopenharmony_ciconstexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "InputChannel"}; 27e0dac50fSopenharmony_ci} 28e0dac50fSopenharmony_ciWindowInputChannel::WindowInputChannel(const sptr<Window>& window): window_(window), isAvailable_(true) 29e0dac50fSopenharmony_ci{ 30e0dac50fSopenharmony_ci} 31e0dac50fSopenharmony_ci 32e0dac50fSopenharmony_ciWindowInputChannel::~WindowInputChannel() 33e0dac50fSopenharmony_ci{ 34e0dac50fSopenharmony_ci WLOGI("windowName: %{public}s, windowId: %{public}d", window_->GetWindowName().c_str(), window_->GetWindowId()); 35e0dac50fSopenharmony_ci window_->SetNeedRemoveWindowInputChannel(false); 36e0dac50fSopenharmony_ci} 37e0dac50fSopenharmony_ci 38e0dac50fSopenharmony_civoid WindowInputChannel::DispatchKeyEventCallback(std::shared_ptr<MMI::KeyEvent>& keyEvent, bool consumed) 39e0dac50fSopenharmony_ci{ 40e0dac50fSopenharmony_ci if (keyEvent == nullptr) { 41e0dac50fSopenharmony_ci WLOGFW("keyEvent is null"); 42e0dac50fSopenharmony_ci return; 43e0dac50fSopenharmony_ci } 44e0dac50fSopenharmony_ci 45e0dac50fSopenharmony_ci if (consumed) { 46e0dac50fSopenharmony_ci WLOGD("Input method has processed key event, id:%{public}d", keyEvent->GetId()); 47e0dac50fSopenharmony_ci return; 48e0dac50fSopenharmony_ci } 49e0dac50fSopenharmony_ci 50e0dac50fSopenharmony_ci if (window_ != nullptr) { 51e0dac50fSopenharmony_ci WLOGD("dispatch keyEvent to ACE"); 52e0dac50fSopenharmony_ci window_->ConsumeKeyEvent(keyEvent); 53e0dac50fSopenharmony_ci } else { 54e0dac50fSopenharmony_ci keyEvent->MarkProcessed(); 55e0dac50fSopenharmony_ci } 56e0dac50fSopenharmony_ci} 57e0dac50fSopenharmony_ci 58e0dac50fSopenharmony_ci__attribute__((no_sanitize("cfi"))) void WindowInputChannel::HandleKeyEvent( 59e0dac50fSopenharmony_ci std::shared_ptr<MMI::KeyEvent>& keyEvent) 60e0dac50fSopenharmony_ci{ 61e0dac50fSopenharmony_ci if (keyEvent == nullptr) { 62e0dac50fSopenharmony_ci WLOGFE("keyEvent is nullptr"); 63e0dac50fSopenharmony_ci return; 64e0dac50fSopenharmony_ci } 65e0dac50fSopenharmony_ci WLOGFD("Receive key event, Id: %{public}u, keyCode: %{public}d", 66e0dac50fSopenharmony_ci window_->GetWindowId(), keyEvent->GetKeyCode()); 67e0dac50fSopenharmony_ci if (window_->GetType() == WindowType::WINDOW_TYPE_DIALOG) { 68e0dac50fSopenharmony_ci if (keyEvent->GetAgentWindowId() != keyEvent->GetTargetWindowId()) { 69e0dac50fSopenharmony_ci window_->NotifyTouchDialogTarget(); 70e0dac50fSopenharmony_ci keyEvent->MarkProcessed(); 71e0dac50fSopenharmony_ci return; 72e0dac50fSopenharmony_ci } 73e0dac50fSopenharmony_ci if (keyEvent->GetKeyCode() == MMI::KeyEvent::KEYCODE_BACK) { 74e0dac50fSopenharmony_ci keyEvent->MarkProcessed(); 75e0dac50fSopenharmony_ci return; 76e0dac50fSopenharmony_ci } 77e0dac50fSopenharmony_ci } 78e0dac50fSopenharmony_ci bool isConsumed = window_->PreNotifyKeyEvent(keyEvent); 79e0dac50fSopenharmony_ci if (isConsumed) { 80e0dac50fSopenharmony_ci TLOGI(WmsLogTag::WMS_EVENT, "PreNotifyKeyEvent id:%{public}d isConsumed:%{public}d", 81e0dac50fSopenharmony_ci keyEvent->GetId(), static_cast<int>(isConsumed)); 82e0dac50fSopenharmony_ci return; 83e0dac50fSopenharmony_ci } 84e0dac50fSopenharmony_ci#ifdef IMF_ENABLE 85e0dac50fSopenharmony_ci bool isKeyboardEvent = IsKeyboardEvent(keyEvent); 86e0dac50fSopenharmony_ci if (isKeyboardEvent) { 87e0dac50fSopenharmony_ci WLOGD("Async dispatch keyEvent to input method"); 88e0dac50fSopenharmony_ci auto callback = [weakThis = wptr(this)] (std::shared_ptr<MMI::KeyEvent>& keyEvent, bool consumed) { 89e0dac50fSopenharmony_ci auto promoteThis = weakThis.promote(); 90e0dac50fSopenharmony_ci if (promoteThis == nullptr) { 91e0dac50fSopenharmony_ci keyEvent->MarkProcessed(); 92e0dac50fSopenharmony_ci WLOGFW("promoteThis is nullptr"); 93e0dac50fSopenharmony_ci return; 94e0dac50fSopenharmony_ci } 95e0dac50fSopenharmony_ci promoteThis->DispatchKeyEventCallback(keyEvent, consumed); 96e0dac50fSopenharmony_ci }; 97e0dac50fSopenharmony_ci auto ret = MiscServices::InputMethodController::GetInstance()->DispatchKeyEvent(keyEvent, callback); 98e0dac50fSopenharmony_ci if (ret != 0) { 99e0dac50fSopenharmony_ci WLOGFE("DispatchKeyEvent failed, ret:%{public}d, id:%{public}d", ret, keyEvent->GetId()); 100e0dac50fSopenharmony_ci DispatchKeyEventCallback(keyEvent, false); 101e0dac50fSopenharmony_ci } 102e0dac50fSopenharmony_ci return; 103e0dac50fSopenharmony_ci } 104e0dac50fSopenharmony_ci#endif // IMF_ENABLE 105e0dac50fSopenharmony_ci WLOGD("dispatch keyEvent to ACE"); 106e0dac50fSopenharmony_ci window_->ConsumeKeyEvent(keyEvent); 107e0dac50fSopenharmony_ci} 108e0dac50fSopenharmony_ci 109e0dac50fSopenharmony_civoid WindowInputChannel::HandlePointerEvent(std::shared_ptr<MMI::PointerEvent>& pointerEvent) 110e0dac50fSopenharmony_ci{ 111e0dac50fSopenharmony_ci if (pointerEvent == nullptr) { 112e0dac50fSopenharmony_ci TLOGE(WmsLogTag::WMS_EVENT, "pointerEvent is nullptr"); 113e0dac50fSopenharmony_ci return; 114e0dac50fSopenharmony_ci } 115e0dac50fSopenharmony_ci if (window_ == nullptr) { 116e0dac50fSopenharmony_ci TLOGE(WmsLogTag::WMS_EVENT, "window_ is nullptr, id:%{public}d", pointerEvent->GetId()); 117e0dac50fSopenharmony_ci return; 118e0dac50fSopenharmony_ci } 119e0dac50fSopenharmony_ci auto action = pointerEvent->GetPointerAction(); 120e0dac50fSopenharmony_ci TLOGD(WmsLogTag::WMS_EVENT, "Receive pointer event, Id: %{public}u, action: %{public}d", 121e0dac50fSopenharmony_ci window_->GetWindowId(), action); 122e0dac50fSopenharmony_ci 123e0dac50fSopenharmony_ci bool isPointDown = action == MMI::PointerEvent::POINTER_ACTION_DOWN || 124e0dac50fSopenharmony_ci action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN; 125e0dac50fSopenharmony_ci MMI::PointerEvent::PointerItem pointerItem; 126e0dac50fSopenharmony_ci bool isValidPointItem = pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem); 127e0dac50fSopenharmony_ci if ((window_->GetType() == WindowType::WINDOW_TYPE_DIALOG || 128e0dac50fSopenharmony_ci WindowHelper::IsModalSubWindow(window_->GetType(), window_->GetWindowFlags())) && 129e0dac50fSopenharmony_ci (pointerEvent->GetAgentWindowId() != pointerEvent->GetTargetWindowId()) && 130e0dac50fSopenharmony_ci action != MMI::PointerEvent::POINTER_ACTION_PULL_UP) { 131e0dac50fSopenharmony_ci if (isPointDown && isValidPointItem) { 132e0dac50fSopenharmony_ci window_->NotifyTouchDialogTarget(pointerItem.GetDisplayX(), pointerItem.GetDisplayY()); 133e0dac50fSopenharmony_ci } 134e0dac50fSopenharmony_ci pointerEvent->MarkProcessed(); 135e0dac50fSopenharmony_ci return; 136e0dac50fSopenharmony_ci } 137e0dac50fSopenharmony_ci TLOGD(WmsLogTag::WMS_EVENT, "Dispatch move event, windowId: %{public}u, action: %{public}d", 138e0dac50fSopenharmony_ci window_->GetWindowId(), action); 139e0dac50fSopenharmony_ci window_->ConsumePointerEvent(pointerEvent); 140e0dac50fSopenharmony_ci} 141e0dac50fSopenharmony_ci 142e0dac50fSopenharmony_civoid WindowInputChannel::Destroy() 143e0dac50fSopenharmony_ci{ 144e0dac50fSopenharmony_ci std::lock_guard<std::mutex> lock(mtx_); 145e0dac50fSopenharmony_ci WLOGI("Destroy WindowInputChannel, windowId:%{public}u", window_->GetWindowId()); 146e0dac50fSopenharmony_ci isAvailable_ = false; 147e0dac50fSopenharmony_ci} 148e0dac50fSopenharmony_ci 149e0dac50fSopenharmony_ciRect WindowInputChannel::GetWindowRect() 150e0dac50fSopenharmony_ci{ 151e0dac50fSopenharmony_ci if (window_ == nullptr) { 152e0dac50fSopenharmony_ci return { 0, 0, 0, 0 }; 153e0dac50fSopenharmony_ci } 154e0dac50fSopenharmony_ci return window_->GetRect(); 155e0dac50fSopenharmony_ci} 156e0dac50fSopenharmony_ci 157e0dac50fSopenharmony_cibool WindowInputChannel::IsKeyboardEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent) const 158e0dac50fSopenharmony_ci{ 159e0dac50fSopenharmony_ci int32_t keyCode = keyEvent->GetKeyCode(); 160e0dac50fSopenharmony_ci bool isKeyFN = (keyCode == MMI::KeyEvent::KEYCODE_FN); 161e0dac50fSopenharmony_ci bool isKeyBack = (keyCode == MMI::KeyEvent::KEYCODE_BACK); 162e0dac50fSopenharmony_ci bool isKeyboard = (keyCode >= MMI::KeyEvent::KEYCODE_0 && keyCode <= MMI::KeyEvent::KEYCODE_NUMPAD_RIGHT_PAREN); 163e0dac50fSopenharmony_ci bool isKeySound = (keyCode == MMI::KeyEvent::KEYCODE_SOUND); 164e0dac50fSopenharmony_ci TLOGD(WmsLogTag::WMS_EVENT, "isKeyFN:%{public}d, isKeyboard:%{public}d", isKeyFN, isKeyboard); 165e0dac50fSopenharmony_ci return (isKeyFN || isKeyboard || isKeyBack || isKeySound); 166e0dac50fSopenharmony_ci} 167e0dac50fSopenharmony_ci} 168e0dac50fSopenharmony_ci} 169