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 "input_event_transmission/input_event_interceptor.h"
17
18 #include <unordered_set>
19
20 #include "cooperate_context.h"
21 #include "devicestatus_define.h"
22 #include "input_event_transmission/input_event_serialization.h"
23 #include "utility.h"
24
25 #undef LOG_TAG
26 #define LOG_TAG "InputEventInterceptor"
27
28 namespace OHOS {
29 namespace Msdp {
30 namespace DeviceStatus {
31 namespace Cooperate {
32 std::unordered_set<int32_t> InputEventInterceptor::filterKeys_ {
33 MMI::KeyEvent::KEYCODE_BACK,
34 MMI::KeyEvent::KEYCODE_VOLUME_UP,
35 MMI::KeyEvent::KEYCODE_VOLUME_DOWN,
36 MMI::KeyEvent::KEYCODE_POWER,
37 };
38
39 std::unordered_set<int32_t> InputEventInterceptor::filterPointers_ {
40 MMI::PointerEvent::POINTER_ACTION_ENTER_WINDOW,
41 MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW,
42 MMI::PointerEvent::POINTER_ACTION_PULL_IN_WINDOW,
43 MMI::PointerEvent::POINTER_ACTION_PULL_OUT_WINDOW,
44 };
45
~InputEventInterceptor()46 InputEventInterceptor::~InputEventInterceptor()
47 {
48 Disable();
49 }
50
Enable(Context & context)51 void InputEventInterceptor::Enable(Context &context)
52 {
53 CALL_INFO_TRACE;
54 if (interceptorId_ > 0) {
55 return;
56 }
57 auto cursorPos = context.CursorPosition();
58 FI_HILOGI("Cursor transite out at (%{public}d, %{public}d)", cursorPos.x, cursorPos.y);
59 remoteNetworkId_ = context.Peer();
60 sender_ = context.Sender();
61 interceptorId_ = env_->GetInput().AddInterceptor(
62 [this](std::shared_ptr<MMI::PointerEvent> pointerEvent) {
63 this->OnPointerEvent(pointerEvent);
64 },
65 [this](std::shared_ptr<MMI::KeyEvent> keyEvent) {
66 this->OnKeyEvent(keyEvent);
67 });
68 if (interceptorId_ < 0) {
69 FI_HILOGE("Input::AddInterceptor fail");
70 }
71 }
72
Disable()73 void InputEventInterceptor::Disable()
74 {
75 CALL_INFO_TRACE;
76 if (interceptorId_ > 0) {
77 env_->GetInput().RemoveInterceptor(interceptorId_);
78 interceptorId_ = -1;
79 }
80 }
81
Update(Context & context)82 void InputEventInterceptor::Update(Context &context)
83 {
84 remoteNetworkId_ = context.Peer();
85 FI_HILOGI("Update peer to \'%{public}s\'", Utility::Anonymize(remoteNetworkId_).c_str());
86 }
87
OnPointerEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent)88 void InputEventInterceptor::OnPointerEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent)
89 {
90 CHKPV(pointerEvent);
91 if (auto pointerAction = pointerEvent->GetPointerAction();
92 filterPointers_.find(pointerAction) != filterPointers_.end()) {
93 FI_HILOGI("Current pointerAction:%{public}d, skip", static_cast<int32_t>(pointerAction));
94 return;
95 }
96 if (auto pointerAction = pointerEvent->GetPointerAction();
97 pointerAction == MMI::PointerEvent::POINTER_ACTION_CANCEL) {
98 auto originAction = pointerEvent->GetOriginPointerAction();
99 FI_HILOGI("Reset to origin action:%{public}d", static_cast<int32_t>(originAction));
100 pointerEvent->SetPointerAction(originAction);
101 }
102 NetPacket packet(MessageId::DSOFTBUS_INPUT_POINTER_EVENT);
103
104 int32_t ret = InputEventSerialization::Marshalling(pointerEvent, packet);
105 if (ret != RET_OK) {
106 FI_HILOGE("Failed to serialize pointer event");
107 return;
108 }
109 FI_HILOGI("PointerEvent(No:%{public}d,Source:%{public}s,Action:%{public}s)", pointerEvent->GetId(),
110 pointerEvent->DumpSourceType(), pointerEvent->DumpPointerAction());
111 env_->GetDSoftbus().SendPacket(remoteNetworkId_, packet);
112 }
113
OnKeyEvent(std::shared_ptr<MMI::KeyEvent> keyEvent)114 void InputEventInterceptor::OnKeyEvent(std::shared_ptr<MMI::KeyEvent> keyEvent)
115 {
116 CHKPV(keyEvent);
117 if (filterKeys_.find(keyEvent->GetKeyCode()) != filterKeys_.end()) {
118 keyEvent->AddFlag(MMI::AxisEvent::EVENT_FLAG_NO_INTERCEPT);
119 env_->GetInput().SimulateInputEvent(keyEvent);
120 return;
121 }
122 NetPacket packet(MessageId::DSOFTBUS_INPUT_KEY_EVENT);
123
124 int32_t ret = InputEventSerialization::KeyEventToNetPacket(keyEvent, packet);
125 if (ret != RET_OK) {
126 FI_HILOGE("Failed to serialize key event");
127 return;
128 }
129 FI_HILOGD("KeyEvent(No:%{public}d,Key:%{private}d,Action:%{public}d)", keyEvent->GetId(), keyEvent->GetKeyCode(),
130 keyEvent->GetKeyAction());
131 env_->GetDSoftbus().SendPacket(remoteNetworkId_, packet);
132 }
133
ReportPointerEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent)134 void InputEventInterceptor::ReportPointerEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent)
135 {
136 MMI::PointerEvent::PointerItem pointerItem;
137
138 if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
139 FI_HILOGE("Corrupted pointer event");
140 return;
141 }
142 auto ret = sender_.Send(CooperateEvent(CooperateEventType::INPUT_POINTER_EVENT,
143 InputPointerEvent {
144 .deviceId = pointerEvent->GetDeviceId(),
145 .pointerAction = pointerEvent->GetPointerAction(),
146 .sourceType = pointerEvent->GetSourceType(),
147 .position = Coordinate {
148 .x = pointerItem.GetDisplayX(),
149 .y = pointerItem.GetDisplayY(),
150 }
151 }));
152 if (ret != Channel<CooperateEvent>::NO_ERROR) {
153 FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
154 }
155 }
156 } // namespace Cooperate
157 } // namespace DeviceStatus
158 } // namespace Msdp
159 } // namespace OHOS
160