1 /*
2 * Copyright (c) 2023 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 "session/container/include/window_event_channel.h"
17 #include "scene_board_judgement.h"
18
19 #include <functional>
20 #include <utility>
21
22 #include <axis_event.h>
23 #include <key_event.h>
24 #include <pointer_event.h>
25
26 #include "window_manager_hilog.h"
27 #include "session_permission.h"
28
29 namespace OHOS::Rosen {
30 namespace {
31 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowEventChannel" };
32 const std::set<int32_t> VALID_KEYCODE_FOR_CONSTRAINED_EMBEDDED_UIEXTENSION({ MMI::KeyEvent::KEYCODE_HOME,
33 MMI::KeyEvent::KEYCODE_TAB, MMI::KeyEvent::KEYCODE_ESCAPE, MMI::KeyEvent::KEYCODE_DPAD_UP,
34 MMI::KeyEvent::KEYCODE_DPAD_DOWN, MMI::KeyEvent::KEYCODE_DPAD_LEFT, MMI::KeyEvent::KEYCODE_DPAD_RIGHT,
35 MMI::KeyEvent::KEYCODE_MOVE_HOME, MMI::KeyEvent::KEYCODE_MOVE_END });
36 constexpr int32_t SIZE_TWO = 2;
37 }
38
OnTransferKeyEventForConsumed(int32_t keyEventId,bool isPreImeEvent,bool isConsumed,WSError retCode)39 void WindowEventChannelListenerProxy::OnTransferKeyEventForConsumed(int32_t keyEventId, bool isPreImeEvent,
40 bool isConsumed, WSError retCode)
41 {
42 MessageParcel data;
43 MessageParcel reply;
44 MessageOption option(MessageOption::TF_ASYNC);
45 if (!data.WriteInterfaceToken(GetDescriptor())) {
46 TLOGE(WmsLogTag::WMS_EVENT, "WriteInterfaceToken failed");
47 return;
48 }
49 if (!data.WriteInt32(keyEventId)) {
50 TLOGE(WmsLogTag::WMS_EVENT, "keyEventId write failed.");
51 return;
52 }
53 if (!data.WriteBool(isPreImeEvent)) {
54 TLOGE(WmsLogTag::WMS_EVENT, "isPreImeEvent write failed.");
55 return;
56 }
57 if (!data.WriteBool(isConsumed)) {
58 TLOGE(WmsLogTag::WMS_EVENT, "isConsumed write failed.");
59 return;
60 }
61 if (!data.WriteInt32(static_cast<int32_t>(retCode))) {
62 TLOGE(WmsLogTag::WMS_EVENT, "retCode write failed.");
63 return;
64 }
65 sptr<IRemoteObject> remote = Remote();
66 if (remote == nullptr) {
67 TLOGE(WmsLogTag::WMS_EVENT, "remote is null");
68 return;
69 }
70 if (remote->SendRequest(static_cast<uint32_t>(
71 WindowEventChannelListenerMessage::TRANS_ID_ON_TRANSFER_KEY_EVENT_FOR_CONSUMED_ASYNC),
72 data, reply, option) != ERR_NONE) {
73 TLOGE(WmsLogTag::WMS_EVENT, "SendRequest failed");
74 }
75 }
76
SetIsUIExtension(bool isUIExtension)77 void WindowEventChannel::SetIsUIExtension(bool isUIExtension)
78 {
79 isUIExtension_ = isUIExtension;
80 }
81
SetUIExtensionUsage(UIExtensionUsage uiExtensionUsage)82 void WindowEventChannel::SetUIExtensionUsage(UIExtensionUsage uiExtensionUsage)
83 {
84 uiExtensionUsage_ = uiExtensionUsage;
85 }
86
TransferKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent)87 WSError WindowEventChannel::TransferKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
88 {
89 WLOGFD("WindowEventChannel receive key event");
90 PrintKeyEvent(keyEvent);
91 bool isConsumed = false;
92 return TransferKeyEventForConsumed(keyEvent, isConsumed);
93 }
94
TransferPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)95 WSError WindowEventChannel::TransferPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
96 {
97 WLOGFD("WindowEventChannel receive pointer event");
98 if (uiExtensionUsage_ == UIExtensionUsage::PREVIEW_EMBEDDED) {
99 TLOGD(WmsLogTag::WMS_EVENT, "Preview uiext does not handle event");
100 return WSError::WS_OK;
101 }
102 PrintPointerEvent(pointerEvent);
103 if (SceneBoardJudgement::IsSceneBoardEnabled() && isUIExtension_ &&
104 (uiExtensionUsage_ == UIExtensionUsage::MODAL ||
105 uiExtensionUsage_ == UIExtensionUsage::CONSTRAINED_EMBEDDED)) {
106 if (!SessionPermission::IsSystemCalling()) {
107 TLOGE(WmsLogTag::WMS_EVENT, "Point event blocked because of modal/constrained UIExtension:%{public}u",
108 uiExtensionUsage_);
109 return WSError::WS_ERROR_INVALID_PERMISSION;
110 } else {
111 TLOGW(WmsLogTag::WMS_EVENT, "SystemCalling UIExtension:%{public}u", uiExtensionUsage_);
112 }
113 }
114 if (!sessionStage_) {
115 WLOGFE("session stage is null!");
116 return WSError::WS_ERROR_NULLPTR;
117 }
118 if (pointerEvent == nullptr) {
119 WLOGFE("PointerEvent is null!");
120 return WSError::WS_ERROR_NULLPTR;
121 }
122 auto pointerAction = pointerEvent->GetPointerAction();
123 if (pointerAction == MMI::PointerEvent::POINTER_ACTION_ENTER_WINDOW ||
124 pointerAction == MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW ||
125 pointerAction == MMI::PointerEvent::POINTER_ACTION_PULL_IN_WINDOW ||
126 pointerAction == MMI::PointerEvent::POINTER_ACTION_PULL_OUT_WINDOW) {
127 WLOGFI("InputTracking id:%{public}d, Dispatch by skipping receipt, action:%{public}s,"
128 " persistentId:%{public}d", pointerEvent->GetId(),
129 pointerEvent->DumpPointerAction(), sessionStage_->GetPersistentId());
130 }
131 sessionStage_->NotifyPointerEvent(pointerEvent);
132 return WSError::WS_OK;
133 }
134
TransferBackpressedEventForConsumed(bool & isConsumed)135 WSError WindowEventChannel::TransferBackpressedEventForConsumed(bool& isConsumed)
136 {
137 WLOGFD("WindowEventChannel receive backpressed event");
138 if (!sessionStage_) {
139 WLOGFE("session stage is null!");
140 return WSError::WS_ERROR_NULLPTR;
141 }
142 sessionStage_->NotifyBackpressedEvent(isConsumed);
143 return WSError::WS_OK;
144 }
145
TransferKeyEventForConsumed(const std::shared_ptr<MMI::KeyEvent> & keyEvent,bool & isConsumed,bool isPreImeEvent)146 WSError WindowEventChannel::TransferKeyEventForConsumed(
147 const std::shared_ptr<MMI::KeyEvent>& keyEvent, bool& isConsumed, bool isPreImeEvent)
148 {
149 WLOGFD("WindowEventChannel receive key event");
150 if (!sessionStage_) {
151 WLOGFE("session stage is null!");
152 return WSError::WS_ERROR_NULLPTR;
153 }
154 if (keyEvent == nullptr) {
155 WLOGFE("keyEvent is nullptr");
156 return WSError::WS_ERROR_NULLPTR;
157 }
158 if (SceneBoardJudgement::IsSceneBoardEnabled() && isUIExtension_ && IsUIExtensionKeyEventBlocked(keyEvent)) {
159 return WSError::WS_ERROR_INVALID_PERMISSION;
160 }
161 if (isPreImeEvent) {
162 isConsumed = sessionStage_->NotifyOnKeyPreImeEvent(keyEvent);
163 TLOGI(WmsLogTag::WMS_EVENT, "NotifyOnKeyPreImeEvent id:%{public}d isConsumed:%{public}d",
164 keyEvent->GetId(), static_cast<int>(isConsumed));
165 return WSError::WS_OK;
166 }
167 sessionStage_->NotifyKeyEvent(keyEvent, isConsumed);
168 keyEvent->MarkProcessed();
169 return WSError::WS_OK;
170 }
171
IsUIExtensionKeyEventBlocked(const std::shared_ptr<MMI::KeyEvent> & keyEvent)172 bool WindowEventChannel::IsUIExtensionKeyEventBlocked(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
173 {
174 if (uiExtensionUsage_ == UIExtensionUsage::MODAL) {
175 if (!SessionPermission::IsSystemCalling()) {
176 TLOGE(WmsLogTag::WMS_EVENT, "Unsupported keyCode due to Modal UIExtension.");
177 return true;
178 } else {
179 TLOGW(WmsLogTag::WMS_EVENT, "SystemCalling UIExtension.");
180 return false;
181 }
182 }
183 if (uiExtensionUsage_ == UIExtensionUsage::CONSTRAINED_EMBEDDED) {
184 auto keyCode = keyEvent->GetKeyCode();
185 if (VALID_KEYCODE_FOR_CONSTRAINED_EMBEDDED_UIEXTENSION.find(keyCode) ==
186 VALID_KEYCODE_FOR_CONSTRAINED_EMBEDDED_UIEXTENSION.end()) {
187 TLOGE(WmsLogTag::WMS_EVENT, "Unsupported keyCode due to Constrained embedded UIExtension.");
188 return true;
189 }
190 auto pressedKeys = keyEvent->GetPressedKeys();
191 if (pressedKeys.size() == SIZE_TWO && keyCode == MMI::KeyEvent::KEYCODE_TAB &&
192 (pressedKeys[0] == MMI::KeyEvent::KEYCODE_SHIFT_LEFT ||
193 pressedKeys[0] == MMI::KeyEvent::KEYCODE_SHIFT_RIGHT)) {
194 // only allows combined keys SHIFT+TAB
195 return false;
196 } else if (pressedKeys.size() >= SIZE_TWO) {
197 TLOGE(WmsLogTag::WMS_EVENT, "Invalid size of PressedKeys due to Constrained embedded UIExtension.");
198 return true;
199 }
200 }
201 return false;
202 }
203
TransferKeyEventForConsumedAsync(const std::shared_ptr<MMI::KeyEvent> & keyEvent,bool isPreImeEvent,const sptr<IRemoteObject> & listener)204 WSError WindowEventChannel::TransferKeyEventForConsumedAsync(
205 const std::shared_ptr<MMI::KeyEvent>& keyEvent, bool isPreImeEvent, const sptr<IRemoteObject>& listener)
206 {
207 bool isConsumed = false;
208 auto ret = TransferKeyEventForConsumed(keyEvent, isConsumed, isPreImeEvent);
209 auto channelListener = iface_cast<IWindowEventChannelListener>(listener);
210 if (channelListener == nullptr) {
211 TLOGE(WmsLogTag::WMS_EVENT, "listener is null.");
212 return ret;
213 }
214
215 auto keyEventId = keyEvent->GetId();
216 TLOGD(WmsLogTag::WMS_EVENT, "finished with isConsumed:%{public}d ret:%{public}d at PreIme:%{public}d id:%{public}d",
217 isConsumed, ret, isPreImeEvent, keyEventId);
218 channelListener->OnTransferKeyEventForConsumed(keyEventId, isPreImeEvent, isConsumed, ret);
219 return ret;
220 }
221
TransferFocusActiveEvent(bool isFocusActive)222 WSError WindowEventChannel::TransferFocusActiveEvent(bool isFocusActive)
223 {
224 WLOGFD("WindowEventChannel receive focus active event");
225 if (!sessionStage_) {
226 WLOGFE("session stage is null!");
227 return WSError::WS_ERROR_NULLPTR;
228 }
229 sessionStage_->NotifyFocusActiveEvent(isFocusActive);
230 return WSError::WS_OK;
231 }
232
PrintKeyEvent(const std::shared_ptr<MMI::KeyEvent> & event)233 void WindowEventChannel::PrintKeyEvent(const std::shared_ptr<MMI::KeyEvent>& event)
234 {
235 if (event == nullptr) {
236 WLOGFE("event is nullptr");
237 return;
238 }
239 std::vector<MMI::KeyEvent::KeyItem> eventItems = event->GetKeyItems();
240 WLOGFD("KeyCode:%{public}d,KeyAction:%{public}s,keyItemsCount:%{public}zu", event->GetKeyCode(),
241 MMI::KeyEvent::ActionToString(event->GetKeyAction()), eventItems.size());
242 for (const auto &item : eventItems) {
243 WLOGFD("KeyCode:%{public}d,IsPressed:%{public}d,GetUnicode:%{public}d",
244 item.GetKeyCode(), item.IsPressed(), item.GetUnicode());
245 }
246 }
247
PrintPointerEvent(const std::shared_ptr<MMI::PointerEvent> & event)248 void WindowEventChannel::PrintPointerEvent(const std::shared_ptr<MMI::PointerEvent>& event)
249 {
250 if (event == nullptr) {
251 WLOGFE("event is nullptr");
252 return;
253 }
254 std::vector<int32_t> pointerIds = event->GetPointerIds();
255 std::string str;
256 std::vector<uint8_t> buffer = event->GetBuffer();
257 for (const auto &buff : buffer) {
258 str += std::to_string(buff);
259 }
260 auto pointerAction = event->GetPointerAction();
261 if (pointerAction == MMI::PointerEvent::POINTER_ACTION_MOVE ||
262 pointerAction == MMI::PointerEvent::POINTER_ACTION_PULL_MOVE) {
263 WLOGFD("PointerAction:%{public}s,SourceType:%{public}s,ButtonId:%{public}d,"
264 "VerticalAxisValue:%{public}.2f,HorizontalAxisValue:%{public}.2f,"
265 "PointerId:%{public}d,PointerCount:%{public}zu,EventNumber:%{public}d,"
266 "BufferCount:%{public}zu,Buffer:%{public}s",
267 event->DumpPointerAction(), event->DumpSourceType(), event->GetButtonId(),
268 event->GetAxisValue(MMI::PointerEvent::AXIS_TYPE_SCROLL_VERTICAL),
269 event->GetAxisValue(MMI::PointerEvent::AXIS_TYPE_SCROLL_HORIZONTAL),
270 event->GetPointerId(), pointerIds.size(), event->GetId(), buffer.size(), str.c_str());
271
272 for (const auto &pointerId : pointerIds) {
273 MMI::PointerEvent::PointerItem item;
274 if (!event->GetPointerItem(pointerId, item)) {
275 WLOGFE("Invalid pointer: %{public}d.", pointerId);
276 return;
277 }
278 TLOGD(WmsLogTag::WMS_EVENT, "pointerId:%{public}d,DownTime:%{public}" PRId64 ",IsPressed:%{public}d,"
279 "DisplayX:%{private}d,DisplayY:%{private}d,WindowX:%{private}d,WindowY:%{private}d",
280 pointerId, item.GetDownTime(), item.IsPressed(), item.GetDisplayX(), item.GetDisplayY(),
281 item.GetWindowX(), item.GetWindowY());
282 }
283 } else {
284 PrintInfoPointerEvent(event);
285 }
286 }
287
PrintInfoPointerEvent(const std::shared_ptr<MMI::PointerEvent> & event)288 void WindowEventChannel::PrintInfoPointerEvent(const std::shared_ptr<MMI::PointerEvent>& event)
289 {
290 if (event == nullptr) {
291 WLOGFE("event is nullptr");
292 return;
293 }
294 std::vector<int32_t> pointerIds = event->GetPointerIds();
295 std::string str;
296 std::vector<uint8_t> buffer = event->GetBuffer();
297 for (const auto &buff : buffer) {
298 str += std::to_string(buff);
299 }
300 WLOGFI("PointerAction:%{public}s,SourceType:%{public}s,ButtonId:%{public}d,"
301 "VerticalAxisValue:%{public}.2f,HorizontalAxisValue:%{public}.2f,"
302 "PointerId:%{public}d,PointerCount:%{public}zu,EventNumber:%{public}d,"
303 "BufferCount:%{public}zu,Buffer:%{public}s",
304 event->DumpPointerAction(), event->DumpSourceType(), event->GetButtonId(),
305 event->GetAxisValue(MMI::PointerEvent::AXIS_TYPE_SCROLL_VERTICAL),
306 event->GetAxisValue(MMI::PointerEvent::AXIS_TYPE_SCROLL_HORIZONTAL),
307 event->GetPointerId(), pointerIds.size(), event->GetId(), buffer.size(), str.c_str());
308
309 for (const auto &pointerId : pointerIds) {
310 MMI::PointerEvent::PointerItem item;
311 if (!event->GetPointerItem(pointerId, item)) {
312 WLOGFE("Invalid pointer: %{public}d.", pointerId);
313 return;
314 }
315 WLOGFI("pointerId:%{public}d,DownTime:%{public}" PRId64 ",IsPressed:%{public}d",
316 pointerId, item.GetDownTime(), item.IsPressed());
317 }
318 }
319
TransferFocusState(bool focusState)320 WSError WindowEventChannel::TransferFocusState(bool focusState)
321 {
322 WLOGFD("WindowEventChannel receive focus state event: %{public}d", static_cast<int>(focusState));
323 if (!sessionStage_) {
324 WLOGFE("session stage is null!");
325 return WSError::WS_ERROR_NULLPTR;
326 }
327 sessionStage_->NotifyFocusStateEvent(focusState);
328 return WSError::WS_OK;
329 }
330
TransferAccessibilityHoverEvent(float pointX,float pointY,int32_t sourceType,int32_t eventType,int64_t timeMs)331 WSError WindowEventChannel::TransferAccessibilityHoverEvent(float pointX, float pointY, int32_t sourceType,
332 int32_t eventType, int64_t timeMs)
333 {
334 if (!sessionStage_) {
335 TLOGE(WmsLogTag::WMS_UIEXT, "session stage is null.");
336 return WSError::WS_ERROR_NULLPTR;
337 }
338 return sessionStage_->NotifyAccessibilityHoverEvent(pointX, pointY, sourceType, eventType, timeMs);
339 }
340
TransferAccessibilityChildTreeRegister(uint32_t windowId,int32_t treeId,int64_t accessibilityId)341 WSError WindowEventChannel::TransferAccessibilityChildTreeRegister(
342 uint32_t windowId, int32_t treeId, int64_t accessibilityId)
343 {
344 if (!sessionStage_) {
345 TLOGE(WmsLogTag::WMS_UIEXT, "session stage is null.");
346 return WSError::WS_ERROR_NULLPTR;
347 }
348 return sessionStage_->NotifyAccessibilityChildTreeRegister(windowId, treeId, accessibilityId);
349 }
350
TransferAccessibilityChildTreeUnregister()351 WSError WindowEventChannel::TransferAccessibilityChildTreeUnregister()
352 {
353 if (!sessionStage_) {
354 TLOGE(WmsLogTag::WMS_UIEXT, "session stage is null.");
355 return WSError::WS_ERROR_NULLPTR;
356 }
357 return sessionStage_->NotifyAccessibilityChildTreeUnregister();
358 }
359
TransferAccessibilityDumpChildInfo(const std::vector<std::string> & params,std::vector<std::string> & info)360 WSError WindowEventChannel::TransferAccessibilityDumpChildInfo(
361 const std::vector<std::string>& params, std::vector<std::string>& info)
362 {
363 if (!sessionStage_) {
364 TLOGE(WmsLogTag::WMS_UIEXT, "session stage is null.");
365 return WSError::WS_ERROR_NULLPTR;
366 }
367 #ifdef ACCESSIBILITY_DUMP_FOR_TEST
368 return sessionStage_->NotifyAccessibilityDumpChildInfo(params, info);
369 #else
370 info.emplace_back("not support in user build variant");
371 return WSError::WS_OK;
372 #endif
373 }
374 } // namespace OHOS::Rosen
375