1 /*
2  * Copyright (c) 2023-2024 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 
18 #include "devicestatus_define.h"
19 #include "utility.h"
20 
21 #undef LOG_TAG
22 #define LOG_TAG "CooperateIn"
23 
24 namespace OHOS {
25 namespace Msdp {
26 namespace DeviceStatus {
27 namespace Cooperate {
28 
CooperateIn(IStateMachine & parent,IContext * env)29 CooperateIn::CooperateIn(IStateMachine &parent, IContext *env)
30     : ICooperateState(parent), env_(env)
31 {
32     initial_ = std::make_shared<Initial>(*this);
33     Initial::BuildChains(initial_, *this);
34     current_ = initial_;
35 }
36 
~CooperateIn()37 CooperateIn::~CooperateIn()
38 {
39     Initial::RemoveChains(initial_);
40 }
41 
OnEvent(Context & context,const CooperateEvent & event)42 void CooperateIn::OnEvent(Context &context, const CooperateEvent &event)
43 {
44     current_->OnEvent(context, event);
45 }
46 
OnEnterState(Context & context)47 void CooperateIn::OnEnterState(Context &context)
48 {
49     CALL_INFO_TRACE;
50     env_->GetInput().SetPointerVisibility(!context.NeedHideCursor());
51 }
52 
OnLeaveState(Context & context)53 void CooperateIn::OnLeaveState(Context & context)
54 {
55     CALL_INFO_TRACE;
56     UpdateCooperateFlagEvent event {
57         .mask = COOPERATE_FLAG_HIDE_CURSOR,
58         .flag = COOPERATE_FLAG_HIDE_CURSOR,
59     };
60     context.UpdateCooperateFlag(event);
61     CHKPV(env_);
62     env_->GetInput().SetPointerVisibility(false);
63 }
64 
65 std::set<int32_t> CooperateIn::Initial::filterPointerActions_ {
66     MMI::PointerEvent::POINTER_ACTION_ENTER_WINDOW,
67     MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW,
68     MMI::PointerEvent::POINTER_ACTION_PULL_IN_WINDOW,
69     MMI::PointerEvent::POINTER_ACTION_PULL_OUT_WINDOW,
70 };
71 
BuildChains(std::shared_ptr<Initial> self,CooperateIn & parent)72 void CooperateIn::Initial::BuildChains(std::shared_ptr<Initial> self, CooperateIn &parent)
73 {
74     auto s11 = std::make_shared<RelayConfirmation>(parent, self);
75     self->relay_ = s11;
76     s11->SetNext(self);
77 }
78 
RemoveChains(std::shared_ptr<Initial> self)79 void CooperateIn::Initial::RemoveChains(std::shared_ptr<Initial> self)
80 {
81     if (self->relay_ != nullptr) {
82         self->relay_->SetNext(nullptr);
83         self->relay_ = nullptr;
84     }
85 }
86 
Initial(CooperateIn & parent)87 CooperateIn::Initial::Initial(CooperateIn &parent)
88     : ICooperateStep(parent, nullptr), parent_(parent)
89 {
90     AddHandler(CooperateEventType::DISABLE, [this](Context &context, const CooperateEvent &event) {
91         this->OnDisable(context, event);
92     });
93     AddHandler(CooperateEventType::START, [this](Context &context, const CooperateEvent &event) {
94         this->OnStart(context, event);
95     });
96     AddHandler(CooperateEventType::STOP, [this](Context &context, const CooperateEvent &event) {
97         this->OnStop(context, event);
98     });
99     AddHandler(CooperateEventType::APP_CLOSED, [this](Context &context, const CooperateEvent &event) {
100         this->OnAppClosed(context, event);
101     });
102     AddHandler(CooperateEventType::INPUT_POINTER_EVENT, [this](Context &context, const CooperateEvent &event) {
103         this->OnPointerEvent(context, event);
104     });
105     AddHandler(CooperateEventType::DDM_BOARD_OFFLINE, [this](Context &context, const CooperateEvent &event) {
106         this->OnBoardOffline(context, event);
107     });
108     AddHandler(CooperateEventType::DDP_COOPERATE_SWITCH_CHANGED,
109         [this](Context &context, const CooperateEvent &event) {
110             this->OnSwitchChanged(context, event);
111     });
112     AddHandler(CooperateEventType::DSOFTBUS_SESSION_CLOSED,
113         [this](Context &context, const CooperateEvent &event) {
114             this->OnSoftbusSessionClosed(context, event);
115     });
116     AddHandler(CooperateEventType::DSOFTBUS_START_COOPERATE,
117         [this](Context &context, const CooperateEvent &event) {
118             this->OnRemoteStart(context, event);
119     });
120     AddHandler(CooperateEventType::DSOFTBUS_STOP_COOPERATE,
121         [this](Context &context, const CooperateEvent &event) {
122             this->OnRemoteStop(context, event);
123     });
124     AddHandler(CooperateEventType::UPDATE_COOPERATE_FLAG,
125         [this](Context &context, const CooperateEvent &event) {
126             this->OnUpdateCooperateFlag(context, event);
127     });
128     AddHandler(CooperateEventType::DSOFTBUS_INPUT_DEV_SYNC,
129         [this](Context &context, const CooperateEvent &event) {
130             this->OnRemoteInputDevice(context, event);
131     });
132 }
133 
OnDisable(Context & context,const CooperateEvent & event)134 void CooperateIn::Initial::OnDisable(Context &context, const CooperateEvent &event)
135 {
136     FI_HILOGI("[disable cooperation] Stop cooperation");
137     parent_.StopCooperate(context, event);
138 }
139 
OnStart(Context & context,const CooperateEvent & event)140 void CooperateIn::Initial::OnStart(Context &context, const CooperateEvent &event)
141 {
142     CALL_INFO_TRACE;
143     StartCooperateEvent startEvent = std::get<StartCooperateEvent>(event.event);
144 
145     if (context.IsLocal(startEvent.remoteNetworkId)) {
146         DSoftbusStartCooperateFinished result {
147             .success = false,
148             .errCode = static_cast<int32_t>(CoordinationErrCode::UNEXPECTED_START_CALL)
149         };
150         context.eventMgr_.StartCooperateFinish(result);
151         return;
152     }
153     FI_HILOGI("[start] start cooperation(%{public}s, %{public}d)",
154         Utility::Anonymize(startEvent.remoteNetworkId).c_str(), startEvent.startDeviceId);
155     context.eventMgr_.StartCooperate(startEvent);
156 
157     if (context.IsPeer(startEvent.remoteNetworkId)) {
158         OnComeBack(context, event);
159     } else {
160         OnRelay(context, event);
161     }
162 }
163 
OnComeBack(Context & context,const CooperateEvent & event)164 void CooperateIn::Initial::OnComeBack(Context &context, const CooperateEvent &event)
165 {
166     CALL_INFO_TRACE;
167     context.inputEventBuilder_.Disable();
168     FI_HILOGI("[come back] To \'%{public}s\'", Utility::Anonymize(context.Peer()).c_str());
169     DSoftbusComeBack notice {
170         .originNetworkId = context.Local(),
171         .success = true,
172         .cursorPos = context.NormalizedCursorPosition(),
173     };
174     context.OnStartCooperate(notice.extra);
175     if (context.dsoftbus_.ComeBack(context.Peer(), notice) != RET_OK) {
176         notice.success = false;
177         notice.errCode = static_cast<int32_t>(CoordinationErrCode::SEND_PACKET_FAILED);
178     }
179     context.eventMgr_.StartCooperateFinish(notice);
180     context.inputDevMgr_.RemoveVirtualInputDevice(context.Peer());
181     TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
182     context.OnBack();
183 }
184 
OnRelay(Context & context,const CooperateEvent & event)185 void CooperateIn::Initial::OnRelay(Context &context, const CooperateEvent &event)
186 {
187     CALL_INFO_TRACE;
188     StartCooperateEvent startEvent = std::get<StartCooperateEvent>(event.event);
189     parent_.process_.StartCooperate(context, startEvent);
190     FI_HILOGI("[relay cooperate] To \'%{public}s\'", Utility::Anonymize(parent_.process_.Peer()).c_str());
191 
192     if (relay_ != nullptr) {
193         Switch(relay_);
194         relay_->OnProgress(context, event);
195     }
196 }
197 
OnStop(Context & context,const CooperateEvent & event)198 void CooperateIn::Initial::OnStop(Context &context, const CooperateEvent &event)
199 {
200     CALL_INFO_TRACE;
201     StopCooperateEvent param = std::get<StopCooperateEvent>(event.event);
202 
203     context.eventMgr_.StopCooperate(param);
204     parent_.StopCooperate(context, event);
205 
206     param.networkId = context.Peer();
207     DSoftbusStopCooperateFinished notice {
208         .networkId = context.Peer(),
209         .normal = true,
210     };
211     context.eventMgr_.StopCooperateFinish(notice);
212 
213     parent_.UnchainConnections(context, param);
214 }
215 
OnRemoteStart(Context & context,const CooperateEvent & event)216 void CooperateIn::Initial::OnRemoteStart(Context &context, const CooperateEvent &event)
217 {
218     CALL_INFO_TRACE;
219     DSoftbusStartCooperate notice = std::get<DSoftbusStartCooperate>(event.event);
220 
221     if (context.IsPeer(notice.networkId) || context.IsLocal(notice.networkId)) {
222         return;
223     }
224     context.OnRemoteStartCooperate(notice.extra);
225     context.eventMgr_.RemoteStart(notice);
226 
227     DSoftbusStopCooperate stopNotice {};
228     context.dsoftbus_.StopCooperate(context.Peer(), stopNotice);
229 
230     context.RemoteStartSuccess(notice);
231     context.inputEventBuilder_.Update(context);
232     context.eventMgr_.RemoteStartFinish(notice);
233     FI_HILOGI("[remote start] Cooperation with \'%{public}s\' established", Utility::Anonymize(context.Peer()).c_str());
234     context.OnTransitionIn();
235 }
236 
OnRemoteStop(Context & context,const CooperateEvent & event)237 void CooperateIn::Initial::OnRemoteStop(Context &context, const CooperateEvent &event)
238 {
239     DSoftbusStopCooperate notice = std::get<DSoftbusStopCooperate>(event.event);
240 
241     if (!context.IsPeer(notice.networkId)) {
242         return;
243     }
244     FI_HILOGI("[remote stop] Notification from \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
245     context.eventMgr_.RemoteStop(notice);
246     context.inputEventBuilder_.Disable();
247     context.eventMgr_.RemoteStopFinish(notice);
248     context.inputDevMgr_.RemoveVirtualInputDevice(context.Peer());
249     TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
250     context.OnResetCooperation();
251 }
252 
OnAppClosed(Context & context,const CooperateEvent & event)253 void CooperateIn::Initial::OnAppClosed(Context &context, const CooperateEvent &event)
254 {
255     FI_HILOGI("[app closed] Close all connections");
256     context.dsoftbus_.CloseAllSessions();
257     FI_HILOGI("[app closed] Stop cooperation");
258     parent_.StopCooperate(context, event);
259 }
260 
OnPointerEvent(Context & context,const CooperateEvent & event)261 void CooperateIn::Initial::OnPointerEvent(Context &context, const CooperateEvent &event)
262 {
263     InputPointerEvent notice = std::get<InputPointerEvent>(event.event);
264 
265     if ((notice.sourceType != MMI::PointerEvent::SOURCE_TYPE_MOUSE) ||
266         (filterPointerActions_.find(notice.pointerAction) != filterPointerActions_.end()) ||
267         !InputEventBuilder::IsLocalEvent(notice)) {
268         return;
269     }
270     FI_HILOGI("Stop cooperation on operation of local pointer");
271     context.OnPointerEvent(notice);
272     parent_.StopCooperate(context, event);
273 }
274 
OnBoardOffline(Context & context,const CooperateEvent & event)275 void CooperateIn::Initial::OnBoardOffline(Context &context, const CooperateEvent &event)
276 {
277     DDMBoardOfflineEvent notice = std::get<DDMBoardOfflineEvent>(event.event);
278 
279     if (!context.IsPeer(notice.networkId)) {
280         return;
281     }
282     FI_HILOGI("[board offline] Peer(\'%{public}s\') is offline", Utility::Anonymize(notice.networkId).c_str());
283     parent_.StopCooperate(context, event);
284 }
285 
OnSwitchChanged(Context & context,const CooperateEvent & event)286 void CooperateIn::Initial::OnSwitchChanged(Context &context, const CooperateEvent &event)
287 {
288     DDPCooperateSwitchChanged notice = std::get<DDPCooperateSwitchChanged>(event.event);
289 
290     if (!context.IsPeer(notice.networkId) || notice.normal) {
291         return;
292     }
293     FI_HILOGI("[switch off] Peer(\'%{public}s\') switch off", Utility::Anonymize(notice.networkId).c_str());
294     parent_.StopCooperate(context, event);
295 }
296 
OnSoftbusSessionClosed(Context & context,const CooperateEvent & event)297 void CooperateIn::Initial::OnSoftbusSessionClosed(Context &context, const CooperateEvent &event)
298 {
299     DSoftbusSessionClosed notice = std::get<DSoftbusSessionClosed>(event.event);
300 
301     if (!context.IsPeer(notice.networkId)) {
302         return;
303     }
304     FI_HILOGI("[softbus session closed] Disconnected with \'%{public}s\'",
305         Utility::Anonymize(notice.networkId).c_str());
306     parent_.StopCooperate(context, event);
307     context.eventMgr_.OnSoftbusSessionClosed(notice);
308 }
309 
OnRemoteInputDevice(Context & context,const CooperateEvent & event)310 void CooperateIn::Initial::OnRemoteInputDevice(Context &context, const CooperateEvent &event)
311 {
312     CALL_INFO_TRACE;
313     DSoftbusSyncInputDevice notice = std::get<DSoftbusSyncInputDevice>(event.event);
314     if (!context.IsPeer(notice.networkId)) {
315         return;
316     }
317     FI_HILOGI("Remote input device from \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
318     context.inputDevMgr_.AddVirtualInputDevice(notice.networkId);
319 }
320 
OnRemoteHotPlug(Context & context,const CooperateEvent & event)321 void CooperateIn::Initial::OnRemoteHotPlug(Context &context, const CooperateEvent &event)
322 {
323     DSoftbusHotPlugEvent notice = std::get<DSoftbusHotPlugEvent>(event.event);
324     if (!context.IsPeer(notice.networkId)) {
325         return;
326     }
327     FI_HILOGI("Remote hot plug event from \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
328 }
329 
OnUpdateCooperateFlag(Context & context,const CooperateEvent & event)330 void CooperateIn::Initial::OnUpdateCooperateFlag(Context &context, const CooperateEvent &event)
331 {
332     UpdateCooperateFlagEvent notice = std::get<UpdateCooperateFlagEvent>(event.event);
333     uint32_t changed = (notice.mask & (context.CooperateFlag() ^ notice.flag));
334     context.UpdateCooperateFlag(notice);
335 
336     if (changed & COOPERATE_FLAG_FREEZE_CURSOR) {
337         FI_HILOGI("Toggle freezing state of cursor");
338         if (notice.flag & COOPERATE_FLAG_FREEZE_CURSOR) {
339             context.inputEventBuilder_.Freeze();
340         } else {
341             context.inputEventBuilder_.Thaw();
342         }
343     }
344 }
345 
OnProgress(Context & context,const CooperateEvent & event)346 void CooperateIn::Initial::OnProgress(Context &context, const CooperateEvent &event)
347 {}
348 
OnReset(Context & context,const CooperateEvent & event)349 void CooperateIn::Initial::OnReset(Context &context, const CooperateEvent &event)
350 {}
351 
RelayConfirmation(CooperateIn & parent,std::shared_ptr<ICooperateStep> prev)352 CooperateIn::RelayConfirmation::RelayConfirmation(CooperateIn &parent, std::shared_ptr<ICooperateStep> prev)
353     : ICooperateStep(parent, prev), parent_(parent)
354 {
355     AddHandler(CooperateEventType::DISABLE, [this](Context &context, const CooperateEvent &event) {
356         this->OnDisable(context, event);
357     });
358     AddHandler(CooperateEventType::STOP, [this](Context &context, const CooperateEvent &event) {
359         this->OnStop(context, event);
360     });
361     AddHandler(CooperateEventType::APP_CLOSED, [this](Context &context, const CooperateEvent &event) {
362         this->OnAppClosed(context, event);
363     });
364     AddHandler(CooperateEventType::INPUT_POINTER_EVENT,
365         [this](Context &context, const CooperateEvent &event) {
366             this->OnPointerEvent(context, event);
367     });
368     AddHandler(CooperateEventType::DDM_BOARD_OFFLINE,
369         [this](Context &context, const CooperateEvent &event) {
370             this->OnBoardOffline(context, event);
371     });
372     AddHandler(CooperateEventType::DDP_COOPERATE_SWITCH_CHANGED,
373         [this](Context &context, const CooperateEvent &event) {
374             this->OnSwitchChanged(context, event);
375     });
376     AddHandler(CooperateEventType::DSOFTBUS_SESSION_CLOSED,
377         [this](Context &context, const CooperateEvent &event) {
378             this->OnSoftbusSessionClosed(context, event);
379     });
380     AddHandler(CooperateEventType::DSOFTBUS_RELAY_COOPERATE_FINISHED,
381         [this](Context &context, const CooperateEvent &event) {
382             this->OnResponse(context, event);
383     });
384     AddHandler(CooperateEventType::DSOFTBUS_START_COOPERATE,
385         [this](Context &context, const CooperateEvent &event) {
386             this->OnRemoteStart(context, event);
387     });
388     AddHandler(CooperateEventType::DSOFTBUS_STOP_COOPERATE,
389         [this](Context &context, const CooperateEvent &event) {
390             this->OnRemoteStop(context, event);
391     });
392 }
393 
OnDisable(Context & context,const CooperateEvent & event)394 void CooperateIn::RelayConfirmation::OnDisable(Context &context, const CooperateEvent &event)
395 {
396     FI_HILOGI("[relay cooperate] Disable cooperation");
397     parent_.StopCooperate(context, event);
398     OnReset(context, event);
399 }
400 
OnStop(Context & context,const CooperateEvent & event)401 void CooperateIn::RelayConfirmation::OnStop(Context &context, const CooperateEvent &event)
402 {
403     FI_HILOGI("[relay cooperate] Stop cooperation");
404     parent_.StopCooperate(context, event);
405     OnReset(context, event);
406 
407     StopCooperateEvent param = std::get<StopCooperateEvent>(event.event);
408     parent_.UnchainConnections(context, param);
409 }
410 
OnRemoteStart(Context & context,const CooperateEvent & event)411 void CooperateIn::RelayConfirmation::OnRemoteStart(Context &context, const CooperateEvent &event)
412 {
413     CALL_INFO_TRACE;
414     DSoftbusStartCooperate notice = std::get<DSoftbusStartCooperate>(event.event);
415 
416     if (context.IsPeer(notice.networkId) || context.IsLocal(notice.networkId)) {
417         return;
418     }
419     FI_HILOGI("[remote start] Notification from %{public}s", Utility::Anonymize(notice.networkId).c_str());
420     if (parent_.process_.IsPeer(notice.networkId)) {
421         auto ret = context.Sender().Send(event);
422         if (ret != Channel<CooperateEvent>::NO_ERROR) {
423             FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
424         }
425         OnReset(context, event);
426         return;
427     }
428     parent_.env_->GetTimerManager().AddTimer(DEFAULT_COOLING_TIME, REPEAT_ONCE,
429         [sender = context.Sender(), event]() mutable {
430             auto ret = sender.Send(event);
431             if (ret != Channel<CooperateEvent>::NO_ERROR) {
432                 FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
433             }
434         });
435 }
436 
OnRemoteStop(Context & context,const CooperateEvent & event)437 void CooperateIn::RelayConfirmation::OnRemoteStop(Context &context, const CooperateEvent &event)
438 {
439     DSoftbusStopCooperate notice = std::get<DSoftbusStopCooperate>(event.event);
440 
441     if (!context.IsPeer(notice.networkId)) {
442         return;
443     }
444     FI_HILOGI("[remote stop] Notification from %{public}s", Utility::Anonymize(notice.networkId).c_str());
445     auto ret = context.Sender().Send(event);
446     if (ret != Channel<CooperateEvent>::NO_ERROR) {
447         FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
448     }
449     OnReset(context, event);
450 }
451 
OnAppClosed(Context & context,const CooperateEvent & event)452 void CooperateIn::RelayConfirmation::OnAppClosed(Context &context, const CooperateEvent &event)
453 {
454     FI_HILOGI("[app closed] Close all connections");
455     context.dsoftbus_.CloseAllSessions();
456     FI_HILOGI("[relay cooperate] Stop cooperation on app closed");
457     parent_.StopCooperate(context, event);
458     OnReset(context, event);
459 }
460 
OnPointerEvent(Context & context,const CooperateEvent & event)461 void CooperateIn::RelayConfirmation::OnPointerEvent(Context &context, const CooperateEvent &event)
462 {
463     InputPointerEvent notice = std::get<InputPointerEvent>(event.event);
464 
465     if ((notice.sourceType != MMI::PointerEvent::SOURCE_TYPE_MOUSE) ||
466         !InputEventBuilder::IsLocalEvent(notice)) {
467         return;
468     }
469     FI_HILOGI("[relay cooperate] Stop cooperation on operation of local pointer");
470     context.OnPointerEvent(notice);
471     parent_.StopCooperate(context, event);
472     OnReset(context, event);
473 }
474 
OnBoardOffline(Context & context,const CooperateEvent & event)475 void CooperateIn::RelayConfirmation::OnBoardOffline(Context &context, const CooperateEvent &event)
476 {
477     DDMBoardOfflineEvent notice = std::get<DDMBoardOfflineEvent>(event.event);
478 
479     if (!context.IsPeer(notice.networkId) && !parent_.process_.IsPeer(notice.networkId)) {
480         return;
481     }
482     FI_HILOGI("[relay cooperate] Peer(%{public}s) is offline", Utility::Anonymize(notice.networkId).c_str());
483     if (context.IsPeer(notice.networkId)) {
484         parent_.StopCooperate(context, event);
485     }
486     OnReset(context, event);
487 }
488 
OnSwitchChanged(Context & context,const CooperateEvent & event)489 void CooperateIn::RelayConfirmation::OnSwitchChanged(Context &context, const CooperateEvent &event)
490 {
491     DDPCooperateSwitchChanged notice = std::get<DDPCooperateSwitchChanged>(event.event);
492 
493     if (notice.normal ||
494         (!context.IsPeer(notice.networkId) &&
495          !parent_.process_.IsPeer(notice.networkId))) {
496         return;
497     }
498     FI_HILOGI("[relay cooperate] Peer(\'%{public}s\') switch off", Utility::Anonymize(notice.networkId).c_str());
499     if (context.IsPeer(notice.networkId)) {
500         parent_.StopCooperate(context, event);
501     }
502     OnReset(context, event);
503 }
504 
OnSoftbusSessionClosed(Context & context,const CooperateEvent & event)505 void CooperateIn::RelayConfirmation::OnSoftbusSessionClosed(Context &context, const CooperateEvent &event)
506 {
507     DSoftbusSessionClosed notice = std::get<DSoftbusSessionClosed>(event.event);
508 
509     if (!context.IsPeer(notice.networkId) && !parent_.process_.IsPeer(notice.networkId)) {
510         return;
511     }
512     FI_HILOGI("[relay cooperate] Disconnected with \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
513     if (context.IsPeer(notice.networkId)) {
514         parent_.StopCooperate(context, event);
515     }
516     OnReset(context, event);
517 }
518 
OnResponse(Context & context,const CooperateEvent & event)519 void CooperateIn::RelayConfirmation::OnResponse(Context &context, const CooperateEvent &event)
520 {
521     DSoftbusRelayCooperateFinished notice = std::get<DSoftbusRelayCooperateFinished>(event.event);
522 
523     if (!context.IsPeer(notice.networkId)) {
524         return;
525     }
526     FI_HILOGI("[relay cooperate] \'%{public}s\' respond", Utility::Anonymize(notice.networkId).c_str());
527     parent_.env_->GetTimerManager().RemoveTimer(timerId_);
528     if (notice.normal) {
529         OnNormal(context, event);
530         Proceed(context, event);
531     } else {
532         OnReset(context, event);
533     }
534 }
535 
OnNormal(Context & context,const CooperateEvent & event)536 void CooperateIn::RelayConfirmation::OnNormal(Context &context, const CooperateEvent &event)
537 {
538     FI_HILOGI("[relay cooperate] Cooperation with \'%{public}s\' established",
539         Utility::Anonymize(parent_.process_.Peer()).c_str());
540     context.inputEventBuilder_.Disable();
541 
542     DSoftbusStartCooperate notice {
543         .originNetworkId = context.Peer(),
544         .success = true,
545         .cursorPos = context.NormalizedCursorPosition(),
546     };
547     context.OnStartCooperate(notice.extra);
548     context.dsoftbus_.StartCooperate(parent_.process_.Peer(), notice);
549 
550     context.eventMgr_.StartCooperateFinish(notice);
551     context.inputDevMgr_.RemoveVirtualInputDevice(context.Peer());
552     TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
553     context.OnRelayCooperation(parent_.process_.Peer(), context.NormalizedCursorPosition());
554 }
555 
OnProgress(Context & context,const CooperateEvent & event)556 void CooperateIn::RelayConfirmation::OnProgress(Context &context, const CooperateEvent &event)
557 {
558     std::string remoteNetworkId = parent_.process_.Peer();
559     FI_HILOGI("[relay cooperate] Connect \'%{public}s\'", Utility::Anonymize(remoteNetworkId).c_str());
560     int32_t ret = context.dsoftbus_.OpenSession(remoteNetworkId);
561     if (ret != RET_OK) {
562         FI_HILOGE("[relay cooperate] Failed to connect to \'%{public}s\'", Utility::Anonymize(remoteNetworkId).c_str());
563         OnReset(context, event);
564         return;
565     }
566 
567     FI_HILOGI("[relay cooperate] Notify origin(\'%{public}s\')", Utility::Anonymize(context.Peer()).c_str());
568     DSoftbusRelayCooperate notice {
569         .targetNetworkId = parent_.process_.Peer(),
570     };
571     context.dsoftbus_.RelayCooperate(context.Peer(), notice);
572 
573     timerId_ = parent_.env_->GetTimerManager().AddTimer(DEFAULT_TIMEOUT, REPEAT_ONCE,
574         [sender = context.Sender(), remoteNetworkId = context.Peer()]() mutable {
575             auto ret = sender.Send(CooperateEvent(
576                 CooperateEventType::DSOFTBUS_RELAY_COOPERATE_FINISHED,
577                 DSoftbusRelayCooperateFinished {
578                     .networkId = remoteNetworkId,
579                     .normal = false,
580                 }));
581             if (ret != Channel<CooperateEvent>::NO_ERROR) {
582                 FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
583             }
584         });
585 }
586 
OnReset(Context & context,const CooperateEvent & event)587 void CooperateIn::RelayConfirmation::OnReset(Context &context, const CooperateEvent &event)
588 {
589     FI_HILOGI("[relay cooperate] reset cooperation with \'%{public}s\'",
590         Utility::Anonymize(parent_.process_.Peer()).c_str());
591     DSoftbusStartCooperateFinished result {
592         .success = false
593     };
594     context.eventMgr_.StartCooperateFinish(result);
595     Reset(context, event);
596 }
597 
StopCooperate(Context & context,const CooperateEvent & event)598 void CooperateIn::StopCooperate(Context &context, const CooperateEvent &event)
599 {
600     FI_HILOGI("Stop cooperation with \'%{public}s\'", Utility::Anonymize(context.Peer()).c_str());
601     context.inputEventBuilder_.Disable();
602     context.UpdateCursorPosition();
603 
604     DSoftbusStopCooperate notice {};
605     context.dsoftbus_.StopCooperate(context.Peer(), notice);
606     context.inputDevMgr_.RemoveVirtualInputDevice(context.Peer());
607     TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
608     context.OnResetCooperation();
609     SetPointerVisible(context);
610 }
611 
SetPointerVisible(Context & context)612 void CooperateIn::SetPointerVisible(Context &context)
613 {
614     CHKPV(env_);
615     bool hasLocalPointerDevice =  env_->GetDeviceManager().HasLocalPointerDevice();
616     env_->GetInput().SetPointerVisibility(hasLocalPointerDevice, PRIORITY);
617 }
618 
UnchainConnections(Context & context,const StopCooperateEvent & event) const619 void CooperateIn::UnchainConnections(Context &context, const StopCooperateEvent &event) const
620 {
621     if (event.isUnchained) {
622         FI_HILOGI("Unchain all connections");
623         context.dsoftbus_.CloseAllSessions();
624         context.eventMgr_.OnUnchain(event);
625     }
626 }
627 } // namespace Cooperate
628 } // namespace DeviceStatus
629 } // namespace Msdp
630 } // namespace OHOS
631