• 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 "cooperate_in.h"
17 #include "cooperate_hisysevent.h"
18 
19 #include "devicestatus_define.h"
20 #include "utility.h"
21 
22 #undef LOG_TAG
23 #define LOG_TAG "CooperateIn"
24 
25 namespace OHOS {
26 namespace Msdp {
27 namespace DeviceStatus {
28 namespace Cooperate {
29 
CooperateIn(IStateMachine & parent,IContext * env)30 CooperateIn::CooperateIn(IStateMachine &parent, IContext *env)
31     : ICooperateState(parent), env_(env)
32 {
33     initial_ = std::make_shared<Initial>(*this);
34     Initial::BuildChains(initial_, *this);
35     current_ = initial_;
36 }
37 
~CooperateIn()38 CooperateIn::~CooperateIn()
39 {
40     Initial::RemoveChains(initial_);
41 }
42 
OnEvent(Context & context,const CooperateEvent & event)43 void CooperateIn::OnEvent(Context &context, const CooperateEvent &event)
44 {
45     current_->OnEvent(context, event);
46 }
47 
OnEnterState(Context & context)48 void CooperateIn::OnEnterState(Context &context)
49 {
50     CALL_INFO_TRACE;
51     int32_t ret = env_->GetInput().SetPointerVisibility(!context.NeedHideCursor(), PRIORITY);
52     CooperateRadarInfo radarInfo {
53         .funcName = __FUNCTION__,
54         .bizState = static_cast<int32_t> (BizState::STATE_END),
55         .bizScene = static_cast<int32_t> (BizCooperateScene::SCENE_PASSIVE),
56         .hostName = "",
57         .localNetId = "",
58         .peerNetId = ""
59     };
60     if (ret != RET_OK) {
61         radarInfo.bizStage = static_cast<int32_t> (BizCooperateStage::STAGE_PASSIVE_CURSOR_VISIBILITY);
62         radarInfo.stageRes = static_cast<int32_t> (BizCooperateStageRes::RES_FAIL);
63         radarInfo.errCode = static_cast<int32_t> (CooperateRadarErrCode::PASSIVE_CURSOR_VISIBILITY_FAILED);
64         CooperateRadar::ReportCooperateRadarInfo(radarInfo);
65     }
66     radarInfo.bizStage = static_cast<int32_t> (BizCooperateStage::STAGE_PASSIVE_CURSOR_VISIBILITY);
67     radarInfo.stageRes = static_cast<int32_t> (BizCooperateStageRes::RES_SUCCESS);
68     radarInfo.errCode = static_cast<int32_t> (CooperateRadarErrCode::CALLING_COOPERATE_SUCCESS);
69     CooperateRadar::ReportCooperateRadarInfo(radarInfo);
70 }
71 
OnLeaveState(Context & context)72 void CooperateIn::OnLeaveState(Context & context)
73 {
74     CALL_INFO_TRACE;
75     UpdateCooperateFlagEvent event {
76         .mask = COOPERATE_FLAG_HIDE_CURSOR,
77         .flag = COOPERATE_FLAG_HIDE_CURSOR,
78     };
79     context.UpdateCooperateFlag(event);
80     CHKPV(env_);
81     env_->GetInput().SetPointerVisibility(false);
82 }
83 
84 std::set<int32_t> CooperateIn::Initial::filterPointerActions_ {
85     MMI::PointerEvent::POINTER_ACTION_ENTER_WINDOW,
86     MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW,
87     MMI::PointerEvent::POINTER_ACTION_PULL_IN_WINDOW,
88     MMI::PointerEvent::POINTER_ACTION_PULL_OUT_WINDOW,
89 };
90 
BuildChains(std::shared_ptr<Initial> self,CooperateIn & parent)91 void CooperateIn::Initial::BuildChains(std::shared_ptr<Initial> self, CooperateIn &parent)
92 {
93     auto s11 = std::make_shared<RelayConfirmation>(parent, self);
94     self->relay_ = s11;
95     s11->SetNext(self);
96 }
97 
RemoveChains(std::shared_ptr<Initial> self)98 void CooperateIn::Initial::RemoveChains(std::shared_ptr<Initial> self)
99 {
100     if (self->relay_ != nullptr) {
101         self->relay_->SetNext(nullptr);
102         self->relay_ = nullptr;
103     }
104 }
105 
Initial(CooperateIn & parent)106 CooperateIn::Initial::Initial(CooperateIn &parent)
107     : ICooperateStep(parent, nullptr), parent_(parent)
108 {
109     AddHandler(CooperateEventType::DISABLE, [this](Context &context, const CooperateEvent &event) {
110         this->OnDisable(context, event);
111     });
112     AddHandler(CooperateEventType::START, [this](Context &context, const CooperateEvent &event) {
113         this->OnStart(context, event);
114     });
115     AddHandler(CooperateEventType::STOP, [this](Context &context, const CooperateEvent &event) {
116         this->OnStop(context, event);
117     });
118     AddHandler(CooperateEventType::APP_CLOSED, [this](Context &context, const CooperateEvent &event) {
119         this->OnAppClosed(context, event);
120     });
121     AddHandler(CooperateEventType::INPUT_POINTER_EVENT, [this](Context &context, const CooperateEvent &event) {
122         this->OnPointerEvent(context, event);
123     });
124     AddHandler(CooperateEventType::DDM_BOARD_OFFLINE, [this](Context &context, const CooperateEvent &event) {
125         this->OnBoardOffline(context, event);
126     });
127     AddHandler(CooperateEventType::DDP_COOPERATE_SWITCH_CHANGED,
128         [this](Context &context, const CooperateEvent &event) {
129             this->OnSwitchChanged(context, event);
130     });
131     AddHandler(CooperateEventType::DSOFTBUS_SESSION_CLOSED,
132         [this](Context &context, const CooperateEvent &event) {
133             this->OnSoftbusSessionClosed(context, event);
134     });
135     AddHandler(CooperateEventType::DSOFTBUS_START_COOPERATE,
136         [this](Context &context, const CooperateEvent &event) {
137             this->OnRemoteStart(context, event);
138     });
139     AddHandler(CooperateEventType::DSOFTBUS_STOP_COOPERATE,
140         [this](Context &context, const CooperateEvent &event) {
141             this->OnRemoteStop(context, event);
142     });
143     AddHandler(CooperateEventType::UPDATE_COOPERATE_FLAG,
144         [this](Context &context, const CooperateEvent &event) {
145             this->OnUpdateCooperateFlag(context, event);
146     });
147     AddHandler(CooperateEventType::DSOFTBUS_INPUT_DEV_SYNC,
148         [this](Context &context, const CooperateEvent &event) {
149             this->OnRemoteInputDevice(context, event);
150     });
151     AddHandler(CooperateEventType::WITH_OPTIONS_START,
152         [this](Context &context, const CooperateEvent &event) {
153             this->OnStartWithOptions(context, event);
154     });
155     AddHandler(CooperateEventType::DSOFTBUS_COOPERATE_WITH_OPTIONS,
156         [this](Context &context, const CooperateEvent &event) {
157             this->OnRemoteStartWithOptions(context, event);
158     });
159 }
160 
OnDisable(Context & context,const CooperateEvent & event)161 void CooperateIn::Initial::OnDisable(Context &context, const CooperateEvent &event)
162 {
163     FI_HILOGI("[disable cooperation] Stop cooperation");
164     parent_.StopCooperate(context, event);
165 }
166 
OnStart(Context & context,const CooperateEvent & event)167 void CooperateIn::Initial::OnStart(Context &context, const CooperateEvent &event)
168 {
169     CALL_INFO_TRACE;
170     CHKPV(parent_.env_);
171     StartCooperateEvent startEvent = std::get<StartCooperateEvent>(event.event);
172     context.ResetPriv();
173 
174     if (parent_.env_->GetDragManager().GetDragState() == DragState::MOTION_DRAGGING) {
175         FI_HILOGE("Not allow cooperate");
176         NotAollowCooperateWhenMotionDragging result {
177             .pid = startEvent.pid,
178             .userData = startEvent.userData,
179             .networkId = startEvent.remoteNetworkId,
180             .success = false,
181             .errCode = static_cast<int32_t>(CoordinationErrCode::NOT_AOLLOW_COOPERATE_WHEN_MOTION_DRAGGING)
182         };
183         context.eventMgr_.ErrorNotAollowCooperateWhenMotionDragging(result);
184         return;
185     }
186     if (context.IsLocal(startEvent.remoteNetworkId)) {
187         DSoftbusStartCooperateFinished result {
188             .success = false,
189             .errCode = static_cast<int32_t>(CoordinationErrCode::UNEXPECTED_START_CALL)
190         };
191         context.eventMgr_.StartCooperateFinish(result);
192         return;
193     }
194     FI_HILOGI("[start] start cooperation(%{public}s, %{public}d)",
195         Utility::Anonymize(startEvent.remoteNetworkId).c_str(), startEvent.startDeviceId);
196     context.eventMgr_.StartCooperate(startEvent);
197 
198     if (context.IsPeer(startEvent.remoteNetworkId)) {
199         OnComeBack(context, event);
200     } else {
201         OnRelay(context, event);
202     }
203 }
204 
OnComeBack(Context & context,const CooperateEvent & event)205 void CooperateIn::Initial::OnComeBack(Context &context, const CooperateEvent &event)
206 {
207     CALL_INFO_TRACE;
208     context.inputEventBuilder_.Disable();
209     FI_HILOGI("[come back] To \'%{public}s\'", Utility::Anonymize(context.Peer()).c_str());
210     StartCooperateEvent startEvent = std::get<StartCooperateEvent>(event.event);
211     DSoftbusComeBack notice {
212         .originNetworkId = context.Local(),
213         .success = true,
214         .cursorPos = context.NormalizedCursorPosition(),
215         .uid = startEvent.uid
216     };
217     context.OnStartCooperate(notice.extra);
218     if (context.dsoftbus_.ComeBack(context.Peer(), notice) != RET_OK) {
219         notice.success = false;
220         notice.errCode = static_cast<int32_t>(CoordinationErrCode::SEND_PACKET_FAILED);
221     }
222     context.eventMgr_.StartCooperateFinish(notice);
223     TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
224     context.OnBack();
225 }
226 
OnRelay(Context & context,const CooperateEvent & event)227 void CooperateIn::Initial::OnRelay(Context &context, const CooperateEvent &event)
228 {
229     CALL_INFO_TRACE;
230     StartCooperateEvent startEvent = std::get<StartCooperateEvent>(event.event);
231     parent_.process_.StartCooperate(context, startEvent);
232     FI_HILOGI("[relay cooperate] To \'%{public}s\'", Utility::Anonymize(parent_.process_.Peer()).c_str());
233 
234     if (relay_ != nullptr) {
235         Switch(relay_);
236         relay_->OnProgress(context, event);
237     }
238 }
239 
OnRelayWithOptions(Context & context,const CooperateEvent & event)240 void CooperateIn::Initial::OnRelayWithOptions(Context &context, const CooperateEvent &event)
241 {
242     CALL_INFO_TRACE;
243     StartWithOptionsEvent startEvent = std::get<StartWithOptionsEvent>(event.event);
244     parent_.process_.StartCooperateWithOptions(context, startEvent);
245     FI_HILOGI("[relay cooperate With Options] To '%{public}s'", Utility::Anonymize(parent_.process_.Peer()).c_str());
246     if (relay_ == nullptr) {
247         FI_HILOGE("relay_ is nullptr");
248         return;
249     }
250     Switch(relay_);
251     relay_->OnProgressWithOptions(context, event);
252 }
253 
OnStartWithOptions(Context & context,const CooperateEvent & event)254 void CooperateIn::Initial::OnStartWithOptions(Context &context, const CooperateEvent &event)
255 {
256     CALL_INFO_TRACE;
257     CHKPV(parent_.env_);
258     StartWithOptionsEvent startEvent = std::get<StartWithOptionsEvent>(event.event);
259     context.ResetPriv();
260     context.UpdateCooperateOptions(startEvent);
261     if (parent_.env_->GetDragManager().GetDragState() == DragState::MOTION_DRAGGING) {
262         FI_HILOGE("Not allow cooperate");
263         NotAollowCooperateWhenMotionDragging result {
264             .pid = startEvent.pid,
265             .userData = startEvent.userData,
266             .networkId = startEvent.remoteNetworkId,
267             .success = false,
268             .errCode = static_cast<int32_t>(CoordinationErrCode::NOT_AOLLOW_COOPERATE_WHEN_MOTION_DRAGGING)
269         };
270         context.eventMgr_.ErrorNotAollowCooperateWhenMotionDragging(result);
271         return;
272     }
273     if (context.IsLocal(startEvent.remoteNetworkId)) {
274         DSoftbusCooperateWithOptionsFinished result {
275             .success = false,
276             .errCode = static_cast<int32_t>(CoordinationErrCode::UNEXPECTED_START_CALL)
277         };
278         context.eventMgr_.StartCooperateWithOptionsFinish(result);
279         return;
280     }
281     FI_HILOGI("[start] with options start cooperation(%{public}s, %{public}d)",
282         Utility::Anonymize(startEvent.remoteNetworkId).c_str(), startEvent.startDeviceId);
283     context.eventMgr_.StartCooperateWithOptions(startEvent);
284     if (context.IsPeer(startEvent.remoteNetworkId)) {
285         OnComeBackWithOptions(context, event);
286     } else {
287         OnRelayWithOptions(context, event);
288     }
289 }
290 
OnComeBackWithOptions(Context & context,const CooperateEvent & event)291 void CooperateIn::Initial::OnComeBackWithOptions(Context &context, const CooperateEvent &event)
292 {
293     CALL_INFO_TRACE;
294     context.inputEventBuilder_.Disable();
295     FI_HILOGI("[come back] To \'%{public}s\'", Utility::Anonymize(context.Peer()).c_str());
296     StartWithOptionsEvent withOptionsNotice = std::get<StartWithOptionsEvent>(event.event);
297     DSoftbusComeBackWithOptions notice {
298         .originNetworkId = context.Local(),
299         .success = true,
300         .cooperateOptions = {withOptionsNotice.displayX, withOptionsNotice.displayY, withOptionsNotice.displayId},
301     };
302     context.OnStartCooperate(notice.extra);
303     if (context.dsoftbus_.ComeBackWithOptions(context.Peer(), notice) != RET_OK) {
304         notice.success = false;
305         notice.errCode = static_cast<int32_t>(CoordinationErrCode::SEND_PACKET_FAILED);
306     }
307     context.eventMgr_.StartCooperateWithOptionsFinish(notice);
308     context.inputDevMgr_.RemoveVirtualInputDevice(context.Peer());
309     TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
310     context.OnBack();
311 }
312 
OnStop(Context & context,const CooperateEvent & event)313 void CooperateIn::Initial::OnStop(Context &context, const CooperateEvent &event)
314 {
315     CALL_INFO_TRACE;
316     StopCooperateEvent param = std::get<StopCooperateEvent>(event.event);
317 
318     context.eventMgr_.StopCooperate(param);
319     parent_.StopCooperate(context, event);
320 
321     param.networkId = context.Peer();
322     DSoftbusStopCooperateFinished notice {
323         .networkId = context.Peer(),
324         .normal = true,
325     };
326     context.eventMgr_.StopCooperateFinish(notice);
327 
328     parent_.UnchainConnections(context, param);
329 }
330 
OnRemoteStart(Context & context,const CooperateEvent & event)331 void CooperateIn::Initial::OnRemoteStart(Context &context, const CooperateEvent &event)
332 {
333     CALL_INFO_TRACE;
334     DSoftbusStartCooperate notice = std::get<DSoftbusStartCooperate>(event.event);
335     context.StorePeerPointerSpeed(notice.pointerSpeed);
336     context.StorePeerTouchPadSpeed(notice.touchPadSpeed);
337     if (context.IsPeer(notice.networkId) || context.IsLocal(notice.networkId)) {
338         return;
339     }
340     context.OnResetCooperation();
341     context.OnRemoteStartCooperate(notice.extra);
342     context.eventMgr_.RemoteStart(notice);
343 
344     DSoftbusStopCooperate stopNotice {};
345     context.dsoftbus_.StopCooperate(context.Peer(), stopNotice);
346 
347     context.RemoteStartSuccess(notice);
348     context.inputEventBuilder_.Update(context);
349     context.eventMgr_.RemoteStartFinish(notice);
350     FI_HILOGI("[remote start] Cooperation with \'%{public}s\' established", Utility::Anonymize(context.Peer()).c_str());
351     context.OnTransitionIn();
352 }
353 
OnRemoteStartWithOptions(Context & context,const CooperateEvent & event)354 void CooperateIn::Initial::OnRemoteStartWithOptions(Context &context, const CooperateEvent &event)
355 {
356     CALL_INFO_TRACE;
357     DSoftbusCooperateOptions notice = std::get<DSoftbusCooperateOptions>(event.event);
358     context.StorePeerPointerSpeed(notice.pointerSpeed);
359     context.StorePeerTouchPadSpeed(notice.touchPadSpeed);
360     if (context.IsPeer(notice.networkId) || context.IsLocal(notice.networkId)) {
361         return;
362     }
363     context.OnResetCooperation();
364     context.OnRemoteStartCooperate(notice.extra);
365     context.eventMgr_.RemoteStartWithOptions(notice);
366 
367     DSoftbusStopCooperate stopNotice {};
368     context.dsoftbus_.StopCooperate(context.Peer(), stopNotice);
369     context.AdjustPointerPos(notice);
370     context.OnRemoteStart(notice);
371     context.inputEventBuilder_.Update(context);
372     context.eventMgr_.RemoteStartWithOptionsFinish(notice);
373     FI_HILOGI("[remote start cooperate with options] Cooperation with \'%{public}s\' established",
374         Utility::Anonymize(context.Peer()).c_str());
375     context.OnTransitionIn();
376 }
377 
OnRemoteStop(Context & context,const CooperateEvent & event)378 void CooperateIn::Initial::OnRemoteStop(Context &context, const CooperateEvent &event)
379 {
380     DSoftbusStopCooperate notice = std::get<DSoftbusStopCooperate>(event.event);
381 
382     if (!context.IsPeer(notice.networkId)) {
383         return;
384     }
385     FI_HILOGI("[remote stop] Notification from \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
386     context.eventMgr_.RemoteStop(notice);
387     context.inputEventBuilder_.Disable();
388     context.eventMgr_.RemoteStopFinish(notice);
389     context.inputDevMgr_.RemoveVirtualInputDevice(context.Peer());
390     TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
391     context.OnResetCooperation();
392 }
393 
OnAppClosed(Context & context,const CooperateEvent & event)394 void CooperateIn::Initial::OnAppClosed(Context &context, const CooperateEvent &event)
395 {
396     FI_HILOGI("[app closed] Close all connections");
397     context.dsoftbus_.CloseAllSessions();
398     FI_HILOGI("[app closed] Stop cooperation");
399     parent_.StopCooperate(context, event);
400 }
401 
OnPointerEvent(Context & context,const CooperateEvent & event)402 void CooperateIn::Initial::OnPointerEvent(Context &context, const CooperateEvent &event)
403 {
404     InputPointerEvent notice = std::get<InputPointerEvent>(event.event);
405 
406     if ((notice.sourceType != MMI::PointerEvent::SOURCE_TYPE_MOUSE) ||
407         (filterPointerActions_.find(notice.pointerAction) != filterPointerActions_.end()) ||
408         !InputEventBuilder::IsLocalEvent(notice)) {
409         return;
410     }
411     FI_HILOGI("Stop cooperation on operation of local pointer");
412     context.OnPointerEvent(notice);
413     parent_.StopCooperate(context, event);
414 }
415 
OnBoardOffline(Context & context,const CooperateEvent & event)416 void CooperateIn::Initial::OnBoardOffline(Context &context, const CooperateEvent &event)
417 {
418     DDMBoardOfflineEvent notice = std::get<DDMBoardOfflineEvent>(event.event);
419 
420     if (!context.IsPeer(notice.networkId)) {
421         return;
422     }
423     FI_HILOGI("[board offline] Peer(\'%{public}s\') is offline", Utility::Anonymize(notice.networkId).c_str());
424     parent_.StopCooperate(context, event);
425 }
426 
OnSwitchChanged(Context & context,const CooperateEvent & event)427 void CooperateIn::Initial::OnSwitchChanged(Context &context, const CooperateEvent &event)
428 {
429     DDPCooperateSwitchChanged notice = std::get<DDPCooperateSwitchChanged>(event.event);
430 
431     if (!context.IsPeer(notice.networkId) || notice.normal) {
432         return;
433     }
434     FI_HILOGI("[switch off] Peer(\'%{public}s\') switch off", Utility::Anonymize(notice.networkId).c_str());
435     parent_.StopCooperate(context, event);
436 }
437 
OnSoftbusSessionClosed(Context & context,const CooperateEvent & event)438 void CooperateIn::Initial::OnSoftbusSessionClosed(Context &context, const CooperateEvent &event)
439 {
440     DSoftbusSessionClosed notice = std::get<DSoftbusSessionClosed>(event.event);
441 
442     if (!context.IsPeer(notice.networkId)) {
443         return;
444     }
445     FI_HILOGI("[softbus session closed] Disconnected with \'%{public}s\'",
446         Utility::Anonymize(notice.networkId).c_str());
447     parent_.StopCooperate(context, event);
448     context.eventMgr_.OnSoftbusSessionClosed(notice);
449 }
450 
OnRemoteInputDevice(Context & context,const CooperateEvent & event)451 void CooperateIn::Initial::OnRemoteInputDevice(Context &context, const CooperateEvent &event)
452 {
453     CALL_INFO_TRACE;
454     DSoftbusSyncInputDevice notice = std::get<DSoftbusSyncInputDevice>(event.event);
455     if (!context.IsPeer(notice.networkId)) {
456         return;
457     }
458     FI_HILOGI("Remote input device from \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
459     context.inputDevMgr_.AddVirtualInputDevice(notice.networkId);
460 }
461 
OnRemoteHotPlug(Context & context,const CooperateEvent & event)462 void CooperateIn::Initial::OnRemoteHotPlug(Context &context, const CooperateEvent &event)
463 {
464     DSoftbusHotPlugEvent notice = std::get<DSoftbusHotPlugEvent>(event.event);
465     if (!context.IsPeer(notice.networkId)) {
466         return;
467     }
468     FI_HILOGI("Remote hot plug event from \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
469 }
470 
OnUpdateCooperateFlag(Context & context,const CooperateEvent & event)471 void CooperateIn::Initial::OnUpdateCooperateFlag(Context &context, const CooperateEvent &event)
472 {
473     UpdateCooperateFlagEvent notice = std::get<UpdateCooperateFlagEvent>(event.event);
474     uint32_t changed = (notice.mask & (context.CooperateFlag() ^ notice.flag));
475     context.UpdateCooperateFlag(notice);
476 
477     if (changed & COOPERATE_FLAG_FREEZE_CURSOR) {
478         FI_HILOGI("Toggle freezing state of cursor");
479         if (notice.flag & COOPERATE_FLAG_FREEZE_CURSOR) {
480             context.inputEventBuilder_.Freeze();
481         } else {
482             context.inputEventBuilder_.Thaw();
483         }
484     }
485 }
486 
OnProgress(Context & context,const CooperateEvent & event)487 void CooperateIn::Initial::OnProgress(Context &context, const CooperateEvent &event)
488 {}
489 
OnReset(Context & context,const CooperateEvent & event)490 void CooperateIn::Initial::OnReset(Context &context, const CooperateEvent &event)
491 {}
492 
OnProgressWithOptions(Context & context,const CooperateEvent & event)493 void CooperateIn::Initial::OnProgressWithOptions(Context &context, const CooperateEvent &event)
494 {}
495 
RelayConfirmation(CooperateIn & parent,std::shared_ptr<ICooperateStep> prev)496 CooperateIn::RelayConfirmation::RelayConfirmation(CooperateIn &parent, std::shared_ptr<ICooperateStep> prev)
497     : ICooperateStep(parent, prev), parent_(parent)
498 {
499     AddHandler(CooperateEventType::DISABLE, [this](Context &context, const CooperateEvent &event) {
500         this->OnDisable(context, event);
501     });
502     AddHandler(CooperateEventType::STOP, [this](Context &context, const CooperateEvent &event) {
503         this->OnStop(context, event);
504     });
505     AddHandler(CooperateEventType::APP_CLOSED, [this](Context &context, const CooperateEvent &event) {
506         this->OnAppClosed(context, event);
507     });
508     AddHandler(CooperateEventType::INPUT_POINTER_EVENT,
509         [this](Context &context, const CooperateEvent &event) {
510             this->OnPointerEvent(context, event);
511     });
512     AddHandler(CooperateEventType::DDM_BOARD_OFFLINE,
513         [this](Context &context, const CooperateEvent &event) {
514             this->OnBoardOffline(context, event);
515     });
516     AddHandler(CooperateEventType::DDP_COOPERATE_SWITCH_CHANGED,
517         [this](Context &context, const CooperateEvent &event) {
518             this->OnSwitchChanged(context, event);
519     });
520     AddHandler(CooperateEventType::DSOFTBUS_SESSION_CLOSED,
521         [this](Context &context, const CooperateEvent &event) {
522             this->OnSoftbusSessionClosed(context, event);
523     });
524     AddHandler(CooperateEventType::DSOFTBUS_RELAY_COOPERATE_FINISHED,
525         [this](Context &context, const CooperateEvent &event) {
526             this->OnResponse(context, event);
527     });
528     AddHandler(CooperateEventType::DSOFTBUS_START_COOPERATE,
529         [this](Context &context, const CooperateEvent &event) {
530             this->OnRemoteStart(context, event);
531     });
532     AddHandler(CooperateEventType::DSOFTBUS_STOP_COOPERATE,
533         [this](Context &context, const CooperateEvent &event) {
534             this->OnRemoteStop(context, event);
535     });
536     AddHandler(CooperateEventType::DSOFTBUS_COOPERATE_WITH_OPTIONS,
537         [this](Context &context, const CooperateEvent &event) {
538             this->OnRemoteStartWithOptions(context, event);
539     });
540     AddHandler(CooperateEventType::DSOFTBUS_RELAY_COOPERATE_WITHOPTIONS_FINISHED,
541         [this](Context &context, const CooperateEvent &event) {
542             this->OnResponseWithOptions(context, event);
543     });
544 }
545 
OnDisable(Context & context,const CooperateEvent & event)546 void CooperateIn::RelayConfirmation::OnDisable(Context &context, const CooperateEvent &event)
547 {
548     FI_HILOGI("[relay cooperate] Disable cooperation");
549     parent_.StopCooperate(context, event);
550     OnReset(context, event);
551 }
552 
OnStop(Context & context,const CooperateEvent & event)553 void CooperateIn::RelayConfirmation::OnStop(Context &context, const CooperateEvent &event)
554 {
555     FI_HILOGI("[relay cooperate] Stop cooperation");
556     parent_.StopCooperate(context, event);
557     OnReset(context, event);
558 
559     StopCooperateEvent param = std::get<StopCooperateEvent>(event.event);
560     parent_.UnchainConnections(context, param);
561 }
562 
OnRemoteStart(Context & context,const CooperateEvent & event)563 void CooperateIn::RelayConfirmation::OnRemoteStart(Context &context, const CooperateEvent &event)
564 {
565     CALL_INFO_TRACE;
566     DSoftbusStartCooperate notice = std::get<DSoftbusStartCooperate>(event.event);
567     context.StorePeerPointerSpeed(notice.pointerSpeed);
568     context.StorePeerTouchPadSpeed(notice.touchPadSpeed);
569     if (context.IsPeer(notice.networkId) || context.IsLocal(notice.networkId)) {
570         return;
571     }
572     FI_HILOGI("[remote start] Notification from %{public}s", Utility::Anonymize(notice.networkId).c_str());
573     if (parent_.process_.IsPeer(notice.networkId)) {
574         auto ret = context.Sender().Send(event);
575         if (ret != Channel<CooperateEvent>::NO_ERROR) {
576             FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
577         }
578         OnResetWithNotifyMessage(context, event);
579         return;
580     }
581     parent_.env_->GetTimerManager().AddTimer(DEFAULT_COOLING_TIME, REPEAT_ONCE,
582         [sender = context.Sender(), event]() mutable {
583             auto ret = sender.Send(event);
584             if (ret != Channel<CooperateEvent>::NO_ERROR) {
585                 FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
586             }
587         });
588 }
589 
OnRemoteStartWithOptions(Context & context,const CooperateEvent & event)590 void CooperateIn::RelayConfirmation::OnRemoteStartWithOptions(Context &context, const CooperateEvent &event)
591 {
592     CALL_INFO_TRACE;
593     DSoftbusCooperateOptions notice = std::get<DSoftbusCooperateOptions>(event.event);
594     context.StorePeerPointerSpeed(notice.pointerSpeed);
595     context.StorePeerTouchPadSpeed(notice.touchPadSpeed);
596     if (context.IsPeer(notice.networkId) || context.IsLocal(notice.networkId)) {
597         return;
598     }
599     FI_HILOGI("[remote start] Notification from %{public}s", Utility::Anonymize(notice.networkId).c_str());
600     if (parent_.process_.IsPeer(notice.networkId)) {
601         auto ret = context.Sender().Send(event);
602         if (ret != Channel<CooperateEvent>::NO_ERROR) {
603             FI_HILOGE("Failed to send with options event via channel, error:%{public}d", ret);
604         }
605         OnReset(context, event);
606         return;
607     }
608     parent_.env_->GetTimerManager().AddTimer(DEFAULT_COOLING_TIME, REPEAT_ONCE,
609         [sender = context.Sender(), event]() mutable {
610             auto ret = sender.Send(event);
611             if (ret != Channel<CooperateEvent>::NO_ERROR) {
612                 FI_HILOGE("Failed to send with options event via channel, error:%{public}d", ret);
613             }
614         });
615 }
616 
OnRemoteStop(Context & context,const CooperateEvent & event)617 void CooperateIn::RelayConfirmation::OnRemoteStop(Context &context, const CooperateEvent &event)
618 {
619     DSoftbusStopCooperate notice = std::get<DSoftbusStopCooperate>(event.event);
620 
621     if (!context.IsPeer(notice.networkId)) {
622         return;
623     }
624     FI_HILOGI("[remote stop] Notification from %{public}s", Utility::Anonymize(notice.networkId).c_str());
625     auto ret = context.Sender().Send(event);
626     if (ret != Channel<CooperateEvent>::NO_ERROR) {
627         FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
628     }
629     OnReset(context, event);
630 }
631 
OnAppClosed(Context & context,const CooperateEvent & event)632 void CooperateIn::RelayConfirmation::OnAppClosed(Context &context, const CooperateEvent &event)
633 {
634     FI_HILOGI("[app closed] Close all connections");
635     context.dsoftbus_.CloseAllSessions();
636     FI_HILOGI("[relay cooperate] Stop cooperation on app closed");
637     parent_.StopCooperate(context, event);
638     OnResetWithNotifyMessage(context, event);
639 }
640 
OnPointerEvent(Context & context,const CooperateEvent & event)641 void CooperateIn::RelayConfirmation::OnPointerEvent(Context &context, const CooperateEvent &event)
642 {
643     InputPointerEvent notice = std::get<InputPointerEvent>(event.event);
644 
645     if ((notice.sourceType != MMI::PointerEvent::SOURCE_TYPE_MOUSE) ||
646         !InputEventBuilder::IsLocalEvent(notice)) {
647         return;
648     }
649     FI_HILOGI("[relay cooperate] Stop cooperation on operation of local pointer");
650     context.OnPointerEvent(notice);
651     parent_.StopCooperate(context, event);
652     OnReset(context, event);
653 }
654 
OnBoardOffline(Context & context,const CooperateEvent & event)655 void CooperateIn::RelayConfirmation::OnBoardOffline(Context &context, const CooperateEvent &event)
656 {
657     DDMBoardOfflineEvent notice = std::get<DDMBoardOfflineEvent>(event.event);
658 
659     if (!context.IsPeer(notice.networkId) && !parent_.process_.IsPeer(notice.networkId)) {
660         return;
661     }
662     FI_HILOGI("[relay cooperate] Peer(%{public}s) is offline", Utility::Anonymize(notice.networkId).c_str());
663     if (context.IsPeer(notice.networkId)) {
664         parent_.StopCooperate(context, event);
665     }
666     OnResetWithNotifyMessage(context, event);
667 }
668 
OnSwitchChanged(Context & context,const CooperateEvent & event)669 void CooperateIn::RelayConfirmation::OnSwitchChanged(Context &context, const CooperateEvent &event)
670 {
671     DDPCooperateSwitchChanged notice = std::get<DDPCooperateSwitchChanged>(event.event);
672 
673     if (notice.normal ||
674         (!context.IsPeer(notice.networkId) &&
675          !parent_.process_.IsPeer(notice.networkId))) {
676         return;
677     }
678     FI_HILOGI("[relay cooperate] Peer(\'%{public}s\') switch off", Utility::Anonymize(notice.networkId).c_str());
679     if (context.IsPeer(notice.networkId)) {
680         parent_.StopCooperate(context, event);
681     }
682     OnResetWithNotifyMessage(context, event);
683 }
684 
OnSoftbusSessionClosed(Context & context,const CooperateEvent & event)685 void CooperateIn::RelayConfirmation::OnSoftbusSessionClosed(Context &context, const CooperateEvent &event)
686 {
687     DSoftbusSessionClosed notice = std::get<DSoftbusSessionClosed>(event.event);
688 
689     if (!context.IsPeer(notice.networkId) && !parent_.process_.IsPeer(notice.networkId)) {
690         return;
691     }
692     FI_HILOGI("[relay cooperate] Disconnected with \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
693     if (context.IsPeer(notice.networkId)) {
694         parent_.StopCooperate(context, event);
695     }
696     OnResetWithNotifyMessage(context, event);
697 }
698 
OnResponse(Context & context,const CooperateEvent & event)699 void CooperateIn::RelayConfirmation::OnResponse(Context &context, const CooperateEvent &event)
700 {
701     DSoftbusRelayCooperateFinished notice = std::get<DSoftbusRelayCooperateFinished>(event.event);
702 
703     if (!context.IsPeer(notice.networkId)) {
704         return;
705     }
706     FI_HILOGI("[relay cooperate] \'%{public}s\' respond", Utility::Anonymize(notice.networkId).c_str());
707     parent_.env_->GetTimerManager().RemoveTimer(timerId_);
708     if (notice.normal) {
709         OnNormal(context, event);
710         Proceed(context, event);
711     } else {
712         OnResetWithNotifyMessage(context, event);
713         parent_.StopCooperate(context, event);
714     }
715 }
716 
OnResponseWithOptions(Context & context,const CooperateEvent & event)717 void CooperateIn::RelayConfirmation::OnResponseWithOptions(Context &context, const CooperateEvent &event)
718 {
719     DSoftbusRelayCooperateFinished notice = std::get<DSoftbusRelayCooperateFinished>(event.event);
720     if (!context.IsPeer(notice.networkId)) {
721         return;
722     }
723     FI_HILOGI("[relay cooperate] \'%{public}s\' respond", Utility::Anonymize(notice.networkId).c_str());
724     parent_.env_->GetTimerManager().RemoveTimer(timerId_);
725     if (notice.normal) {
726         OnNormalWithOptions(context, event);
727         Proceed(context, event);
728     } else {
729         OnResetWithOptionsNotifyMessage(context, event);
730         parent_.StopCooperate(context, event);
731     }
732 }
733 
OnNormal(Context & context,const CooperateEvent & event)734 void CooperateIn::RelayConfirmation::OnNormal(Context &context, const CooperateEvent &event)
735 {
736     FI_HILOGI("[relay cooperate] Cooperation with \'%{public}s\' established",
737         Utility::Anonymize(parent_.process_.Peer()).c_str());
738     context.inputEventBuilder_.Disable();
739     DSoftbusRelayCooperateFinished noticeFinished = std::get<DSoftbusRelayCooperateFinished>(event.event);
740     DSoftbusStartCooperate notice {
741         .originNetworkId = context.Peer(),
742         .success = true,
743         .cursorPos = context.NormalizedCursorPosition(),
744         .uid = noticeFinished.uid,
745     };
746     context.OnStartCooperate(notice.extra);
747     context.dsoftbus_.StartCooperate(parent_.process_.Peer(), notice);
748 
749     context.eventMgr_.StartCooperateFinish(notice);
750     TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
751     context.OnRelayCooperation(parent_.process_.Peer(), context.NormalizedCursorPosition());
752 }
753 
OnNormalWithOptions(Context & context,const CooperateEvent & event)754 void CooperateIn::RelayConfirmation::OnNormalWithOptions(Context &context, const CooperateEvent &event)
755 {
756     FI_HILOGI("[relay cooperate] Cooperation with \'%{public}s\' established",
757         Utility::Anonymize(parent_.process_.Peer()).c_str());
758     context.inputEventBuilder_.Disable();
759 
760     DSoftbusCooperateOptions notice {
761         .originNetworkId = context.Peer(),
762         .success = true,
763         .cooperateOptions = {startWithOptionsEvent_.displayX, startWithOptionsEvent_.displayY,
764             startWithOptionsEvent_.displayId},
765     };
766     context.OnStartCooperate(notice.extra);
767     context.dsoftbus_.StartCooperateWithOptions(parent_.process_.Peer(), notice);
768 
769     context.eventMgr_.StartCooperateWithOptionsFinish(notice);
770     TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
771     context.OnRelayCooperation(parent_.process_.Peer(), context.NormalizedCursorPosition());
772 }
773 
OnProgress(Context & context,const CooperateEvent & event)774 void CooperateIn::RelayConfirmation::OnProgress(Context &context, const CooperateEvent &event)
775 {
776     std::string remoteNetworkId = parent_.process_.Peer();
777     FI_HILOGI("[relay cooperate] Connect \'%{public}s\'", Utility::Anonymize(remoteNetworkId).c_str());
778     int32_t ret = context.dsoftbus_.OpenSession(remoteNetworkId);
779     if (ret != RET_OK) {
780         FI_HILOGE("[relay cooperate] Failed to connect to \'%{public}s\'", Utility::Anonymize(remoteNetworkId).c_str());
781         OnResetWithNotifyMessage(context, event);
782         return;
783     }
784     StartCooperateEvent startEvent = std::get<StartCooperateEvent>(event.event);
785     FI_HILOGI("[relay cooperate] Notify origin(\'%{public}s\')", Utility::Anonymize(context.Peer()).c_str());
786     DSoftbusRelayCooperate notice {
787         .targetNetworkId = parent_.process_.Peer(),
788         .pointerSpeed = context.GetPointerSpeed(),
789         .touchPadSpeed = context.GetTouchPadSpeed(),
790         .uid = startEvent.uid,
791     };
792     context.dsoftbus_.RelayCooperate(context.Peer(), notice);
793     timerId_ = parent_.env_->GetTimerManager().AddTimer(DEFAULT_TIMEOUT, REPEAT_ONCE,
794         [sender = context.Sender(), remoteNetworkId = context.Peer()]() mutable {
795             auto ret = sender.Send(CooperateEvent(
796                 CooperateEventType::DSOFTBUS_RELAY_COOPERATE_FINISHED,
797                 DSoftbusRelayCooperateFinished {
798                     .networkId = remoteNetworkId,
799                     .normal = false,
800                 }));
801             if (ret != Channel<CooperateEvent>::NO_ERROR) {
802                 FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
803             }
804         });
805 }
806 
OnProgressWithOptions(Context & context,const CooperateEvent & event)807 void CooperateIn::RelayConfirmation::OnProgressWithOptions(Context &context, const CooperateEvent &event)
808 {
809     std::string remoteNetworkId = parent_.process_.Peer();
810     FI_HILOGI("[relay cooperate] Connect \'%{public}s\'", Utility::Anonymize(remoteNetworkId).c_str());
811     int32_t ret = context.dsoftbus_.OpenSession(remoteNetworkId);
812     if (ret != RET_OK) {
813         FI_HILOGE("[relay cooperate] Failed to connect to \'%{public}s\'", Utility::Anonymize(remoteNetworkId).c_str());
814         OnResetWithOptionsNotifyMessage(context, event);
815         return;
816     }
817 
818     FI_HILOGI("[relay cooperate] Notify origin(\'%{public}s\')", Utility::Anonymize(context.Peer()).c_str());
819     DSoftbusRelayCooperate notice {
820         .targetNetworkId = parent_.process_.Peer(),
821         .pointerSpeed = context.GetPointerSpeed(),
822         .touchPadSpeed = context.GetTouchPadSpeed(),
823     };
824     context.dsoftbus_.RelayCooperateWithOptions(context.Peer(), notice);
825     startWithOptionsEvent_ = std::get<StartWithOptionsEvent>(event.event);
826     timerId_ = parent_.env_->GetTimerManager().AddTimer(DEFAULT_TIMEOUT, REPEAT_ONCE,
827         [sender = context.Sender(), remoteNetworkId = context.Peer()]() mutable {
828             auto ret = sender.Send(CooperateEvent(
829                 CooperateEventType::DSOFTBUS_RELAY_COOPERATE_WITHOPTIONS_FINISHED,
830                 DSoftbusRelayCooperateFinished {
831                     .networkId = remoteNetworkId,
832                     .normal = false,
833                 }));
834             if (ret != Channel<CooperateEvent>::NO_ERROR) {
835                 FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
836             }
837         });
838 }
839 
OnReset(Context & context,const CooperateEvent & event)840 void CooperateIn::RelayConfirmation::OnReset(Context &context, const CooperateEvent &event)
841 {
842     FI_HILOGI("[relay cooperate] reset cooperation with \'%{public}s\'",
843         Utility::Anonymize(parent_.process_.Peer()).c_str());
844     Reset(context, event);
845 }
846 
OnResetWithNotifyMessage(Context & context,const CooperateEvent & event)847 void CooperateIn::RelayConfirmation::OnResetWithNotifyMessage(Context &context, const CooperateEvent &event)
848 {
849     FI_HILOGI("[relay cooperate] reset cooperation with \'%{public}s\'",
850         Utility::Anonymize(parent_.process_.Peer()).c_str());
851     DSoftbusStartCooperateFinished result {
852         .success = false
853     };
854     context.eventMgr_.StartCooperateFinish(result);
855     Reset(context, event);
856 }
857 
OnResetWithOptionsNotifyMessage(Context & context,const CooperateEvent & event)858 void CooperateIn::RelayConfirmation::OnResetWithOptionsNotifyMessage(Context &context, const CooperateEvent &event)
859 {
860     FI_HILOGI("[relay cooperate] reset cooperation with \'%{public}s\'",
861         Utility::Anonymize(parent_.process_.Peer()).c_str());
862     DSoftbusCooperateWithOptionsFinished result {
863         .success = false
864     };
865     context.eventMgr_.StartCooperateWithOptionsFinish(result);
866     Reset(context, event);
867 }
868 
StopCooperate(Context & context,const CooperateEvent & event)869 void CooperateIn::StopCooperate(Context &context, const CooperateEvent &event)
870 {
871     FI_HILOGI("Stop cooperation with \'%{public}s\'", Utility::Anonymize(context.Peer()).c_str());
872     context.inputEventBuilder_.Disable();
873     context.UpdateCursorPosition();
874 
875     DSoftbusStopCooperate notice {};
876     context.dsoftbus_.StopCooperate(context.Peer(), notice);
877     TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
878     context.OnResetCooperation();
879     SetPointerVisible(context);
880 }
881 
SetPointerVisible(Context & context)882 void CooperateIn::SetPointerVisible(Context &context)
883 {
884     CHKPV(env_);
885     bool hasLocalPointerDevice =  env_->GetDeviceManager().HasLocalPointerDevice() ||
886         env_->GetInput().HasLocalPointerDevice() ||
887         env_->GetDeviceManager().HasPencilAirMouse();
888     FI_HILOGI("HasLocalPointerDevice:%{public}s", hasLocalPointerDevice ? "true" : "false");
889     env_->GetInput().SetPointerVisibility(hasLocalPointerDevice, PRIORITY);
890 }
891 
UnchainConnections(Context & context,const StopCooperateEvent & event) const892 void CooperateIn::UnchainConnections(Context &context, const StopCooperateEvent &event) const
893 {
894     if (event.isUnchained) {
895         FI_HILOGI("Unchain all connections");
896         context.dsoftbus_.CloseAllSessions();
897         context.eventMgr_.OnUnchain(event);
898     }
899 }
900 } // namespace Cooperate
901 } // namespace DeviceStatus
902 } // namespace Msdp
903 } // namespace OHOS
904