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