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 "window_input_channel.h"
17 #ifdef IMF_ENABLE
18 #include <input_method_controller.h>
19 #endif // IMF_ENABLE
20 #include "window_manager_hilog.h"
21
22 namespace OHOS {
23 namespace Rosen {
24 namespace {
25 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "InputChannel"};
26 }
WindowInputChannel(const sptr<Window> & window)27 WindowInputChannel::WindowInputChannel(const sptr<Window>& window): window_(window), isAvailable_(true)
28 {
29 }
30
~WindowInputChannel()31 WindowInputChannel::~WindowInputChannel()
32 {
33 WLOGI("windowName: %{public}s, windowId: %{public}d", window_->GetWindowName().c_str(), window_->GetWindowId());
34 window_->SetNeedRemoveWindowInputChannel(false);
35 }
36
DispatchKeyEventCallback(std::shared_ptr<MMI::KeyEvent> & keyEvent,bool consumed)37 void WindowInputChannel::DispatchKeyEventCallback(std::shared_ptr<MMI::KeyEvent>& keyEvent, bool consumed)
38 {
39 if (keyEvent == nullptr) {
40 WLOGFW("keyEvent is null");
41 return;
42 }
43
44 if (consumed) {
45 WLOGD("Input method has processed key event, id:%{public}d", keyEvent->GetId());
46 return;
47 }
48
49 if (window_ != nullptr) {
50 WLOGD("dispatch keyEvent to ACE");
51 window_->ConsumeKeyEvent(keyEvent);
52 } else {
53 keyEvent->MarkProcessed();
54 }
55 }
56
HandleKeyEvent(std::shared_ptr<MMI::KeyEvent> & keyEvent)57 void WindowInputChannel::HandleKeyEvent(std::shared_ptr<MMI::KeyEvent>& keyEvent)
58 {
59 if (keyEvent == nullptr) {
60 WLOGFE("keyEvent is nullptr");
61 return;
62 }
63 WLOGFD("Receive key event, Id: %{public}u, keyCode: %{public}d",
64 window_->GetWindowId(), keyEvent->GetKeyCode());
65 if (window_->GetType() == WindowType::WINDOW_TYPE_DIALOG) {
66 if (keyEvent->GetAgentWindowId() != keyEvent->GetTargetWindowId()) {
67 window_->NotifyTouchDialogTarget();
68 keyEvent->MarkProcessed();
69 return;
70 }
71 if (keyEvent->GetKeyCode() == MMI::KeyEvent::KEYCODE_BACK) {
72 keyEvent->MarkProcessed();
73 return;
74 }
75 }
76
77 #ifdef IMF_ENABLE
78 bool isKeyboardEvent = IsKeyboardEvent(keyEvent);
79 if (isKeyboardEvent) {
80 WLOGD("Async dispatch keyEvent to input method");
81 auto callback = [weakThis = wptr(this)] (std::shared_ptr<MMI::KeyEvent>& keyEvent, bool consumed) {
82 auto promoteThis = weakThis.promote();
83 if (promoteThis == nullptr) {
84 keyEvent->MarkProcessed();
85 WLOGFW("promoteThis is nullptr");
86 return;
87 }
88 promoteThis->DispatchKeyEventCallback(keyEvent, consumed);
89 };
90 auto ret = MiscServices::InputMethodController::GetInstance()->DispatchKeyEvent(keyEvent, callback);
91 if (ret != 0) {
92 WLOGFE("DispatchKeyEvent failed, ret:%{public}d, id:%{public}d", ret, keyEvent->GetId());
93 keyEvent->MarkProcessed();
94 }
95 return;
96 }
97 #endif // IMF_ENABLE
98 WLOGD("dispatch keyEvent to ACE");
99 window_->ConsumeKeyEvent(keyEvent);
100 }
101
HandlePointerEvent(std::shared_ptr<MMI::PointerEvent> & pointerEvent)102 void WindowInputChannel::HandlePointerEvent(std::shared_ptr<MMI::PointerEvent>& pointerEvent)
103 {
104 if (pointerEvent == nullptr) {
105 WLOGFE("pointerEvent is nullptr");
106 return;
107 }
108 WLOGFD("Receive pointer event, Id: %{public}u, action: %{public}d",
109 window_->GetWindowId(), pointerEvent->GetPointerAction());
110 if ((window_->GetType() == WindowType::WINDOW_TYPE_DIALOG) &&
111 (pointerEvent->GetAgentWindowId() != pointerEvent->GetTargetWindowId())) {
112 if (pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_DOWN ||
113 pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
114 MMI::PointerEvent::PointerItem pointerItem;
115 if (pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
116 window_->NotifyTouchDialogTarget(pointerItem.GetDisplayX(), pointerItem.GetDisplayY());
117 }
118 }
119 pointerEvent->MarkProcessed();
120 return;
121 }
122 WLOGFD("Dispatch move event, windowId: %{public}u, action: %{public}d",
123 window_->GetWindowId(), pointerEvent->GetPointerAction());
124 window_->ConsumePointerEvent(pointerEvent);
125 }
126
Destroy()127 void WindowInputChannel::Destroy()
128 {
129 std::lock_guard<std::mutex> lock(mtx_);
130 WLOGI("Destroy WindowInputChannel, windowId:%{public}u", window_->GetWindowId());
131 isAvailable_ = false;
132 }
133
IsKeyboardEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent) const134 bool WindowInputChannel::IsKeyboardEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent) const
135 {
136 int32_t keyCode = keyEvent->GetKeyCode();
137 bool isKeyFN = (keyCode == MMI::KeyEvent::KEYCODE_FN);
138 bool isKeyBack = (keyCode == MMI::KeyEvent::KEYCODE_BACK);
139 bool isKeyboard = (keyCode >= MMI::KeyEvent::KEYCODE_0 && keyCode <= MMI::KeyEvent::KEYCODE_NUMPAD_RIGHT_PAREN);
140 WLOGI("isKeyFN: %{public}d, isKeyboard: %{public}d", isKeyFN, isKeyboard);
141 return (isKeyFN || isKeyboard || isKeyBack);
142 }
143 }
144 }
145