• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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