• 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     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