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 PrintPointerEvent(pointerEvent);
99 if (SceneBoardJudgement::IsSceneBoardEnabled() && isUIExtension_ &&
100 (uiExtensionUsage_ == UIExtensionUsage::MODAL ||
101 uiExtensionUsage_ == UIExtensionUsage::CONSTRAINED_EMBEDDED)) {
102 if (!SessionPermission::IsSystemCalling()) {
103 TLOGE(WmsLogTag::WMS_EVENT, "Point event blocked because of modal/constrained UIExtension:%{public}u",
104 uiExtensionUsage_);
105 return WSError::WS_ERROR_INVALID_PERMISSION;
106 } else {
107 TLOGW(WmsLogTag::WMS_EVENT, "SystemCalling UIExtension:%{public}u", uiExtensionUsage_);
108 }
109 }
110 if (!sessionStage_) {
111 WLOGFE("session stage is null!");
112 return WSError::WS_ERROR_NULLPTR;
113 }
114 if (pointerEvent == nullptr) {
115 WLOGFE("PointerEvent is null!");
116 return WSError::WS_ERROR_NULLPTR;
117 }
118 auto pointerAction = pointerEvent->GetPointerAction();
119 if (pointerAction == MMI::PointerEvent::POINTER_ACTION_ENTER_WINDOW ||
120 pointerAction == MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW ||
121 pointerAction == MMI::PointerEvent::POINTER_ACTION_PULL_IN_WINDOW ||
122 pointerAction == MMI::PointerEvent::POINTER_ACTION_PULL_OUT_WINDOW) {
123 WLOGFI("InputTracking id:%{public}d, Dispatch by skipping receipt, action:%{public}s,"
124 " persistentId:%{public}d", pointerEvent->GetId(),
125 pointerEvent->DumpPointerAction(), sessionStage_->GetPersistentId());
126 }
127 sessionStage_->NotifyPointerEvent(pointerEvent);
128 return WSError::WS_OK;
129 }
130
TransferBackpressedEventForConsumed(bool & isConsumed)131 WSError WindowEventChannel::TransferBackpressedEventForConsumed(bool& isConsumed)
132 {
133 WLOGFD("WindowEventChannel receive backpressed event");
134 if (!sessionStage_) {
135 WLOGFE("session stage is null!");
136 return WSError::WS_ERROR_NULLPTR;
137 }
138 sessionStage_->NotifyBackpressedEvent(isConsumed);
139 return WSError::WS_OK;
140 }
141
TransferKeyEventForConsumed(const std::shared_ptr<MMI::KeyEvent> & keyEvent,bool & isConsumed,bool isPreImeEvent)142 WSError WindowEventChannel::TransferKeyEventForConsumed(
143 const std::shared_ptr<MMI::KeyEvent>& keyEvent, bool& isConsumed, bool isPreImeEvent)
144 {
145 WLOGFD("WindowEventChannel receive key event");
146 if (!sessionStage_) {
147 WLOGFE("session stage is null!");
148 return WSError::WS_ERROR_NULLPTR;
149 }
150 if (keyEvent == nullptr) {
151 WLOGFE("keyEvent is nullptr");
152 return WSError::WS_ERROR_NULLPTR;
153 }
154 if (SceneBoardJudgement::IsSceneBoardEnabled() && isUIExtension_ && IsUIExtensionKeyEventBlocked(keyEvent)) {
155 return WSError::WS_ERROR_INVALID_PERMISSION;
156 }
157 if (isPreImeEvent) {
158 isConsumed = sessionStage_->NotifyOnKeyPreImeEvent(keyEvent);
159 TLOGI(WmsLogTag::WMS_EVENT, "NotifyOnKeyPreImeEvent id:%{public}d isConsumed:%{public}d",
160 keyEvent->GetId(), static_cast<int>(isConsumed));
161 return WSError::WS_OK;
162 }
163 sessionStage_->NotifyKeyEvent(keyEvent, isConsumed);
164 keyEvent->MarkProcessed();
165 return WSError::WS_OK;
166 }
167
IsUIExtensionKeyEventBlocked(const std::shared_ptr<MMI::KeyEvent> & keyEvent)168 bool WindowEventChannel::IsUIExtensionKeyEventBlocked(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
169 {
170 if (uiExtensionUsage_ == UIExtensionUsage::MODAL) {
171 if (!SessionPermission::IsSystemCalling()) {
172 TLOGE(WmsLogTag::WMS_EVENT, "Unsupported keyCode due to Modal UIExtension.");
173 return true;
174 } else {
175 TLOGW(WmsLogTag::WMS_EVENT, "SystemCalling UIExtension.");
176 return false;
177 }
178 }
179 if (uiExtensionUsage_ == UIExtensionUsage::CONSTRAINED_EMBEDDED) {
180 auto keyCode = keyEvent->GetKeyCode();
181 if (VALID_KEYCODE_FOR_CONSTRAINED_EMBEDDED_UIEXTENSION.find(keyCode) ==
182 VALID_KEYCODE_FOR_CONSTRAINED_EMBEDDED_UIEXTENSION.end()) {
183 TLOGE(WmsLogTag::WMS_EVENT, "Unsupported keyCode due to Constrained embedded UIExtension.");
184 return true;
185 }
186 auto pressedKeys = keyEvent->GetPressedKeys();
187 if (pressedKeys.size() == SIZE_TWO && keyCode == MMI::KeyEvent::KEYCODE_TAB &&
188 (pressedKeys[0] == MMI::KeyEvent::KEYCODE_SHIFT_LEFT ||
189 pressedKeys[0] == MMI::KeyEvent::KEYCODE_SHIFT_RIGHT)) {
190 // only allows combined keys SHIFT+TAB
191 return false;
192 } else if (pressedKeys.size() >= SIZE_TWO) {
193 TLOGE(WmsLogTag::WMS_EVENT, "Invalid size of PressedKeys due to Constrained embedded UIExtension.");
194 return true;
195 }
196 }
197 return false;
198 }
199
TransferKeyEventForConsumedAsync(const std::shared_ptr<MMI::KeyEvent> & keyEvent,bool isPreImeEvent,const sptr<IRemoteObject> & listener)200 WSError WindowEventChannel::TransferKeyEventForConsumedAsync(
201 const std::shared_ptr<MMI::KeyEvent>& keyEvent, bool isPreImeEvent, const sptr<IRemoteObject>& listener)
202 {
203 bool isConsumed = false;
204 auto ret = TransferKeyEventForConsumed(keyEvent, isConsumed, isPreImeEvent);
205 auto channelListener = iface_cast<IWindowEventChannelListener>(listener);
206 if (channelListener == nullptr) {
207 TLOGE(WmsLogTag::WMS_EVENT, "listener is null.");
208 return ret;
209 }
210
211 auto keyEventId = keyEvent->GetId();
212 TLOGD(WmsLogTag::WMS_EVENT, "finished with isConsumed:%{public}d ret:%{public}d at PreIme:%{public}d id:%{public}d",
213 isConsumed, ret, isPreImeEvent, keyEventId);
214 channelListener->OnTransferKeyEventForConsumed(keyEventId, isPreImeEvent, isConsumed, ret);
215 return ret;
216 }
217
TransferFocusActiveEvent(bool isFocusActive)218 WSError WindowEventChannel::TransferFocusActiveEvent(bool isFocusActive)
219 {
220 WLOGFD("WindowEventChannel receive focus active event");
221 if (!sessionStage_) {
222 WLOGFE("session stage is null!");
223 return WSError::WS_ERROR_NULLPTR;
224 }
225 sessionStage_->NotifyFocusActiveEvent(isFocusActive);
226 return WSError::WS_OK;
227 }
228
PrintKeyEvent(const std::shared_ptr<MMI::KeyEvent> & event)229 void WindowEventChannel::PrintKeyEvent(const std::shared_ptr<MMI::KeyEvent>& event)
230 {
231 if (event == nullptr) {
232 WLOGFE("event is nullptr");
233 return;
234 }
235 std::vector<MMI::KeyEvent::KeyItem> eventItems = event->GetKeyItems();
236 WLOGFD("KeyCode:%{public}d,KeyAction:%{public}s,keyItemsCount:%{public}zu", event->GetKeyCode(),
237 MMI::KeyEvent::ActionToString(event->GetKeyAction()), eventItems.size());
238 for (const auto &item : eventItems) {
239 WLOGFD("KeyCode:%{public}d,IsPressed:%{public}d,GetUnicode:%{public}d",
240 item.GetKeyCode(), item.IsPressed(), item.GetUnicode());
241 }
242 }
243
PrintPointerEvent(const std::shared_ptr<MMI::PointerEvent> & event)244 void WindowEventChannel::PrintPointerEvent(const std::shared_ptr<MMI::PointerEvent>& event)
245 {
246 if (event == nullptr) {
247 WLOGFE("event is nullptr");
248 return;
249 }
250 std::vector<int32_t> pointerIds = event->GetPointerIds();
251 std::string str;
252 std::vector<uint8_t> buffer = event->GetBuffer();
253 for (const auto &buff : buffer) {
254 str += std::to_string(buff);
255 }
256 auto pointerAction = event->GetPointerAction();
257 if (pointerAction == MMI::PointerEvent::POINTER_ACTION_MOVE ||
258 pointerAction == MMI::PointerEvent::POINTER_ACTION_PULL_MOVE) {
259 WLOGFD("PointerAction:%{public}s,SourceType:%{public}s,ButtonId:%{public}d,"
260 "VerticalAxisValue:%{public}.2f,HorizontalAxisValue:%{public}.2f,"
261 "PointerId:%{public}d,PointerCount:%{public}zu,EventNumber:%{public}d,"
262 "BufferCount:%{public}zu,Buffer:%{public}s",
263 event->DumpPointerAction(), event->DumpSourceType(), event->GetButtonId(),
264 event->GetAxisValue(MMI::PointerEvent::AXIS_TYPE_SCROLL_VERTICAL),
265 event->GetAxisValue(MMI::PointerEvent::AXIS_TYPE_SCROLL_HORIZONTAL),
266 event->GetPointerId(), pointerIds.size(), event->GetId(), buffer.size(), str.c_str());
267
268 for (const auto &pointerId : pointerIds) {
269 MMI::PointerEvent::PointerItem item;
270 if (!event->GetPointerItem(pointerId, item)) {
271 WLOGFE("Invalid pointer: %{public}d.", pointerId);
272 return;
273 }
274 TLOGD(WmsLogTag::WMS_EVENT, "pointerId:%{public}d,DownTime:%{public}" PRId64 ",IsPressed:%{public}d,"
275 "DisplayX:%{private}d,DisplayY:%{private}d,WindowX:%{private}d,WindowY:%{private}d",
276 pointerId, item.GetDownTime(), item.IsPressed(), item.GetDisplayX(), item.GetDisplayY(),
277 item.GetWindowX(), item.GetWindowY());
278 }
279 } else {
280 PrintInfoPointerEvent(event);
281 }
282 }
283
PrintInfoPointerEvent(const std::shared_ptr<MMI::PointerEvent> & event)284 void WindowEventChannel::PrintInfoPointerEvent(const std::shared_ptr<MMI::PointerEvent>& event)
285 {
286 if (event == nullptr) {
287 WLOGFE("event is nullptr");
288 return;
289 }
290 std::vector<int32_t> pointerIds = event->GetPointerIds();
291 std::string str;
292 std::vector<uint8_t> buffer = event->GetBuffer();
293 for (const auto &buff : buffer) {
294 str += std::to_string(buff);
295 }
296 WLOGFI("PointerAction:%{public}s,SourceType:%{public}s,ButtonId:%{public}d,"
297 "VerticalAxisValue:%{public}.2f,HorizontalAxisValue:%{public}.2f,"
298 "PointerId:%{public}d,PointerCount:%{public}zu,EventNumber:%{public}d,"
299 "BufferCount:%{public}zu,Buffer:%{public}s",
300 event->DumpPointerAction(), event->DumpSourceType(), event->GetButtonId(),
301 event->GetAxisValue(MMI::PointerEvent::AXIS_TYPE_SCROLL_VERTICAL),
302 event->GetAxisValue(MMI::PointerEvent::AXIS_TYPE_SCROLL_HORIZONTAL),
303 event->GetPointerId(), pointerIds.size(), event->GetId(), buffer.size(), str.c_str());
304
305 for (const auto &pointerId : pointerIds) {
306 MMI::PointerEvent::PointerItem item;
307 if (!event->GetPointerItem(pointerId, item)) {
308 WLOGFE("Invalid pointer: %{public}d.", pointerId);
309 return;
310 }
311 WLOGFI("pointerId:%{public}d,DownTime:%{public}" PRId64 ",IsPressed:%{public}d",
312 pointerId, item.GetDownTime(), item.IsPressed());
313 }
314 }
315
TransferFocusState(bool focusState)316 WSError WindowEventChannel::TransferFocusState(bool focusState)
317 {
318 WLOGFD("WindowEventChannel receive focus state event: %{public}d", static_cast<int>(focusState));
319 if (!sessionStage_) {
320 WLOGFE("session stage is null!");
321 return WSError::WS_ERROR_NULLPTR;
322 }
323 sessionStage_->NotifyFocusStateEvent(focusState);
324 return WSError::WS_OK;
325 }
326
TransferAccessibilityHoverEvent(float pointX,float pointY,int32_t sourceType,int32_t eventType,int64_t timeMs)327 WSError WindowEventChannel::TransferAccessibilityHoverEvent(float pointX, float pointY, int32_t sourceType,
328 int32_t eventType, int64_t timeMs)
329 {
330 if (!sessionStage_) {
331 TLOGE(WmsLogTag::WMS_UIEXT, "session stage is null.");
332 return WSError::WS_ERROR_NULLPTR;
333 }
334 return sessionStage_->NotifyAccessibilityHoverEvent(pointX, pointY, sourceType, eventType, timeMs);
335 }
336
TransferAccessibilityChildTreeRegister(uint32_t windowId,int32_t treeId,int64_t accessibilityId)337 WSError WindowEventChannel::TransferAccessibilityChildTreeRegister(
338 uint32_t windowId, int32_t treeId, int64_t accessibilityId)
339 {
340 if (!sessionStage_) {
341 TLOGE(WmsLogTag::WMS_UIEXT, "session stage is null.");
342 return WSError::WS_ERROR_NULLPTR;
343 }
344 return sessionStage_->NotifyAccessibilityChildTreeRegister(windowId, treeId, accessibilityId);
345 }
346
TransferAccessibilityChildTreeUnregister()347 WSError WindowEventChannel::TransferAccessibilityChildTreeUnregister()
348 {
349 if (!sessionStage_) {
350 TLOGE(WmsLogTag::WMS_UIEXT, "session stage is null.");
351 return WSError::WS_ERROR_NULLPTR;
352 }
353 return sessionStage_->NotifyAccessibilityChildTreeUnregister();
354 }
355
TransferAccessibilityDumpChildInfo(const std::vector<std::string> & params,std::vector<std::string> & info)356 WSError WindowEventChannel::TransferAccessibilityDumpChildInfo(
357 const std::vector<std::string>& params, std::vector<std::string>& info)
358 {
359 if (!sessionStage_) {
360 TLOGE(WmsLogTag::WMS_UIEXT, "session stage is null.");
361 return WSError::WS_ERROR_NULLPTR;
362 }
363 #ifdef ACCESSIBILITY_DUMP_FOR_TEST
364 return sessionStage_->NotifyAccessibilityDumpChildInfo(params, info);
365 #else
366 info.emplace_back("not support in user build variant");
367 return WSError::WS_OK;
368 #endif
369 }
370 } // namespace OHOS::Rosen
371