• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2025 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 "cooperate_context.h"
19 #include "cooperate_hisysevent.h"
20 #include "devicestatus_define.h"
21 #include "display_manager.h"
22 #include "power_mgr_client.h"
23 #include "input_event_transmission/input_event_serialization.h"
24 #include "utility.h"
25 #include "kits/c/wifi_hid2d.h"
26 
27 #include "res_sched_client.h"
28 #include "res_type.h"
29 
30 #undef LOG_TAG
31 #define LOG_TAG "InputEventInterceptor"
32 
33 namespace OHOS {
34 namespace Msdp {
35 namespace DeviceStatus {
36 namespace Cooperate {
37 
38 namespace {
39 const std::string WIFI_INTERFACE_NAME { "chba0" };
40 const int32_t RESTORE_SCENE { 0 };
41 const int32_t FORBIDDEN_SCENE { 1 };
42 const int32_t UPPER_SCENE_FPS { 0 };
43 const int32_t UPPER_SCENE_BW { 0 };
44 const int32_t INTERVAL_MS { 2000 };
45 const int32_t REPEAT_MAX { 10000 };
46 const int32_t MODE_ENABLE { 0 };
47 const int32_t MODE_DISABLE { 1 };
48 const std::string LOW_LATENCY_KEY = "identity";
49 }
50 
51 std::set<int32_t> InputEventInterceptor::filterKeys_ {
52     MMI::KeyEvent::KEYCODE_BACK,
53     MMI::KeyEvent::KEYCODE_POWER,
54 };
55 
56 std::set<int32_t> InputEventInterceptor::filterPointers_ {
57     MMI::PointerEvent::POINTER_ACTION_ENTER_WINDOW,
58     MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW,
59     MMI::PointerEvent::POINTER_ACTION_PULL_IN_WINDOW,
60     MMI::PointerEvent::POINTER_ACTION_PULL_OUT_WINDOW,
61 };
62 
~InputEventInterceptor()63 InputEventInterceptor::~InputEventInterceptor()
64 {
65     Disable();
66 }
67 
Enable(Context & context)68 int32_t InputEventInterceptor::Enable(Context &context)
69 {
70     CALL_INFO_TRACE;
71     CHKPR(env_, RET_ERR);
72     if (interceptorId_ > 0) {
73         return RET_OK;
74     }
75     auto cursorPos = context.CursorPosition();
76     FI_HILOGI("Cursor transite out at (%{private}d, %{private}d)", cursorPos.x, cursorPos.y);
77     remoteNetworkId_ = context.Peer();
78     sender_ = context.Sender();
79     inputEventSampler_.SetPointerEventHandler(
80         [this](std::shared_ptr<MMI::PointerEvent> pointerEvent) {
81             this->OnPointerEvent(pointerEvent);
82         }
83     );
84     interceptorId_ = env_->GetInput().AddInterceptor(
85         [this](std::shared_ptr<MMI::PointerEvent> pointerEvent) { inputEventSampler_.OnPointerEvent(pointerEvent); },
86         [this](std::shared_ptr<MMI::KeyEvent> keyEvent) { this->OnKeyEvent(keyEvent); });
87     if (interceptorId_ < 0) {
88         FI_HILOGE("Input::AddInterceptor fail");
89         CooperateRadarInfo radarInfo {
90             .funcName = __FUNCTION__,
91             .bizState = static_cast<int32_t> (BizState::STATE_END),
92             .bizStage = static_cast<int32_t> (BizCooperateStage::STAGE_ADD_MMI_EVENT_INTERCEPOR),
93             .stageRes = static_cast<int32_t> (BizCooperateStageRes::RES_FAIL),
94             .bizScene = static_cast<int32_t> (BizCooperateScene::SCENE_ACTIVE),
95             .errCode = static_cast<int32_t> (CooperateRadarErrCode::ADD_MMI_EVENT_INTERCEPOR_FAILED),
96             .hostName = "",
97             .localNetId = Utility::DFXRadarAnonymize(context.Local().c_str()),
98             .peerNetId = Utility::DFXRadarAnonymize(remoteNetworkId_.c_str())
99         };
100         CooperateRadar::ReportCooperateRadarInfo(radarInfo);
101         return RET_ERR;
102     }
103     TurnOffChannelScan();
104     HeartBeatSend();
105     ExecuteInner();
106     return RET_OK;
107 }
108 
HeartBeatSend()109 void InputEventInterceptor::HeartBeatSend()
110 {
111     CALL_DEBUG_ENTER;
112     CHKPV(env_);
113     heartTimer_ = env_->GetTimerManager().AddTimerAsync(INTERVAL_MS, REPEAT_MAX, [this]() {
114         NetPacket packet(MessageId::DSOFTBUS_HEART_BEAT_PACKET);
115         if (InputEventSerialization::HeartBeatMarshalling(packet) != RET_OK) {
116             FI_HILOGE("Failed to serialize packet");
117             return;
118         }
119         env_->GetDSoftbus().SendPacket(remoteNetworkId_, packet);
120     });
121 }
122 
Disable()123 void InputEventInterceptor::Disable()
124 {
125     CALL_INFO_TRACE;
126     CHKPV(env_);
127     TurnOnChannelScan();
128     if (interceptorId_ > 0) {
129         env_->GetInput().RemoveInterceptor(interceptorId_);
130         interceptorId_ = -1;
131     }
132     if ((pointerEventTimer_ >= 0)) {
133         env_->GetTimerManager().RemoveTimerAsync(pointerEventTimer_);
134         pointerEventTimer_ = -1;
135     }
136     if (heartTimer_ < 0) {
137         FI_HILOGE("Invalid heartTimer_");
138         return;
139     }
140     if (env_->GetTimerManager().RemoveTimerAsync(heartTimer_) != RET_OK) {
141         FI_HILOGE("Failed to RemoveTimer");
142     }
143     heartTimer_ = -1;
144 }
145 
Update(Context & context)146 void InputEventInterceptor::Update(Context &context)
147 {
148     remoteNetworkId_ = context.Peer();
149     FI_HILOGI("Update peer to \'%{public}s\'", Utility::Anonymize(remoteNetworkId_).c_str());
150 }
151 
OnPointerEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent)152 void InputEventInterceptor::OnPointerEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent)
153 {
154     CHKPV(pointerEvent);
155     int64_t interceptorTime = Utility::GetSysClockTime();
156     if (scanState_) {
157         TurnOffChannelScan();
158     }
159     RefreshActivity();
160     if ((pointerEventTimer_ >= 0)) {
161         env_->GetTimerManager().RemoveTimerAsync(pointerEventTimer_);
162         pointerEventTimer_ = -1;
163     }
164     if (auto pointerAction = pointerEvent->GetPointerAction();
165         filterPointers_.find(pointerAction) != filterPointers_.end()) {
166         FI_HILOGI("Current pointerAction:%{public}d, skip", static_cast<int32_t>(pointerAction));
167         return;
168     }
169     if (auto pointerAction = pointerEvent->GetPointerAction();
170         pointerAction == MMI::PointerEvent::POINTER_ACTION_CANCEL) {
171         auto originAction = pointerEvent->GetOriginPointerAction();
172         FI_HILOGI("Reset to origin action:%{public}d", static_cast<int32_t>(originAction));
173         pointerEvent->SetPointerAction(originAction);
174     }
175     OnNotifyCrossDrag(pointerEvent);
176     NetPacket packet(MessageId::DSOFTBUS_INPUT_POINTER_EVENT);
177 
178     int32_t ret = InputEventSerialization::Marshalling(pointerEvent, packet, interceptorTime);
179     if (ret != RET_OK) {
180         FI_HILOGE("Failed to serialize pointer event");
181         return;
182     }
183     FI_HILOGD("PointerEvent(No:%{public}d,Source:%{public}s,Action:%{public}s)",
184         pointerEvent->GetId(), pointerEvent->DumpSourceType(), pointerEvent->DumpPointerAction());
185     env_->GetDSoftbus().SendPacket(remoteNetworkId_, packet);
186     pointerEventTimer_ = env_->GetTimerManager().AddTimerAsync(POINTER_EVENT_TIMEOUT, REPEAT_ONCE, [this]() {
187         TurnOnChannelScan();
188         pointerEventTimer_ = -1;
189     });
190 }
191 
OnNotifyCrossDrag(std::shared_ptr<MMI::PointerEvent> pointerEvent)192 void InputEventInterceptor::OnNotifyCrossDrag(std::shared_ptr<MMI::PointerEvent> pointerEvent)
193 {
194     CHKPV(pointerEvent);
195     CHKPV(env_);
196     auto pointerAction = pointerEvent->GetPointerAction();
197     if (pointerAction == MMI::PointerEvent::POINTER_ACTION_PULL_IN_WINDOW ||
198         pointerAction == MMI::PointerEvent::POINTER_ACTION_PULL_OUT_WINDOW) {
199         FI_HILOGD("PointerAction:%{public}d, it's pressedButtons is empty, skip", pointerAction);
200         return;
201     }
202     auto pressedButtons = pointerEvent->GetPressedButtons();
203     bool isButtonDown = (pressedButtons.find(MMI::PointerEvent::MOUSE_BUTTON_LEFT) != pressedButtons.end());
204     FI_HILOGD("PointerAction:%{public}d, isPressed:%{public}s", pointerAction, isButtonDown ? "true" : "false");
205     CHKPV(env_);
206     env_->GetDragManager().NotifyCrossDrag(isButtonDown);
207 }
208 
OnKeyEvent(std::shared_ptr<MMI::KeyEvent> keyEvent)209 void InputEventInterceptor::OnKeyEvent(std::shared_ptr<MMI::KeyEvent> keyEvent)
210 {
211     CHKPV(keyEvent);
212     CHKPV(env_);
213     RefreshActivity();
214     if (filterKeys_.find(keyEvent->GetKeyCode()) != filterKeys_.end()) {
215         keyEvent->AddFlag(MMI::AxisEvent::EVENT_FLAG_NO_INTERCEPT);
216         env_->GetInput().SimulateInputEvent(keyEvent);
217         return;
218     }
219     NetPacket packet(MessageId::DSOFTBUS_INPUT_KEY_EVENT);
220 
221     int32_t ret = InputEventSerialization::KeyEventToNetPacket(keyEvent, packet);
222     if (ret != RET_OK) {
223         FI_HILOGE("Failed to serialize key event");
224         return;
225     }
226     FI_HILOGD("KeyEvent(No:%{public}d,Key:%{private}d,Action:%{public}d)",
227         keyEvent->GetId(), keyEvent->GetKeyCode(), keyEvent->GetKeyAction());
228     env_->GetDSoftbus().SendPacket(remoteNetworkId_, packet);
229 }
230 
TurnOffChannelScan()231 void InputEventInterceptor::TurnOffChannelScan()
232 {
233     scanState_ = false;
234     if (SetWifiScene(FORBIDDEN_SCENE) != RET_OK) {
235         scanState_ = true;
236         FI_HILOGE("Forbidden scene failed");
237     }
238 }
239 
ExecuteInner()240 void InputEventInterceptor::ExecuteInner()
241 {
242     CALL_DEBUG_ENTER;
243     // to enable low latency mode: value = 0
244     OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(
245         OHOS::ResourceSchedule::ResType::RES_TYPE_NETWORK_LATENCY_REQUEST, MODE_ENABLE,
246         {{LOW_LATENCY_KEY, FI_PKG_NAME}});
247 }
248 
HandleStopTimer()249 void InputEventInterceptor::HandleStopTimer()
250 {
251     CALL_DEBUG_ENTER;
252     OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(
253         OHOS::ResourceSchedule::ResType::RES_TYPE_NETWORK_LATENCY_REQUEST, MODE_DISABLE,
254         {{LOW_LATENCY_KEY, FI_PKG_NAME}});
255 }
256 
TurnOnChannelScan()257 void InputEventInterceptor::TurnOnChannelScan()
258 {
259     scanState_ = true;
260     if (SetWifiScene(RESTORE_SCENE) != RET_OK) {
261         scanState_ = false;
262         FI_HILOGE("Restore scene failed");
263     }
264 }
265 
SetWifiScene(unsigned int scene)266 int32_t InputEventInterceptor::SetWifiScene(unsigned int scene)
267 {
268     CALL_DEBUG_ENTER;
269     Hid2dUpperScene upperScene;
270     upperScene.scene = scene;
271     upperScene.fps = UPPER_SCENE_FPS;
272     upperScene.bw = UPPER_SCENE_BW;
273     if (Hid2dSetUpperScene(WIFI_INTERFACE_NAME.c_str(), &upperScene) != RET_OK) {
274         FI_HILOGE("Set wifi scene failed");
275         return RET_ERR;
276     }
277     return RET_OK;
278 }
279 
ReportPointerEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent)280 void InputEventInterceptor::ReportPointerEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent)
281 {
282     MMI::PointerEvent::PointerItem pointerItem;
283 
284     if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
285         FI_HILOGE("Corrupted pointer event");
286         return;
287     }
288     auto ret = sender_.Send(CooperateEvent(
289         CooperateEventType::INPUT_POINTER_EVENT,
290         InputPointerEvent {
291             .deviceId = pointerEvent->GetDeviceId(),
292             .pointerAction = pointerEvent->GetPointerAction(),
293             .sourceType = pointerEvent->GetSourceType(),
294             .position = Coordinate {
295                 .x = pointerItem.GetDisplayX(),
296                 .y = pointerItem.GetDisplayY(),
297             }
298         }));
299     if (ret != Channel<CooperateEvent>::NO_ERROR) {
300         FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
301     }
302 }
303 
RefreshActivity()304 void InputEventInterceptor::RefreshActivity()
305 {
306     if (!PowerMgr::PowerMgrClient::GetInstance().RefreshActivity(
307         PowerMgr::UserActivityType::USER_ACTIVITY_TYPE_TOUCH)) {
308         FI_HILOGE("RefreshActivity Failed");
309     }
310     return;
311 }
312 } // namespace Cooperate
313 } // namespace DeviceStatus
314 } // namespace Msdp
315 } // namespace OHOS
316