• 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_out.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 "CooperateOut"
24 
25 namespace OHOS {
26 namespace Msdp {
27 namespace DeviceStatus {
28 namespace Cooperate {
29 
CooperateOut(IStateMachine & parent,IContext * env)30 CooperateOut::CooperateOut(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 
~CooperateOut()38 CooperateOut::~CooperateOut()
39 {
40     Initial::RemoveChains(initial_);
41 }
42 
OnEvent(Context & context,const CooperateEvent & event)43 void CooperateOut::OnEvent(Context &context, const CooperateEvent &event)
44 {
45     current_->OnEvent(context, event);
46 }
47 
OnEnterState(Context & context)48 void CooperateOut::OnEnterState(Context &context)
49 {
50     CALL_INFO_TRACE;
51     int32_t ret = env_->GetInput().SetPointerVisibility(false);
52     if (ret != RET_OK) {
53         CooperateRadarInfo radarInfo {
54             .funcName = __FUNCTION__,
55             .bizState = static_cast<int32_t> (BizState::STATE_IDLE),
56             .bizStage = static_cast<int32_t> (BizCooperateStage::STAGE_SET_CURSOR_VISIBILITY),
57             .stageRes = static_cast<int32_t> (BizCooperateStageRes::RES_FAIL),
58             .bizScene = static_cast<int32_t> (BizCooperateScene::SCENE_ACTIVE),
59             .errCode = static_cast<int32_t> (CooperateRadarErrCode::SET_CURSOR_VISIBILITY_FAILED),
60             .hostName = "",
61             .localNetId = "",
62             .peerNetId = ""
63         };
64         CooperateRadar::ReportCooperateRadarInfo(radarInfo);
65     }
66 }
67 
OnLeaveState(Context & context)68 void CooperateOut::OnLeaveState(Context &context)
69 {
70     CALL_INFO_TRACE;
71     SetPointerVisible(context);
72 }
73 
SetPointerVisible(Context & context)74 void CooperateOut::SetPointerVisible(Context &context)
75 {
76     CHKPV(env_);
77     bool hasLocalPointerDevice =  env_->GetDeviceManager().HasLocalPointerDevice() ||
78         env_->GetInput().HasLocalPointerDevice();
79     bool visible = !context.NeedHideCursor() && hasLocalPointerDevice;
80     FI_HILOGI("Set pointer visible:%{public}s, HasLocalPointerDevice:%{public}s",
81         visible ? "true" : "false", hasLocalPointerDevice ? "true" : "false");
82     env_->GetInput().SetPointerVisibility(visible, PRIORITY);
83 }
84 
SimulateShowPointerEvent()85 void CooperateOut::SimulateShowPointerEvent()
86 {
87     CALL_INFO_TRACE;
88     CHKPV(env_);
89     auto pointerEvent = OHOS::MMI::PointerEvent::Create();
90     OHOS::MMI::PointerEvent::PointerItem item;
91     item.SetPointerId(0);
92     item.SetRawDx(0);
93     item.SetRawDy(0);
94     CHKPV(pointerEvent);
95     pointerEvent->SetPointerAction(OHOS::MMI::PointerEvent::POINTER_ACTION_MOVE);
96     pointerEvent->AddFlag(OHOS::MMI::InputEvent::EVENT_FLAG_RAW_POINTER_MOVEMENT);
97     pointerEvent->SetPointerId(0);
98     pointerEvent->SetSourceType(OHOS::MMI::PointerEvent::SOURCE_TYPE_MOUSE);
99     pointerEvent->AddPointerItem(item);
100     env_->GetInput().SimulateInputEvent(pointerEvent);
101 }
102 
BuildChains(std::shared_ptr<Initial> self,CooperateOut & parent)103 void CooperateOut::Initial::BuildChains(std::shared_ptr<Initial> self, CooperateOut &parent)
104 {}
105 
RemoveChains(std::shared_ptr<Initial> self)106 void CooperateOut::Initial::RemoveChains(std::shared_ptr<Initial> self)
107 {}
108 
Initial(CooperateOut & parent)109 CooperateOut::Initial::Initial(CooperateOut &parent)
110     : ICooperateStep(parent, nullptr), parent_(parent)
111 {
112     AddHandler(CooperateEventType::DISABLE, [this](Context &context, const CooperateEvent &event) {
113         this->OnDisable(context, event);
114     });
115     AddHandler(CooperateEventType::START, [this](Context &context, const CooperateEvent &event) {
116         this->OnStart(context, event);
117     });
118     AddHandler(CooperateEventType::WITH_OPTIONS_START, [this](Context &context, const CooperateEvent &event) {
119         this->OnStartWithOptions(context, event);
120     });
121     AddHandler(CooperateEventType::STOP, [this](Context &context, const CooperateEvent &event) {
122         this->OnStop(context, event);
123     });
124     AddHandler(CooperateEventType::APP_CLOSED, [this](Context &context, const CooperateEvent &event) {
125         this->OnAppClosed(context, event);
126     });
127     AddHandler(CooperateEventType::INPUT_HOTPLUG_EVENT, [this](Context &context, const CooperateEvent &event) {
128         this->OnHotplug(context, event);
129     });
130     AddHandler(CooperateEventType::INPUT_POINTER_EVENT, [this](Context &context, const CooperateEvent &event) {
131         this->OnPointerEvent(context, event);
132     });
133     AddHandler(CooperateEventType::DDM_BOARD_OFFLINE, [this](Context &context, const CooperateEvent &event) {
134         this->OnBoardOffline(context, event);
135     });
136     AddHandler(CooperateEventType::DDP_COOPERATE_SWITCH_CHANGED,
137         [this](Context &context, const CooperateEvent &event) {
138             this->OnSwitchChanged(context, event);
139     });
140     AddHandler(CooperateEventType::DSOFTBUS_SESSION_CLOSED,
141         [this](Context &context, const CooperateEvent &event) {
142             this->OnSoftbusSessionClosed(context, event);
143     });
144     AddHandler(CooperateEventType::DSOFTBUS_COME_BACK,
145         [this](Context &context, const CooperateEvent &event) {
146             this->OnComeBack(context, event);
147     });
148     AddHandler(CooperateEventType::DSOFTBUS_START_COOPERATE,
149         [this](Context &context, const CooperateEvent &event) {
150             this->OnRemoteStart(context, event);
151     });
152     AddHandler(CooperateEventType::DSOFTBUS_STOP_COOPERATE,
153         [this](Context &context, const CooperateEvent &event) {
154             this->OnRemoteStop(context, event);
155     });
156     AddHandler(CooperateEventType::DSOFTBUS_RELAY_COOPERATE,
157         [this](Context &context, const CooperateEvent &event) {
158             this->OnRelay(context, event);
159     });
160     AddHandler(CooperateEventType::DSOFTBUS_COOPERATE_WITH_OPTIONS,
161         [this](Context &context, const CooperateEvent &event) {
162             this->OnRemoteStartWithOptions(context, event);
163     });
164     AddHandler(CooperateEventType::DSOFTBUS_COME_BACK_WITH_OPTIONS,
165         [this](Context &context, const CooperateEvent &event) {
166             this->OnComeBackWithOptions(context, event);
167     });
168     AddHandler(CooperateEventType::DSOFTBUS_RELAY_COOPERATE_WITHOPTIONS,
169         [this](Context &context, const CooperateEvent &event) {
170             this->OnRelayWithOptions(context, event);
171     });
172 }
173 
OnDisable(Context & context,const CooperateEvent & event)174 void CooperateOut::Initial::OnDisable(Context &context, const CooperateEvent &event)
175 {
176     FI_HILOGI("[disable cooperation] Stop cooperation");
177     parent_.StopCooperate(context, event);
178 }
179 
OnStart(Context & context,const CooperateEvent & event)180 void CooperateOut::Initial::OnStart(Context &context, const CooperateEvent &event)
181 {
182     StartCooperateEvent param = std::get<StartCooperateEvent>(event.event);
183 
184     if (parent_.env_->GetDragManager().GetDragState() == DragState::MOTION_DRAGGING) {
185         FI_HILOGE("Not allow cooperate");
186         NotAollowCooperateWhenMotionDragging result {
187             .pid = param.pid,
188             .userData = param.userData,
189             .networkId = param.remoteNetworkId,
190             .success = false,
191             .errCode = static_cast<int32_t>(CoordinationErrCode::NOT_AOLLOW_COOPERATE_WHEN_MOTION_DRAGGING)
192         };
193         context.eventMgr_.ErrorNotAollowCooperateWhenMotionDragging(result);
194         return;
195     }
196     context.eventMgr_.StartCooperate(param);
197     FI_HILOGI("[start] Start cooperation with \'%{public}s\', report success when out",
198         Utility::Anonymize(context.Peer()).c_str());
199     DSoftbusStartCooperateFinished failNotice {
200         .success = false,
201         .errCode = static_cast<int32_t>(CoordinationErrCode::UNEXPECTED_START_CALL)
202     };
203     context.eventMgr_.StartCooperateFinish(failNotice);
204 }
205 
OnStartWithOptions(Context & context,const CooperateEvent & event)206 void CooperateOut::Initial::OnStartWithOptions(Context &context, const CooperateEvent &event)
207 {
208     StartWithOptionsEvent param = std::get<StartWithOptionsEvent>(event.event);
209 
210     context.eventMgr_.StartCooperateWithOptions(param);
211     FI_HILOGI("[start] Start cooperation with Options\'%{public}s\', report success when out",
212         Utility::Anonymize(context.Peer()).c_str());
213     DSoftbusCooperateOptions failNotice {
214         .success = false,
215         .errCode = static_cast<int32_t>(CoordinationErrCode::UNEXPECTED_START_CALL)
216     };
217     context.eventMgr_.StartCooperateWithOptinsFinish(failNotice);
218 }
219 
OnStop(Context & context,const CooperateEvent & event)220 void CooperateOut::Initial::OnStop(Context &context, const CooperateEvent &event)
221 {
222     StopCooperateEvent param = std::get<StopCooperateEvent>(event.event);
223 
224     context.eventMgr_.StopCooperate(param);
225     FI_HILOGI("[stop] Stop cooperation with \'%{public}s\', unchain:%{public}d",
226         Utility::Anonymize(context.Peer()).c_str(), param.isUnchained);
227     parent_.StopCooperate(context, event);
228 
229     param.networkId = context.Peer();
230     DSoftbusStopCooperateFinished notice {
231         .networkId = context.Peer(),
232         .normal = true,
233     };
234     context.eventMgr_.StopCooperateFinish(notice);
235 
236     parent_.UnchainConnections(context, param);
237 }
238 
OnComeBack(Context & context,const CooperateEvent & event)239 void CooperateOut::Initial::OnComeBack(Context &context, const CooperateEvent &event)
240 {
241     CALL_INFO_TRACE;
242     DSoftbusComeBack notice = std::get<DSoftbusComeBack>(event.event);
243 
244     if (!context.IsPeer(notice.networkId)) {
245         return;
246     }
247     FI_HILOGI("[come back] From \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
248     context.OnRemoteStartCooperate(notice.extra);
249     DSoftbusStartCooperate startEvent {
250         .networkId = notice.networkId,
251     };
252     context.eventMgr_.RemoteStart(startEvent);
253     context.inputEventInterceptor_.Disable();
254 
255     context.RemoteStartSuccess(notice);
256     context.eventMgr_.RemoteStartFinish(notice);
257     TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
258     context.OnBack();
259     if (!context.NeedHideCursor()) {
260         parent_.SimulateShowPointerEvent();
261     }
262 }
263 
OnComeBackWithOptions(Context & context,const CooperateEvent & event)264 void CooperateOut::Initial::OnComeBackWithOptions(Context &context, const CooperateEvent &event)
265 {
266     CALL_INFO_TRACE;
267     DSoftbusCooperateOptions notice = std::get<DSoftbusCooperateOptions>(event.event);
268 
269     if (!context.IsPeer(notice.networkId)) {
270         return;
271     }
272     FI_HILOGI("[come back cooperate with options] From \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
273     context.OnRemoteStartCooperate(notice.extra);
274     DSoftbusStartCooperate startEvent{
275         .networkId = notice.networkId,
276     };
277     context.eventMgr_.RemoteStart(startEvent);
278     context.inputEventInterceptor_.Disable();
279 
280     context.OnRemoteStart(notice);
281     context.eventMgr_.RemoteStartWithOptionsFinish(notice);
282     TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
283     context.OnBack();
284 }
285 
OnRemoteStart(Context & context,const CooperateEvent & event)286 void CooperateOut::Initial::OnRemoteStart(Context &context, const CooperateEvent &event)
287 {
288     DSoftbusStartCooperate notice = std::get<DSoftbusStartCooperate>(event.event);
289 
290     if (context.IsLocal(notice.networkId)) {
291         return;
292     }
293     FI_HILOGI("[remote start] Request from \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
294     if (context.IsPeer(notice.networkId)) {
295         FI_HILOGI("[remote start] Reset on request from peer");
296         parent_.StopCooperate(context, event);
297         return;
298     }
299     context.OnResetCooperation();
300     context.OnRemoteStartCooperate(notice.extra);
301     context.eventMgr_.RemoteStart(notice);
302     context.inputEventInterceptor_.Disable();
303 
304     DSoftbusStopCooperate stopNotice {};
305     context.dsoftbus_.StopCooperate(context.Peer(), stopNotice);
306 
307     context.RemoteStartSuccess(notice);
308     context.inputEventBuilder_.Enable(context);
309     context.eventMgr_.RemoteStartFinish(notice);
310     FI_HILOGI("[remote start] Cooperation with \'%{public}s\' established", Utility::Anonymize(context.Peer()).c_str());
311     TransiteTo(context, CooperateState::COOPERATE_STATE_IN);
312     context.OnTransitionIn();
313 }
314 
OnRemoteStartWithOptions(Context & context,const CooperateEvent & event)315 void CooperateOut::Initial::OnRemoteStartWithOptions(Context &context, const CooperateEvent &event)
316 {
317     DSoftbusCooperateOptions notice = std::get<DSoftbusCooperateOptions>(event.event);
318     if (context.IsLocal(notice.networkId)) {
319         return;
320     }
321     FI_HILOGI("[remote start cooperate with options ] Request from '%{public}s'",
322         Utility::Anonymize(notice.networkId).c_str());
323     if (context.IsPeer(notice.networkId)) {
324         FI_HILOGI("[remote start] Reset on request from peer");
325         parent_.StopCooperate(context, event);
326         return;
327     }
328     context.OnResetCooperation();
329     context.OnRemoteStartCooperate(notice.extra);
330     context.eventMgr_.RemoteStartWithOptions(notice);
331     context.inputEventInterceptor_.Disable();
332 
333     DSoftbusStopCooperate stopNotice{};
334     context.dsoftbus_.StopCooperate(context.Peer(), stopNotice);
335 
336     context.OnRemoteStart(notice);
337     context.inputEventBuilder_.Enable(context);
338     context.eventMgr_.RemoteStartWithOptionsFinish(notice);
339     FI_HILOGI("[remote start] Cooperation with \'%{public}s\' established", Utility::Anonymize(context.Peer()).c_str());
340     TransiteTo(context, CooperateState::COOPERATE_STATE_IN);
341     context.OnTransitionIn();
342 }
343 
OnRemoteStop(Context & context,const CooperateEvent & event)344 void CooperateOut::Initial::OnRemoteStop(Context &context, const CooperateEvent &event)
345 {
346     DSoftbusStopCooperate notice = std::get<DSoftbusStopCooperate>(event.event);
347 
348     if (!context.IsPeer(notice.networkId)) {
349         return;
350     }
351     FI_HILOGI("[remote stop] Notification from \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
352     context.eventMgr_.RemoteStop(notice);
353     context.inputEventInterceptor_.Disable();
354     context.ResetCursorPosition();
355     context.eventMgr_.RemoteStopFinish(notice);
356     TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
357     context.OnResetCooperation();
358 }
359 
OnRelay(Context & context,const CooperateEvent & event)360 void CooperateOut::Initial::OnRelay(Context &context, const CooperateEvent &event)
361 {
362     DSoftbusRelayCooperate notice = std::get<DSoftbusRelayCooperate>(event.event);
363     if (!context.IsPeer(notice.networkId)) {
364         return;
365     }
366     DSoftbusRelayCooperateFinished resp {
367         .targetNetworkId = notice.targetNetworkId,
368     };
369 
370     int32_t ret = context.dsoftbus_.OpenSession(notice.targetNetworkId);
371     if (ret != RET_OK) {
372         FI_HILOGE("[relay cooperate] Failed to connect to \'%{public}s\'",
373             Utility::Anonymize(notice.targetNetworkId).c_str());
374         resp.normal = false;
375         context.dsoftbus_.RelayCooperateFinish(notice.networkId, resp);
376         return;
377     }
378 
379     resp.normal = true;
380     context.dsoftbus_.RelayCooperateFinish(notice.networkId, resp);
381 
382     context.RelayCooperate(notice);
383     context.inputEventInterceptor_.Update(context);
384     FI_HILOGI("[relay cooperate] Relay cooperation to \'%{public}s\'", Utility::Anonymize(context.Peer()).c_str());
385     context.OnRelayCooperation(context.Peer(), context.NormalizedCursorPosition());
386 }
387 
OnRelayWithOptions(Context & context,const CooperateEvent & event)388 void CooperateOut::Initial::OnRelayWithOptions(Context &context, const CooperateEvent &event)
389 {
390     DSoftbusRelayCooperate notice = std::get<DSoftbusRelayCooperate>(event.event);
391     if (!context.IsPeer(notice.networkId)) {
392         return;
393     }
394     DSoftbusRelayCooperateFinished resp {
395         .targetNetworkId = notice.targetNetworkId,
396     };
397 
398     int32_t ret = context.dsoftbus_.OpenSession(notice.targetNetworkId);
399     if (ret != RET_OK) {
400         FI_HILOGE("[relay cooperate] Failed to connect to \'%{public}s\'",
401             Utility::Anonymize(notice.targetNetworkId).c_str());
402         resp.normal = false;
403         context.dsoftbus_.RelayCooperateWithOptionsFinish(notice.networkId, resp);
404         return;
405     }
406 
407     resp.normal = true;
408     context.dsoftbus_.RelayCooperateWithOptionsFinish(notice.networkId, resp);
409 
410     context.RelayCooperate(notice);
411     context.inputEventInterceptor_.Update(context);
412     FI_HILOGI("[relay cooperate] Relay cooperation to \'%{public}s\'", Utility::Anonymize(context.Peer()).c_str());
413     context.OnRelayCooperation(context.Peer(), context.NormalizedCursorPosition());
414 }
415 
OnHotplug(Context & context,const CooperateEvent & event)416 void CooperateOut::Initial::OnHotplug(Context &context, const CooperateEvent &event)
417 {
418     InputHotplugEvent notice = std::get<InputHotplugEvent>(event.event);
419     if (notice.deviceId != context.StartDeviceId()) {
420         return;
421     }
422     FI_HILOGI("Stop cooperation on unplug of dedicated pointer");
423     parent_.StopCooperate(context, event);
424 }
425 
OnAppClosed(Context & context,const CooperateEvent & event)426 void CooperateOut::Initial::OnAppClosed(Context &context, const CooperateEvent &event)
427 {
428     FI_HILOGI("[app closed] Close all connections");
429     context.dsoftbus_.CloseAllSessions();
430     FI_HILOGI("[app closed] Stop cooperation");
431     parent_.StopCooperate(context, event);
432 }
433 
OnPointerEvent(Context & context,const CooperateEvent & event)434 void CooperateOut::Initial::OnPointerEvent(Context &context, const CooperateEvent &event)
435 {
436     InputPointerEvent notice = std::get<InputPointerEvent>(event.event);
437 
438     if ((notice.sourceType != MMI::PointerEvent::SOURCE_TYPE_MOUSE) ||
439         (notice.deviceId == context.StartDeviceId()) ||
440         (notice.deviceId < 0)) {
441         return;
442     }
443     FI_HILOGI("Stop cooperation on operation of undedicated pointer");
444     parent_.StopCooperate(context, event);
445 }
446 
OnBoardOffline(Context & context,const CooperateEvent & event)447 void CooperateOut::Initial::OnBoardOffline(Context &context, const CooperateEvent &event)
448 {
449     DDMBoardOfflineEvent notice = std::get<DDMBoardOfflineEvent>(event.event);
450 
451     if (!context.IsPeer(notice.networkId)) {
452         return;
453     }
454     FI_HILOGI("[board offline] Peer(\'%{public}s\') is offline", Utility::Anonymize(notice.networkId).c_str());
455     parent_.StopCooperate(context, event);
456 }
457 
OnSwitchChanged(Context & context,const CooperateEvent & event)458 void CooperateOut::Initial::OnSwitchChanged(Context &context, const CooperateEvent &event)
459 {
460     DDPCooperateSwitchChanged notice = std::get<DDPCooperateSwitchChanged>(event.event);
461 
462     if (!context.IsPeer(notice.networkId) || notice.normal) {
463         return;
464     }
465     FI_HILOGI("[switch off] Peer(\'%{public}s\') switch off", Utility::Anonymize(notice.networkId).c_str());
466     parent_.StopCooperate(context, event);
467 }
468 
OnSoftbusSessionClosed(Context & context,const CooperateEvent & event)469 void CooperateOut::Initial::OnSoftbusSessionClosed(Context &context, const CooperateEvent &event)
470 {
471     DSoftbusSessionClosed notice = std::get<DSoftbusSessionClosed>(event.event);
472 
473     if (!context.IsPeer(notice.networkId)) {
474         return;
475     }
476     FI_HILOGI("[dsoftbus session closed] Disconnected with \'%{public}s\'",
477         Utility::Anonymize(notice.networkId).c_str());
478     parent_.StopCooperate(context, event);
479 }
480 
OnProgress(Context & context,const CooperateEvent & event)481 void CooperateOut::Initial::OnProgress(Context &context, const CooperateEvent &event)
482 {}
483 
OnProgressWithOptions(Context & context,const CooperateEvent & event)484 void CooperateOut::Initial::OnProgressWithOptions(Context &context, const CooperateEvent &event)
485 {}
486 
OnReset(Context & context,const CooperateEvent & event)487 void CooperateOut::Initial::OnReset(Context &context, const CooperateEvent &event)
488 {}
489 
StopCooperate(Context & context,const CooperateEvent & event)490 void CooperateOut::StopCooperate(Context &context, const CooperateEvent &event)
491 {
492     context.inputEventInterceptor_.Disable();
493 
494     DSoftbusStopCooperate notice {};
495     context.dsoftbus_.StopCooperate(context.Peer(), notice);
496 
497     context.ResetCursorPosition();
498     TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
499     context.OnResetCooperation();
500 }
501 
UnchainConnections(Context & context,const StopCooperateEvent & event) const502 void CooperateOut::UnchainConnections(Context &context, const StopCooperateEvent &event) const
503 {
504     if (event.isUnchained) {
505         FI_HILOGI("Unchain all connections");
506         context.dsoftbus_.CloseAllSessions();
507         context.eventMgr_.OnUnchain(event);
508     }
509 }
510 } // namespace Cooperate
511 } // namespace DeviceStatus
512 } // namespace Msdp
513 } // namespace OHOS
514