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