• 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 "input_event_transmission/input_event_builder.h"
17 
18 #include "display_info.h"
19 
20 #include "cooperate_context.h"
21 #include "cooperate_hisysevent.h"
22 #include "devicestatus_define.h"
23 #include "input_event_transmission/input_event_serialization.h"
24 #include "utility.h"
25 #include "kits/c/wifi_hid2d.h"
26 #include "res_sched_client.h"
27 #include "res_type.h"
28 
29 #undef LOG_TAG
30 #define LOG_TAG "InputEventBuilder"
31 
32 namespace OHOS {
33 namespace Msdp {
34 namespace DeviceStatus {
35 namespace Cooperate {
36 namespace {
37 constexpr size_t LOG_PERIOD { 10 };
38 constexpr int32_t DEFAULT_SCREEN_WIDTH { 512 };
39 constexpr double MIN_DAMPLING_COEFFICENT { 0.05 };
40 constexpr double MAX_DAMPLING_COEFFICENT { 1.5 };
41 constexpr double DEFAULT_DAMPLING_COEFFICIENT { 1.0 };
42 const std::string WIFI_INTERFACE_NAME { "chba0" };
43 const int32_t RESTORE_SCENE { 0 };
44 const int32_t FORBIDDEN_SCENE { 1 };
45 const int32_t UPPER_SCENE_FPS { 0 };
46 const int32_t UPPER_SCENE_BW { 0 };
47 const int32_t MODE_ENABLE { 0 };
48 const int32_t MODE_DISABLE { 1 };
49 const int32_t DRIVE_INTERCEPTOR_LATENCY { 5 };
50 const int32_t INTERCEPTOR_TRANSMISSION_LATENCY { 20 };
51 const std::string LOW_LATENCY_KEY = "identity";
52 }
53 
InputEventBuilder(IContext * env)54 InputEventBuilder::InputEventBuilder(IContext *env)
55     : env_(env)
56 {
57     observer_ = std::make_shared<DSoftbusObserver>(*this);
58     pointerEvent_ = MMI::PointerEvent::Create();
59     keyEvent_ = MMI::KeyEvent::Create();
60 
61     for (size_t index = 0, cnt = damplingCoefficients_.size(); index < cnt; ++index) {
62         damplingCoefficients_[index] = DEFAULT_DAMPLING_COEFFICIENT;
63     }
64 }
65 
~InputEventBuilder()66 InputEventBuilder::~InputEventBuilder()
67 {
68     Disable();
69 }
70 
Enable(Context & context)71 void InputEventBuilder::Enable(Context &context)
72 {
73     CALL_INFO_TRACE;
74     CHKPV(env_);
75     if (enable_) {
76         return;
77     }
78     enable_ = true;
79     xDir_ = 0;
80     movement_ = 0;
81     freezing_ = (context.CooperateFlag() & COOPERATE_FLAG_FREEZE_CURSOR);
82     remoteNetworkId_ = context.Peer();
83     localNetworkId_ = context.Local();
84     pointerSpeed_ = context.GetPointerSpeed();
85     touchPadSpeed_ = context.GetTouchPadSpeed();
86     env_->GetDSoftbus().AddObserver(observer_);
87     Coordinate cursorPos = context.CursorPosition();
88     TurnOffChannelScan();
89     FI_HILOGI("Cursor transite in (%{private}d, %{private}d)", cursorPos.x, cursorPos.y);
90     if (!enable_) {
91         CooperateRadarInfo radarInfo {
92             .funcName =  __FUNCTION__,
93             .bizState = static_cast<int32_t> (BizState::STATE_END),
94             .bizStage = static_cast<int32_t> (BizCooperateStage::STATE_INPUT_EVENT_BUILDER_ENABLE),
95             .stageRes = static_cast<int32_t> (BizCooperateStageRes::RES_FAIL),
96             .bizScene = static_cast<int32_t> (BizCooperateScene::SCENE_PASSIVE),
97             .errCode = static_cast<int32_t> (CooperateRadarErrCode::INPUT_EVENT_BUILDER_ENABLE_FAILED),
98             .hostName = "",
99             .localNetId = Utility::DFXRadarAnonymize(context.Local().c_str()),
100             .peerNetId = Utility::DFXRadarAnonymize(remoteNetworkId_.c_str())
101         };
102         CooperateRadar::ReportCooperateRadarInfo(radarInfo);
103     }
104     ExecuteInner();
105 }
106 
Disable()107 void InputEventBuilder::Disable()
108 {
109     CALL_INFO_TRACE;
110     CHKPV(env_);
111     if (enable_) {
112         enable_ = false;
113         env_->GetDSoftbus().RemoveObserver(observer_);
114         TurnOnChannelScan();
115         ResetPressedEvents();
116     }
117     if ((pointerEventTimer_ >= 0)) {
118         env_->GetTimerManager().RemoveTimerAsync(pointerEventTimer_);
119         pointerEventTimer_ = -1;
120     }
121     HandleStopTimer();
122 }
123 
Update(Context & context)124 void InputEventBuilder::Update(Context &context)
125 {
126     remoteNetworkId_ = context.Peer();
127     FI_HILOGI("Update peer to \'%{public}s\'", Utility::Anonymize(remoteNetworkId_).c_str());
128 }
129 
Freeze()130 void InputEventBuilder::Freeze()
131 {
132     if (!enable_) {
133         return;
134     }
135     xDir_ = 0;
136     movement_ = 0;
137     freezing_ = true;
138     FI_HILOGI("Freeze remote input from '%{public}s'", Utility::Anonymize(remoteNetworkId_).c_str());
139 }
140 
Thaw()141 void InputEventBuilder::Thaw()
142 {
143     if (!enable_) {
144         return;
145     }
146     freezing_ = false;
147     FI_HILOGI("Thaw remote input from '%{public}s'", Utility::Anonymize(remoteNetworkId_).c_str());
148 }
149 
SetDamplingCoefficient(uint32_t direction,double coefficient)150 void InputEventBuilder::SetDamplingCoefficient(uint32_t direction, double coefficient)
151 {
152     coefficient = std::clamp(coefficient, MIN_DAMPLING_COEFFICENT, MAX_DAMPLING_COEFFICENT);
153     FI_HILOGI("SetDamplingCoefficient(0x%{public}x, %{public}.3f)", direction, coefficient);
154     if ((direction & COORDINATION_DAMPLING_UP) == COORDINATION_DAMPLING_UP) {
155         damplingCoefficients_[DamplingDirection::DAMPLING_DIRECTION_UP] = coefficient;
156     }
157     if ((direction & COORDINATION_DAMPLING_DOWN) == COORDINATION_DAMPLING_DOWN) {
158         damplingCoefficients_[DamplingDirection::DAMPLING_DIRECTION_DOWN] = coefficient;
159     }
160     if ((direction & COORDINATION_DAMPLING_LEFT) == COORDINATION_DAMPLING_LEFT) {
161         damplingCoefficients_[DamplingDirection::DAMPLING_DIRECTION_LEFT] = coefficient;
162     }
163     if ((direction & COORDINATION_DAMPLING_RIGHT) == COORDINATION_DAMPLING_RIGHT) {
164         damplingCoefficients_[DamplingDirection::DAMPLING_DIRECTION_RIGHT] = coefficient;
165     }
166 }
167 
UpdateVirtualDeviceIdMap(const std::unordered_map<int32_t,int32_t> & remote2VirtualIds)168 void InputEventBuilder::UpdateVirtualDeviceIdMap(const std::unordered_map<int32_t, int32_t> &remote2VirtualIds)
169 {
170     CALL_INFO_TRACE;
171     std::unique_lock<std::shared_mutex> lock(lock_);
172     remote2VirtualIds_ = remote2VirtualIds;
173     for (const auto &elem: remote2VirtualIds_) {
174         FI_HILOGI("Remote:%{public}d -> virtual:%{public}d", elem.first, elem.second);
175     }
176 }
177 
GetDamplingCoefficient(DamplingDirection direction) const178 double InputEventBuilder::GetDamplingCoefficient(DamplingDirection direction) const
179 {
180     if ((direction >= DamplingDirection::DAMPLING_DIRECTION_UP) &&
181         (direction < DamplingDirection::N_DAMPLING_DIRECTIONS)) {
182         return damplingCoefficients_[direction];
183     }
184     return DEFAULT_DAMPLING_COEFFICIENT;
185 }
186 
OnPacket(const std::string & networkId,Msdp::NetPacket & packet)187 bool InputEventBuilder::OnPacket(const std::string &networkId, Msdp::NetPacket &packet)
188 {
189     if (networkId != remoteNetworkId_) {
190         FI_HILOGW("Unexpected packet from \'%{public}s\'", Utility::Anonymize(networkId).c_str());
191         return false;
192     }
193     switch (packet.GetMsgId()) {
194         case MessageId::DSOFTBUS_INPUT_POINTER_EVENT: {
195             OnPointerEvent(packet);
196             break;
197         }
198         case MessageId::DSOFTBUS_INPUT_KEY_EVENT: {
199             OnKeyEvent(packet);
200             break;
201         }
202         case MessageId::DSOFTBUS_HEART_BEAT_PACKET: {
203             FI_HILOGD("Heart beat received");
204             break;
205         }
206         default: {
207             FI_HILOGW("Unexpected message(%{public}d) from \'%{public}s\'",
208                 static_cast<int32_t>(packet.GetMsgId()), Utility::Anonymize(networkId).c_str());
209             return false;
210         }
211     }
212     return true;
213 }
214 
OnPointerEvent(Msdp::NetPacket & packet)215 void InputEventBuilder::OnPointerEvent(Msdp::NetPacket &packet)
216 {
217     int64_t curCrossPlatformTime = Utility::GetSysClockTime();
218     CHKPV(pointerEvent_);
219     CHKPV(env_);
220     if (scanState_) {
221         TurnOffChannelScan();
222     }
223     if ((pointerEventTimer_ >= 0)) {
224         env_->GetTimerManager().RemoveTimerAsync(pointerEventTimer_);
225         pointerEventTimer_ = -1;
226     }
227     pointerEvent_->Reset();
228     int64_t curInterceptorTime = -1;
229     int32_t ret = InputEventSerialization::Unmarshalling(packet, pointerEvent_, curInterceptorTime);
230     if (ret != RET_OK) {
231         FI_HILOGE("Failed to deserialize pointer event");
232         return;
233     }
234     TagRemoteEvent(pointerEvent_);
235     OnNotifyCrossDrag(pointerEvent_);
236     FI_HILOGD("PointerEvent(No:%{public}d, Source:%{public}s, Action:%{public}s)",
237         pointerEvent_->GetId(), pointerEvent_->DumpSourceType(), pointerEvent_->DumpPointerAction());
238     if (IsActive(pointerEvent_)) {
239         CheckLatency(pointerEvent_->GetActionTime(), curInterceptorTime, curCrossPlatformTime, pointerEvent_);
240         if (!UpdatePointerEvent()) {
241             return;
242         }
243         env_->GetInput().SimulateInputEvent(pointerEvent_);
244     }
245     pointerEventTimer_ = env_->GetTimerManager().AddTimerAsync(POINTER_EVENT_TIMEOUT, REPEAT_ONCE, [this]() {
246         TurnOnChannelScan();
247         pointerEventTimer_ = -1;
248     });
249 }
250 
CheckLatency(int64_t curDriveActionTime,int64_t curInterceptorTime,int64_t curCrossPlatformTime,std::shared_ptr<MMI::PointerEvent> pointerEvent)251 void InputEventBuilder::CheckLatency(int64_t curDriveActionTime, int64_t curInterceptorTime,
252     int64_t curCrossPlatformTime, std::shared_ptr<MMI::PointerEvent> pointerEvent)
253 {
254     CHKPV(pointerEvent);
255     if (pointerEvent->GetPointerAction() != MMI::PointerEvent::POINTER_ACTION_MOVE ||
256         curInterceptorTime == -1) {
257         preDriveEventTime_ = -1;
258         return;
259     }
260     if (preDriveEventTime_ < 0) {
261         preDriveEventTime_ = curDriveActionTime;
262         preInterceptorTime_ = curInterceptorTime;
263         preCrossPlatformTime_ = curCrossPlatformTime;
264         return;
265     }
266     driveEventTimeDT_ = curDriveActionTime - preDriveEventTime_;
267     cooperateInterceptorTimeDT_ = curInterceptorTime - preInterceptorTime_;
268     crossPlatformTimeDT_ = curCrossPlatformTime - preCrossPlatformTime_;
269     preDriveEventTime_ = curDriveActionTime;
270     preInterceptorTime_ = curInterceptorTime;
271     preCrossPlatformTime_ = curCrossPlatformTime;
272     TransmissionLatencyRadarInfo radarInfo {
273         .funcName = __FUNCTION__,
274         .bizState = static_cast<int32_t> (BizState::STATE_END),
275         .bizStage = static_cast<int32_t> (BizCooperateStage::STAGE_CLIENT_ON_MESSAGE_RCVD),
276         .stageRes = static_cast<int32_t> (BizCooperateStageRes::RES_IDLE),
277         .bizScene = static_cast<int32_t> (BizCooperateScene::SCENE_ACTIVE),
278         .localNetId = Utility::DFXRadarAnonymize(localNetworkId_.c_str()),
279         .peerNetId = Utility::DFXRadarAnonymize(remoteNetworkId_.c_str()),
280     };
281     int64_t DriveToInterceptorDT = Utility::GetSysClockTimeMilli(cooperateInterceptorTimeDT_ - driveEventTimeDT_);
282     int64_t InterceptorToCrossDT = std::abs(Utility::GetSysClockTimeMilli(
283         crossPlatformTimeDT_ - cooperateInterceptorTimeDT_));
284     if (DriveToInterceptorDT > DRIVE_INTERCEPTOR_LATENCY || InterceptorToCrossDT > INTERCEPTOR_TRANSMISSION_LATENCY) {
285         FI_HILOGI("driveEventTimeDT:%{public}" PRId64 ", cooperateInterceptorTimeDT:%{public}" PRId64 ""
286             "crossPlatformTimeDT:%{public}" PRId64, driveEventTimeDT_, cooperateInterceptorTimeDT_,
287             crossPlatformTimeDT_);
288         radarInfo.driveEventTimeDT = driveEventTimeDT_;
289         radarInfo.cooperateInterceptorTimeDT = cooperateInterceptorTimeDT_;
290         radarInfo.crossPlatformTimeDT = crossPlatformTimeDT_;
291         radarInfo.pointerSpeed = pointerSpeed_;
292         radarInfo.touchPadSpeed = touchPadSpeed_;
293         CooperateRadar::ReportTransmissionLatencyRadarInfo(radarInfo);
294     }
295 }
296 
OnNotifyCrossDrag(std::shared_ptr<MMI::PointerEvent> pointerEvent)297 void InputEventBuilder::OnNotifyCrossDrag(std::shared_ptr<MMI::PointerEvent> pointerEvent)
298 {
299     CHKPV(pointerEvent);
300     auto pointerAction = pointerEvent->GetPointerAction();
301     if (pointerAction == MMI::PointerEvent::POINTER_ACTION_PULL_IN_WINDOW ||
302         pointerAction == MMI::PointerEvent::POINTER_ACTION_PULL_OUT_WINDOW) {
303         FI_HILOGD("PointerAction:%{public}d, it's pressedButtons is empty, skip", pointerAction);
304         return;
305     }
306     auto pressedButtons = pointerEvent->GetPressedButtons();
307     bool isButtonDown = (pressedButtons.find(MMI::PointerEvent::MOUSE_BUTTON_LEFT) != pressedButtons.end());
308     FI_HILOGD("PointerAction:%{public}d, isPressed:%{public}s", pointerAction, isButtonDown ? "true" : "false");
309     CHKPV(env_);
310     env_->GetDragManager().NotifyCrossDrag(isButtonDown);
311 }
312 
OnKeyEvent(Msdp::NetPacket & packet)313 void InputEventBuilder::OnKeyEvent(Msdp::NetPacket &packet)
314 {
315     CHKPV(keyEvent_);
316     keyEvent_->Reset();
317     int32_t ret = InputEventSerialization::NetPacketToKeyEvent(packet, keyEvent_);
318     if (ret != RET_OK) {
319         FI_HILOGE("Failed to deserialize key event");
320         return;
321     }
322     UpdateKeyEvent(keyEvent_);
323     TagRemoteEvent(keyEvent_);
324     FI_HILOGD("KeyEvent(No:%{public}d,Key:%{private}d,Action:%{public}d)",
325         keyEvent_->GetId(), keyEvent_->GetKeyCode(), keyEvent_->GetKeyAction());
326     keyEvent_->AddFlag(MMI::InputEvent::EVENT_FLAG_SIMULATE);
327     env_->GetInput().SimulateInputEvent(keyEvent_);
328 }
329 
TurnOffChannelScan()330 void InputEventBuilder::TurnOffChannelScan()
331 {
332     CALL_INFO_TRACE;
333     scanState_ = false;
334     if (SetWifiScene(FORBIDDEN_SCENE) != RET_OK) {
335         scanState_ = true;
336         FI_HILOGE("Forbidden scene failed");
337     }
338 }
339 
ExecuteInner()340 void InputEventBuilder::ExecuteInner()
341 {
342     CALL_DEBUG_ENTER;
343     // to enable low latency mode: value = 0
344     OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(
345         OHOS::ResourceSchedule::ResType::RES_TYPE_NETWORK_LATENCY_REQUEST, MODE_ENABLE,
346         {{LOW_LATENCY_KEY, FI_PKG_NAME}});
347 }
348 
HandleStopTimer()349 void InputEventBuilder::HandleStopTimer()
350 {
351     CALL_DEBUG_ENTER;
352     OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(
353         OHOS::ResourceSchedule::ResType::RES_TYPE_NETWORK_LATENCY_REQUEST, MODE_DISABLE,
354         {{LOW_LATENCY_KEY, FI_PKG_NAME}});
355 }
356 
TurnOnChannelScan()357 void InputEventBuilder::TurnOnChannelScan()
358 {
359     CALL_INFO_TRACE;
360     scanState_ = true;
361     if (SetWifiScene(RESTORE_SCENE) != RET_OK) {
362         scanState_ = false;
363         FI_HILOGE("Restore scene failed");
364     }
365 }
366 
SetWifiScene(unsigned int scene)367 int32_t InputEventBuilder::SetWifiScene(unsigned int scene)
368 {
369     CALL_DEBUG_ENTER;
370     Hid2dUpperScene upperScene;
371     upperScene.scene = scene;
372     upperScene.fps = UPPER_SCENE_FPS;
373     upperScene.bw = UPPER_SCENE_BW;
374     if (Hid2dSetUpperScene(WIFI_INTERFACE_NAME.c_str(), &upperScene) != RET_OK) {
375         FI_HILOGE("Set wifi scene failed");
376         return RET_ERR;
377     }
378     return RET_OK;
379 }
380 
UpdatePointerEvent()381 bool InputEventBuilder::UpdatePointerEvent()
382 {
383     if (pointerEvent_->GetSourceType() != MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
384         return true;
385     }
386     if (!DampPointerMotion(pointerEvent_)) {
387         FI_HILOGE("DampPointerMotion fail");
388         return false;
389     }
390     pointerEvent_->AddFlag(MMI::InputEvent::EVENT_FLAG_RAW_POINTER_MOVEMENT);
391     int64_t time = Utility::GetSysClockTime();
392     pointerEvent_->SetActionTime(time);
393     pointerEvent_->SetActionStartTime(time);
394     pointerEvent_->SetTargetDisplayId(-1);
395     pointerEvent_->SetTargetWindowId(-1);
396     pointerEvent_->SetAgentWindowId(-1);
397     return true;
398 }
399 
DampPointerMotion(std::shared_ptr<MMI::PointerEvent> pointerEvent)400 bool InputEventBuilder::DampPointerMotion(std::shared_ptr<MMI::PointerEvent> pointerEvent)
401 {
402     MMI::PointerEvent::PointerItem item;
403     if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), item)) {
404         FI_HILOGE("Corrupted pointer event");
405         return false;
406     }
407     // Dampling pointer movement.
408     // First transition will trigger special effect which would damp pointer movement. We want to
409     // damp pointer movement even further than that could be achieved by setting pointer speed.
410     // By scaling increment of pointer movement, we want to enlarge the range of pointer speed setting.
411     if (item.GetRawDx() > 0) {
412         double rawDxRight = rawDxRightRemainder_ + item.GetRawDx() * GetDamplingCoefficient(
413             DamplingDirection::DAMPLING_DIRECTION_RIGHT);
414         int32_t rawDxIntegerRight = static_cast<int32_t>(rawDxRight);
415         rawDxRightRemainder_ = rawDxRight - static_cast<double>(rawDxIntegerRight);
416         item.SetRawDx(rawDxIntegerRight);
417     } else if (item.GetRawDx() < 0) {
418         double rawDxLeft = rawDxLeftRemainder_ + item.GetRawDx() * GetDamplingCoefficient(
419             DamplingDirection::DAMPLING_DIRECTION_LEFT);
420         int32_t rawDxIntegerLeft = static_cast<int32_t>(rawDxLeft);
421         rawDxLeftRemainder_ = rawDxLeft - static_cast<double>(rawDxIntegerLeft);
422         item.SetRawDx(rawDxIntegerLeft);
423     }
424     if (item.GetRawDy() >= 0) {
425         item.SetRawDy(static_cast<int32_t>(
426             item.GetRawDy() * GetDamplingCoefficient(DamplingDirection::DAMPLING_DIRECTION_DOWN)));
427     } else {
428         item.SetRawDy(static_cast<int32_t>(
429             item.GetRawDy() * GetDamplingCoefficient(DamplingDirection::DAMPLING_DIRECTION_UP)));
430     }
431     pointerEvent->UpdatePointerItem(pointerEvent->GetPointerId(), item);
432     return true;
433 }
434 
UpdateKeyEvent(std::shared_ptr<MMI::KeyEvent> keyEvent)435 void InputEventBuilder::UpdateKeyEvent(std::shared_ptr<MMI::KeyEvent> keyEvent)
436 {
437     int64_t time = Utility::GetSysClockTime();
438     keyEvent->SetActionTime(time);
439     keyEvent->SetActionStartTime(time);
440 }
441 
TagRemoteEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent)442 void InputEventBuilder::TagRemoteEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent)
443 {
444     std::shared_lock<std::shared_mutex> lock(lock_);
445     if (auto deviceId = pointerEvent->GetDeviceId(); remote2VirtualIds_.find(deviceId) != remote2VirtualIds_.end()) {
446         pointerEvent->SetDeviceId(remote2VirtualIds_[deviceId]);
447     } else {
448         pointerEvent->SetDeviceId((deviceId >= 0) ? -(deviceId + 1) : deviceId);
449     }
450 }
451 
TagRemoteEvent(std::shared_ptr<MMI::KeyEvent> keyEvent)452 void InputEventBuilder::TagRemoteEvent(std::shared_ptr<MMI::KeyEvent> keyEvent)
453 {
454     std::shared_lock<std::shared_mutex> lock(lock_);
455     if (auto deviceId = keyEvent->GetDeviceId(); remote2VirtualIds_.find(deviceId) != remote2VirtualIds_.end()) {
456         keyEvent->SetDeviceId(remote2VirtualIds_[deviceId]);
457     } else {
458         keyEvent->SetDeviceId((deviceId >= 0) ? -(deviceId + 1) : deviceId);
459     }
460 }
461 
IsActive(std::shared_ptr<MMI::PointerEvent> pointerEvent)462 bool InputEventBuilder::IsActive(std::shared_ptr<MMI::PointerEvent> pointerEvent)
463 {
464     if (!freezing_) {
465         return true;
466     }
467     if ((pointerEvent->GetSourceType() != MMI::PointerEvent::SOURCE_TYPE_MOUSE) ||
468         ((pointerEvent->GetPointerAction() != MMI::PointerEvent::POINTER_ACTION_MOVE) &&
469          (pointerEvent->GetPointerAction() != MMI::PointerEvent::POINTER_ACTION_PULL_MOVE))) {
470         return true;
471     }
472     MMI::PointerEvent::PointerItem item;
473     if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), item)) {
474         FI_HILOGE("Corrupted pointer event");
475         return false;
476     }
477     movement_ += item.GetRawDx();
478     movement_ = std::clamp(movement_, -DEFAULT_SCREEN_WIDTH, DEFAULT_SCREEN_WIDTH);
479     if (xDir_ == 0) {
480         xDir_ = movement_;
481     }
482     if (((xDir_ > 0) && (movement_ <= 0)) || ((xDir_ < 0) && (movement_ >= 0))) {
483         return true;
484     }
485     if ((nDropped_++ % LOG_PERIOD) == 0) {
486         FI_HILOGI("Remote input from '%{public}s' is freezing", Utility::Anonymize(remoteNetworkId_).c_str());
487     }
488     return false;
489 }
490 
ResetPressedEvents()491 void InputEventBuilder::ResetPressedEvents()
492 {
493     CHKPV(env_);
494     CHKPV(pointerEvent_);
495     if (auto pressedButtons = pointerEvent_->GetPressedButtons(); !pressedButtons.empty()) {
496         auto dragState = env_->GetDragManager().GetDragState();
497         for (auto buttonId : pressedButtons) {
498             if (dragState == DragState::START && buttonId == MMI::PointerEvent::MOUSE_BUTTON_LEFT) {
499                 FI_HILOGI("Dragging with mouse_button_left down, skip");
500                 continue;
501             }
502             pointerEvent_->SetButtonId(buttonId);
503             pointerEvent_->SetPointerAction(MMI::PointerEvent::POINTER_ACTION_BUTTON_UP);
504             env_->GetInput().SimulateInputEvent(pointerEvent_);
505             FI_HILOGI("Simulate button-up event, buttonId:%{public}d", buttonId);
506         }
507         pointerEvent_->Reset();
508     }
509 }
510 } // namespace Cooperate
511 } // namespace DeviceStatus
512 } // namespace Msdp
513 } // namespace OHOS
514