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