• 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 "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 #include "window_helper.h"
22 
23 namespace OHOS {
24 namespace Rosen {
25 namespace {
26 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "InputChannel"};
27 }
WindowInputChannel(const sptr<Window> & window)28 WindowInputChannel::WindowInputChannel(const sptr<Window>& window): window_(window), isAvailable_(true)
29 {
30 }
31 
~WindowInputChannel()32 WindowInputChannel::~WindowInputChannel()
33 {
34     WLOGI("windowName: %{public}s, windowId: %{public}d", window_->GetWindowName().c_str(), window_->GetWindowId());
35     window_->SetNeedRemoveWindowInputChannel(false);
36 }
37 
DispatchKeyEventCallback(std::shared_ptr<MMI::KeyEvent> & keyEvent,bool consumed)38 void WindowInputChannel::DispatchKeyEventCallback(std::shared_ptr<MMI::KeyEvent>& keyEvent, bool consumed)
39 {
40     if (keyEvent == nullptr) {
41         WLOGFW("keyEvent is null");
42         return;
43     }
44 
45     if (consumed) {
46         WLOGD("Input method has processed key event, id:%{public}d", keyEvent->GetId());
47         return;
48     }
49 
50     if (window_ != nullptr) {
51         WLOGD("dispatch keyEvent to ACE");
52         window_->ConsumeKeyEvent(keyEvent);
53     } else {
54         keyEvent->MarkProcessed();
55     }
56 }
57 
HandleKeyEvent(std::shared_ptr<MMI::KeyEvent> & keyEvent)58 __attribute__((no_sanitize("cfi"))) void WindowInputChannel::HandleKeyEvent(
59     std::shared_ptr<MMI::KeyEvent>& keyEvent)
60 {
61     if (keyEvent == nullptr) {
62         WLOGFE("keyEvent is nullptr");
63         return;
64     }
65 
66     if (window_ == nullptr) {
67         TLOGE(WmsLogTag::WMS_EVENT, "window_ is nullptr");
68         return;
69     }
70     WLOGFD("Receive key event, Id: %{public}u, keyCode: %{public}d",
71         window_->GetWindowId(), keyEvent->GetKeyCode());
72     if (window_->GetType() == WindowType::WINDOW_TYPE_DIALOG) {
73         if (keyEvent->GetAgentWindowId() != keyEvent->GetTargetWindowId()) {
74             window_->NotifyTouchDialogTarget();
75             keyEvent->MarkProcessed();
76             return;
77         }
78         if (keyEvent->GetKeyCode() == MMI::KeyEvent::KEYCODE_BACK) {
79             if (keyEvent->GetKeyAction() == MMI::KeyEvent::KEY_ACTION_UP &&
80                 window_->IsDialogSessionBackGestureEnabled()) {
81                 window_->ConsumeBackEvent();
82             }
83             keyEvent->MarkProcessed();
84             return;
85         }
86     }
87     bool isConsumed = window_->PreNotifyKeyEvent(keyEvent);
88     if (isConsumed) {
89         TLOGI(WmsLogTag::WMS_EVENT, "PreNotifyKeyEvent id:%{public}d isConsumed:%{public}d",
90             keyEvent->GetId(), static_cast<int>(isConsumed));
91         return;
92     }
93 #ifdef IMF_ENABLE
94     bool isKeyboardEvent = IsKeyboardEvent(keyEvent);
95     if (isKeyboardEvent) {
96         WLOGD("Async dispatch keyEvent to input method");
97         auto callback = [weakThis = wptr(this)] (std::shared_ptr<MMI::KeyEvent>& keyEvent, bool consumed) {
98             auto promoteThis = weakThis.promote();
99             if (promoteThis == nullptr) {
100                 keyEvent->MarkProcessed();
101                 WLOGFW("promoteThis is nullptr");
102                 return;
103             }
104             promoteThis->DispatchKeyEventCallback(keyEvent, consumed);
105         };
106         auto ret = MiscServices::InputMethodController::GetInstance()->DispatchKeyEvent(keyEvent, callback);
107         if (ret != 0) {
108             TLOGI(WmsLogTag::WMS_EVENT, "DispatchKeyEvent ret:%{public}d, id:%{public}d", ret, keyEvent->GetId());
109             DispatchKeyEventCallback(keyEvent, false);
110         }
111         return;
112     }
113 #endif // IMF_ENABLE
114     WLOGD("dispatch keyEvent to ACE");
115     window_->ConsumeKeyEvent(keyEvent);
116 }
117 
ProcAncoEvent(std::shared_ptr<MMI::PointerEvent> & pointerEvent)118 void WindowInputChannel::ProcAncoEvent(std::shared_ptr<MMI::PointerEvent>& pointerEvent)
119 {
120     auto action = pointerEvent->GetPointerAction();
121     bool isPointDown = ((action == MMI::PointerEvent::POINTER_ACTION_DOWN) ||
122         (action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN));
123     if (!isPointDown) {
124         return;
125     }
126 
127     MMI::PointerEvent::PointerItem pointerItem;
128     bool ret = pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem);
129     if (!ret) {
130         TLOGE(WmsLogTag::WMS_EVENT, "get item failed, %{public}d", pointerEvent->GetId());
131         return;
132     }
133 
134     auto x = pointerItem.GetDisplayX();
135     auto y = pointerItem.GetDisplayY();
136     window_->OnPointDown(pointerEvent->GetId(), x, y);
137 }
138 
HandlePointerEvent(std::shared_ptr<MMI::PointerEvent> & pointerEvent)139 void WindowInputChannel::HandlePointerEvent(std::shared_ptr<MMI::PointerEvent>& pointerEvent)
140 {
141     if (pointerEvent == nullptr) {
142         TLOGE(WmsLogTag::WMS_EVENT, "pointerEvent is nullptr");
143         return;
144     }
145     if (window_ == nullptr) {
146         TLOGE(WmsLogTag::WMS_EVENT, "window_ is nullptr, id:%{public}d", pointerEvent->GetId());
147         return;
148     }
149 
150     if (window_->IsAnco()) {
151         ProcAncoEvent(pointerEvent);
152         pointerEvent->MarkProcessed();
153         return;
154     }
155 
156     auto action = pointerEvent->GetPointerAction();
157     TLOGD(WmsLogTag::WMS_EVENT, "Receive pointer event, Id: %{public}u, action: %{public}d",
158         window_->GetWindowId(), action);
159 
160     bool isPointDown = action == MMI::PointerEvent::POINTER_ACTION_DOWN ||
161         action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN;
162     MMI::PointerEvent::PointerItem pointerItem;
163     bool isValidPointItem = pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem);
164     if ((window_->GetType() == WindowType::WINDOW_TYPE_DIALOG ||
165          WindowHelper::IsModalSubWindow(window_->GetType(), window_->GetWindowFlags()) ||
166          WindowHelper::IsModalMainWindow(window_->GetType(), window_->GetWindowFlags())) &&
167         pointerEvent->GetAgentWindowId() != pointerEvent->GetTargetWindowId() &&
168         action != MMI::PointerEvent::POINTER_ACTION_PULL_UP) {
169         if (isPointDown && isValidPointItem) {
170             window_->NotifyTouchDialogTarget(pointerItem.GetDisplayX(), pointerItem.GetDisplayY());
171         }
172         pointerEvent->MarkProcessed();
173         return;
174     }
175     TLOGD(WmsLogTag::WMS_EVENT, "Dispatch move event, windowId: %{public}u, action: %{public}d",
176         window_->GetWindowId(), action);
177     window_->ConsumePointerEvent(pointerEvent);
178     window_->SetTouchEvent(action);
179 }
180 
Destroy()181 void WindowInputChannel::Destroy()
182 {
183     std::lock_guard<std::mutex> lock(mtx_);
184     WLOGI("Destroy WindowInputChannel, windowId:%{public}u", window_->GetWindowId());
185     isAvailable_ = false;
186 }
187 
GetWindowRect()188 Rect WindowInputChannel::GetWindowRect()
189 {
190     if (window_ == nullptr) {
191         return { 0, 0, 0, 0 };
192     }
193     return window_->GetRect();
194 }
195 
IsKeyboardEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent) const196 bool WindowInputChannel::IsKeyboardEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent) const
197 {
198     int32_t keyCode = keyEvent->GetKeyCode();
199     bool isKeyFN = (keyCode == MMI::KeyEvent::KEYCODE_FN);
200     bool isKeyBack = (keyCode == MMI::KeyEvent::KEYCODE_BACK);
201     bool isKeyboard = (keyCode >= MMI::KeyEvent::KEYCODE_0 && keyCode <= MMI::KeyEvent::KEYCODE_NUMPAD_RIGHT_PAREN);
202     bool isKeySound = (keyCode == MMI::KeyEvent::KEYCODE_SOUND);
203     TLOGD(WmsLogTag::WMS_EVENT, "isKeyFN:%{public}d, isKeyboard:%{public}d", isKeyFN, isKeyboard);
204     return (isKeyFN || isKeyboard || isKeyBack || isKeySound);
205 }
206 }
207 }
208