• 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 "state_machine.h"
17 
18 #include "application_state_observer_stub.h"
19 #include "iservice_registry.h"
20 #include "system_ability_definition.h"
21 
22 #include "common_event_observer.h"
23 #include "cooperate_events.h"
24 #include "cooperate_free.h"
25 #include "cooperate_hisysevent.h"
26 #include "cooperate_in.h"
27 #include "cooperate_out.h"
28 #include "devicestatus_define.h"
29 #include "devicestatus_errors.h"
30 #include "event_manager.h"
31 #include "utility.h"
32 
33 #undef LOG_TAG
34 #define LOG_TAG "StateMachine"
35 
36 namespace OHOS {
37 namespace Msdp {
38 namespace DeviceStatus {
39 
40 namespace {
41 const std::string VIRTUAL_TRACK_PAD_NAME { "VirtualTrackpad" };
42 }
43 namespace Cooperate {
44 
AppStateObserver(Channel<CooperateEvent>::Sender sender,int32_t clientPid)45 StateMachine::AppStateObserver::AppStateObserver(Channel<CooperateEvent>::Sender sender, int32_t clientPid)
46     : sender_(sender), clientPid_(clientPid) {}
47 
OnProcessDied(const AppExecFwk::ProcessData & processData)48 void StateMachine::AppStateObserver::OnProcessDied(const AppExecFwk::ProcessData &processData)
49 {
50     FI_HILOGI("\'%{public}s\' died, pid:%{public}d", processData.bundleName.c_str(), processData.pid);
51     if (processData.pid == clientPid_) {
52         auto ret = sender_.Send(CooperateEvent(
53             CooperateEventType::APP_CLOSED,
54             ClientDiedEvent {
55                 .pid = clientPid_,
56             }));
57         if (ret != Channel<CooperateEvent>::NO_ERROR) {
58             FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
59         }
60         FI_HILOGI("\'%{public}s\' died, report to handler", processData.bundleName.c_str());
61     }
62 }
63 
UpdateClientPid(int32_t clientPid)64 void StateMachine::AppStateObserver::UpdateClientPid(int32_t clientPid)
65 {
66     clientPid_ = clientPid;
67 }
68 
StateMachine(IContext * env)69 StateMachine::StateMachine(IContext *env)
70     : env_(env)
71 {
72     states_[COOPERATE_STATE_FREE] = std::make_shared<CooperateFree>(*this, env);
73     states_[COOPERATE_STATE_OUT] = std::make_shared<CooperateOut>(*this, env);
74     states_[COOPERATE_STATE_IN] = std::make_shared<CooperateIn>(*this, env);
75 
76     AddHandler(CooperateEventType::ADD_OBSERVER, [this](Context &context, const CooperateEvent &event) {
77         this->AddObserver(context, event);
78     });
79     AddHandler(CooperateEventType::REMOVE_OBSERVER, [this](Context &context, const CooperateEvent &event) {
80         this->RemoveObserver(context, event);
81     });
82     AddHandler(CooperateEventType::REGISTER_LISTENER, [this](Context &context, const CooperateEvent &event) {
83         this->RegisterListener(context, event);
84     });
85     AddHandler(CooperateEventType::UNREGISTER_LISTENER, [this](Context &context, const CooperateEvent &event) {
86         this->UnregisterListener(context, event);
87     });
88     AddHandler(CooperateEventType::REGISTER_HOTAREA_LISTENER, [this](Context &context, const CooperateEvent &event) {
89         this->RegisterHotAreaListener(context, event);
90     });
91     AddHandler(CooperateEventType::UNREGISTER_HOTAREA_LISTENER,
92         [this](Context &context, const CooperateEvent &event) {
93             this->UnregisterHotAreaListener(context, event);
94     });
95     AddHandler(CooperateEventType::ENABLE, [this](Context &context, const CooperateEvent &event) {
96         this->EnableCooperate(context, event);
97     });
98     AddHandler(CooperateEventType::DISABLE, [this](Context &context, const CooperateEvent &event) {
99         this->DisableCooperate(context, event);
100     });
101     AddHandler(CooperateEventType::START, [this](Context &context, const CooperateEvent &event) {
102         this->StartCooperate(context, event);
103     });
104     AddHandler(CooperateEventType::GET_COOPERATE_STATE, [this](Context &context, const CooperateEvent &event) {
105         this->GetCooperateState(context, event);
106     });
107     AddHandler(CooperateEventType::WITH_OPTIONS_START, [this](Context &context, const CooperateEvent &event) {
108         this->StartCooperateWithOptions(context, event);
109     });
110     AddHandler(CooperateEventType::REGISTER_EVENT_LISTENER,
111         [this](Context &context, const CooperateEvent &event) {
112             this->RegisterEventListener(context, event);
113     });
114     AddHandler(CooperateEventType::UNREGISTER_EVENT_LISTENER,
115         [this](Context &context, const CooperateEvent &event) {
116             this->UnregisterEventListener(context, event);
117     });
118     AddHandler(CooperateEventType::DDM_BOARD_ONLINE,
119         [this](Context &context, const CooperateEvent &event) {
120             this->OnBoardOnline(context, event);
121     });
122     AddHandler(CooperateEventType::DDM_BOARD_OFFLINE,
123         [this](Context &context, const CooperateEvent &event) {
124             this->OnBoardOffline(context, event);
125     });
126     AddHandler(CooperateEventType::DDP_COOPERATE_SWITCH_CHANGED,
127         [this](Context &context, const CooperateEvent &event) {
128             this->OnProfileChanged(context, event);
129     });
130     AddHandler(CooperateEventType::INPUT_POINTER_EVENT,
131         [this](Context &context, const CooperateEvent &event) {
132             this->OnPointerEvent(context, event);
133     });
134     AddHandler(CooperateEventType::APP_CLOSED, [this](Context &context, const CooperateEvent &event) {
135         this->OnProcessClientDied(context, event);
136     });
137     AddHandler(CooperateEventType::DSOFTBUS_SESSION_OPENED,
138         [this](Context &context, const CooperateEvent &event) {
139             this->OnSoftbusSessionOpened(context, event);
140     });
141     AddHandler(CooperateEventType::DSOFTBUS_SESSION_CLOSED,
142         [this](Context &context, const CooperateEvent &event) {
143             this->OnSoftbusSessionClosed(context, event);
144     });
145     AddHandler(CooperateEventType::DSOFTBUS_SUBSCRIBE_MOUSE_LOCATION,
146         [this](Context &context, const CooperateEvent &event) {
147             this->OnSoftbusSubscribeMouseLocation(context, event);
148     });
149     AddHandler(CooperateEventType::DSOFTBUS_UNSUBSCRIBE_MOUSE_LOCATION,
150         [this](Context &context, const CooperateEvent &event) {
151             this->OnSoftbusUnSubscribeMouseLocation(context, event);
152     });
153     AddHandler(CooperateEventType::DSOFTBUS_REPLY_SUBSCRIBE_MOUSE_LOCATION,
154         [this](Context &context, const CooperateEvent &event) {
155             this->OnSoftbusReplySubscribeMouseLocation(context, event);
156     });
157     AddHandler(CooperateEventType::DSOFTBUS_REPLY_UNSUBSCRIBE_MOUSE_LOCATION,
158         [this](Context &context, const CooperateEvent &event) {
159             this->OnSoftbusReplyUnSubscribeMouseLocation(context, event);
160     });
161     AddHandler(CooperateEventType::DSOFTBUS_MOUSE_LOCATION,
162         [this](Context &context, const CooperateEvent &event) {
163             this->OnSoftbusMouseLocation(context, event);
164     });
165     AddHandler(CooperateEventType::DSOFTBUS_START_COOPERATE,
166         [this](Context &context, const CooperateEvent &event) {
167             this->OnRemoteStart(context, event);
168     });
169     AddHandler(CooperateEventType::INPUT_HOTPLUG_EVENT,
170         [this](Context &context, const CooperateEvent &event) {
171             this->OnHotPlugEvent(context, event);
172     });
173     AddHandler(CooperateEventType::DSOFTBUS_INPUT_DEV_HOT_PLUG,
174         [this](Context &context, const CooperateEvent &event) {
175             this->OnRemoteHotPlug(context, event);
176     });
177     AddHandler(CooperateEventType::DSOFTBUS_INPUT_DEV_SYNC,
178         [this](Context &context, const CooperateEvent &event) {
179             this->OnRemoteInputDevice(context, event);
180     });
181     AddHandler(CooperateEventType::STOP, [this](Context &context, const CooperateEvent &event) {
182         this->StopCooperate(context, event);
183     });
184     AddHandler(CooperateEventType::UPDATE_VIRTUAL_DEV_ID_MAP, [this](Context &context, const CooperateEvent &event) {
185         this->UpdateVirtualDeviceIdMap(context, event);
186     });
187     AddHandler(CooperateEventType::DSOFTBUS_COOPERATE_WITH_OPTIONS,
188         [this](Context &context, const CooperateEvent &event) {
189             this->OnRemoteStartWithOptions(context, event);
190     });
191 }
192 
OnEvent(Context & context,const CooperateEvent & event)193 void StateMachine::OnEvent(Context &context, const CooperateEvent &event)
194 {
195     if (auto iter = handlers_.find(event.type); iter != handlers_.end()) {
196         iter->second(context, event);
197     } else {
198         Transfer(context, event);
199     }
200 }
201 
TransiteTo(Context & context,CooperateState state)202 void StateMachine::TransiteTo(Context &context, CooperateState state)
203 {
204     if ((state >= COOPERATE_STATE_FREE) &&
205         (state < N_COOPERATE_STATES) &&
206         (state != current_)) {
207         states_[current_]->OnLeaveState(context);
208         current_ = state;
209         states_[current_]->OnEnterState(context);
210         StatusChangeEvent event = {
211             .networkId = IDSoftbusAdapter::GetLocalNetworkId(),
212             .msg = CoordinationMessage::COORDINATION_STATUS_FREE,
213         };
214         if (state == COOPERATE_STATE_OUT) {
215             event.msg = CoordinationMessage::COORDINATION_STATUS_OUT;
216         }
217         if (state == COOPERATE_STATE_IN) {
218             event.msg = CoordinationMessage::COORDINATION_STATUS_IN;
219         }
220         context.eventMgr_.OnStatusChanged(event);
221     }
222 }
223 
AddHandler(CooperateEventType event,std::function<void (Context &,const CooperateEvent &)> handler)224 void StateMachine::AddHandler(CooperateEventType event, std::function<void(Context&, const CooperateEvent&)> handler)
225 {
226     handlers_.emplace(event, handler);
227 }
228 
OnQuit(Context & context)229 void StateMachine::OnQuit(Context &context)
230 {
231     CALL_DEBUG_ENTER;
232     RemoveWatches(context);
233     RemoveMonitor(context);
234 }
235 
AddObserver(Context & context,const CooperateEvent & event)236 void StateMachine::AddObserver(Context &context, const CooperateEvent &event)
237 {
238     AddObserverEvent notice = std::get<AddObserverEvent>(event.event);
239     context.AddObserver(notice.observer);
240 }
241 
RemoveObserver(Context & context,const CooperateEvent & event)242 void StateMachine::RemoveObserver(Context &context, const CooperateEvent &event)
243 {
244     RemoveObserverEvent notice = std::get<RemoveObserverEvent>(event.event);
245     context.RemoveObserver(notice.observer);
246 }
247 
RegisterListener(Context & context,const CooperateEvent & event)248 void StateMachine::RegisterListener(Context &context, const CooperateEvent &event)
249 {
250     RegisterListenerEvent notice = std::get<RegisterListenerEvent>(event.event);
251     context.eventMgr_.RegisterListener(notice);
252 }
253 
UnregisterListener(Context & context,const CooperateEvent & event)254 void StateMachine::UnregisterListener(Context &context, const CooperateEvent &event)
255 {
256     UnregisterListenerEvent notice = std::get<UnregisterListenerEvent>(event.event);
257     context.eventMgr_.UnregisterListener(notice);
258 }
259 
RegisterHotAreaListener(Context & context,const CooperateEvent & event)260 void StateMachine::RegisterHotAreaListener(Context &context, const CooperateEvent &event)
261 {
262     RegisterHotareaListenerEvent notice = std::get<RegisterHotareaListenerEvent>(event.event);
263     context.hotArea_.AddListener(notice);
264 }
265 
UnregisterHotAreaListener(Context & context,const CooperateEvent & event)266 void StateMachine::UnregisterHotAreaListener(Context &context, const CooperateEvent &event)
267 {
268     UnregisterHotareaListenerEvent notice = std::get<UnregisterHotareaListenerEvent>(event.event);
269     context.hotArea_.RemoveListener(notice);
270 }
271 
EnableCooperate(Context & context,const CooperateEvent & event)272 void StateMachine::EnableCooperate(Context &context, const CooperateEvent &event)
273 {
274     CALL_INFO_TRACE;
275     EnableCooperateEvent enableEvent = std::get<EnableCooperateEvent>(event.event);
276     context.EnableCooperate(enableEvent);
277     context.eventMgr_.EnableCooperate(enableEvent);
278     context.hotArea_.EnableCooperate(enableEvent);
279     observer_ = CommonEventObserver::CreateCommonEventObserver(
280         [&context, this] (const std::string &commonEvent) {
281             OnCommonEvent(context, commonEvent);
282         }
283     );
284     context.commonEvent_.AddObserver(observer_);
285     AddSessionObserver(context, enableEvent);
286     AddMonitor(context);
287     AddPreMonitor(context);
288     auto devAddedCallback = [this, &context](int32_t deviceId, const std::string &type) {
289         FI_HILOGI("Device added");
290         bool isVirtualtrackpad = this->CheckIsVirtualTrackpad(deviceId);
291         if (isVirtualtrackpad) {
292             context.SetVirtualTrackpadDeviceId(deviceId);
293         }
294     };
295     auto devRemovedCallback = [this, &context](int32_t deviceId, const std::string &type) {
296         FI_HILOGI("Device removed, deviceId %{public}d", deviceId);
297         if (deviceId == context.GetVirtualTrackpadDeviceId()) {
298             ResetCooperate(context);
299             context.ResetVirtualTrackpadDeviceId();
300         }
301     };
302     CHKPV(env_);
303     env_->GetInput().RegisterDevListener(devAddedCallback, devRemovedCallback);
304     isCooperateEnable_ = true;
305     Transfer(context, event);
306 }
307 
DisableCooperate(Context & context,const CooperateEvent & event)308 void StateMachine::DisableCooperate(Context &context, const CooperateEvent &event)
309 {
310     CALL_INFO_TRACE;
311     CHKPV(env_);
312     DisableCooperateEvent disableEvent = std::get<DisableCooperateEvent>(event.event);
313     context.DisableCooperate(disableEvent);
314     context.eventMgr_.DisableCooperate(disableEvent);
315     context.commonEvent_.RemoveObserver(observer_);
316     context.inputDevMgr_.RemoveAllVirtualInputDevice();
317     RemoveSessionObserver(context, disableEvent);
318     RemoveMonitor(context);
319     RemovePreMonitor(context);
320     env_->GetInput().UnregisterDevListener();
321     context.ResetVirtualTrackpadDeviceId();
322     isCooperateEnable_ = false;
323     Transfer(context, event);
324 }
325 
StartCooperate(Context & context,const CooperateEvent & event)326 void StateMachine::StartCooperate(Context &context, const CooperateEvent &event)
327 {
328     CALL_INFO_TRACE;
329     CHKPV(env_);
330     StartCooperateEvent startEvent = std::get<StartCooperateEvent>(event.event);
331     bool checkSameAccount = false;
332     if (startEvent.uid > 0) {
333         checkSameAccount = env_->GetDDM().CheckSameAccountToLocalWithUid(startEvent.remoteNetworkId, startEvent.uid);
334     } else {
335         checkSameAccount = env_->GetDDM().CheckSameAccountToLocal(startEvent.remoteNetworkId);
336     }
337     if (!checkSameAccount) {
338         FI_HILOGE("CheckSameAccountToLocal failed");
339         startEvent.errCode->set_value(COMMON_PERMISSION_CHECK_ERROR);
340         CooperateRadarInfo radarInfo {
341             .funcName =  __FUNCTION__,
342             .bizState = static_cast<int32_t> (BizState::STATE_END),
343             .bizStage = static_cast<int32_t> (BizCooperateStage::STAGE_CHECK_SAME_ACCOUNT),
344             .stageRes = static_cast<int32_t> (BizCooperateStageRes::RES_FAIL),
345             .bizScene = static_cast<int32_t> (BizCooperateScene::SCENE_ACTIVE),
346             .errCode = static_cast<int32_t> (CooperateRadarErrCode::CHECK_SAME_ACCOUNT_FAILED),
347             .hostName = "",
348             .localNetId = Utility::DFXRadarAnonymize(context.Local().c_str()),
349             .peerNetId = Utility::DFXRadarAnonymize(startEvent.remoteNetworkId.c_str())
350         };
351         CooperateRadar::ReportCooperateRadarInfo(radarInfo);
352         return;
353     }
354     UpdateApplicationStateObserver(startEvent.pid);
355     if (!context.IsAllowCooperate()) {
356         FI_HILOGI("Not allow cooperate");
357         startEvent.errCode->set_value(COMMON_NOT_ALLOWED_DISTRIBUTED);
358         CooperateRadarInfo radarInfo {
359             .funcName = __FUNCTION__,
360             .bizState = static_cast<int32_t> (BizState::STATE_END),
361             .bizStage = static_cast<int32_t> (BizCooperateStage::STAGE_CHECK_ALLOW_COOPERATE),
362             .stageRes = static_cast<int32_t> (BizCooperateStageRes::RES_FAIL),
363             .bizScene = static_cast<int32_t> (BizCooperateScene::SCENE_ACTIVE),
364             .errCode = static_cast<int32_t> (CooperateRadarErrCode::CHECK_ALLOW_COOPERATE_FAILED),
365             .hostName = "",
366             .localNetId = Utility::DFXRadarAnonymize(context.Local().c_str()),
367             .peerNetId = Utility::DFXRadarAnonymize(startEvent.remoteNetworkId.c_str())
368         };
369         CooperateRadar::ReportCooperateRadarInfo(radarInfo);
370         return;
371     }
372     startEvent.errCode->set_value(RET_OK);
373     Transfer(context, event);
374 }
375 
StopCooperate(Context & context,const CooperateEvent & event)376 void StateMachine::StopCooperate(Context &context, const CooperateEvent &event)
377 {
378     CALL_DEBUG_ENTER;
379     context.CloseDistributedFileConnection(context.Peer());
380     context.OnStopCooperate();
381     context.inputDevMgr_.RemoveAllVirtualInputDevice();
382     Transfer(context, event);
383 }
384 
StartCooperateWithOptions(Context & context,const CooperateEvent & event)385 void StateMachine::StartCooperateWithOptions(Context &context, const CooperateEvent &event)
386 {
387     CALL_INFO_TRACE;
388     CHKPV(env_);
389     StartWithOptionsEvent withOptionsEvent = std::get<StartWithOptionsEvent>(event.event);
390     if (!env_->GetDDM().CheckSameAccountToLocal(withOptionsEvent.remoteNetworkId)) {
391         FI_HILOGE("CheckSameAccountToLocal failed");
392         withOptionsEvent.errCode->set_value(COMMON_PERMISSION_CHECK_ERROR);
393         CooperateRadarInfo radarInfo {
394             .funcName =  __FUNCTION__,
395             .bizState = static_cast<int32_t> (BizState::STATE_END),
396             .bizStage = static_cast<int32_t> (BizCooperateStage::STAGE_CHECK_SAME_ACCOUNT),
397             .stageRes = static_cast<int32_t> (BizCooperateStageRes::RES_FAIL),
398             .bizScene = static_cast<int32_t> (BizCooperateScene::SCENE_ACTIVE),
399             .errCode = static_cast<int32_t> (CooperateRadarErrCode::CHECK_SAME_ACCOUNT_FAILED),
400             .hostName = "",
401             .localNetId = Utility::DFXRadarAnonymize(context.Local().c_str()),
402             .peerNetId = Utility::DFXRadarAnonymize(withOptionsEvent.remoteNetworkId.c_str())
403         };
404         CooperateRadar::ReportCooperateRadarInfo(radarInfo);
405         return;
406     }
407     UpdateApplicationStateObserver(withOptionsEvent.pid);
408     if (!context.IsAllowCooperate()) {
409         FI_HILOGI("Not allow cooperate");
410         withOptionsEvent.errCode->set_value(COMMON_NOT_ALLOWED_DISTRIBUTED);
411         CooperateRadarInfo radarInfo {
412             .funcName = __FUNCTION__,
413             .bizState = static_cast<int32_t> (BizState::STATE_END),
414             .bizStage = static_cast<int32_t> (BizCooperateStage::STAGE_CHECK_ALLOW_COOPERATE),
415             .stageRes = static_cast<int32_t> (BizCooperateStageRes::RES_FAIL),
416             .bizScene = static_cast<int32_t> (BizCooperateScene::SCENE_ACTIVE),
417             .errCode = static_cast<int32_t> (CooperateRadarErrCode::CHECK_ALLOW_COOPERATE_FAILED),
418             .hostName = "",
419             .localNetId = Utility::DFXRadarAnonymize(context.Local().c_str()),
420             .peerNetId = Utility::DFXRadarAnonymize(withOptionsEvent.remoteNetworkId.c_str())
421         };
422         CooperateRadar::ReportCooperateRadarInfo(radarInfo);
423         return;
424     }
425     withOptionsEvent.errCode->set_value(RET_OK);
426     Transfer(context, event);
427 }
428 
GetCooperateState(Context & context,const CooperateEvent & event)429 void StateMachine::GetCooperateState(Context &context, const CooperateEvent &event)
430 {
431     CALL_INFO_TRACE;
432     GetCooperateStateEvent stateEvent = std::get<GetCooperateStateEvent>(event.event);
433     UpdateApplicationStateObserver(stateEvent.pid);
434     EventManager::CooperateStateNotice notice {
435         .pid = stateEvent.pid,
436         .msgId = MessageId::COORDINATION_GET_STATE,
437         .userData = stateEvent.userData,
438         .state = isCooperateEnable_,
439     };
440     context.eventMgr_.GetCooperateState(notice);
441 }
442 
OnProcessClientDied(Context & context,const CooperateEvent & event)443 void StateMachine::OnProcessClientDied(Context &context, const CooperateEvent &event)
444 {
445     CALL_INFO_TRACE;
446     ClientDiedEvent notice = std::get<ClientDiedEvent>(event.event);
447     context.eventMgr_.OnClientDied(notice);
448     context.hotArea_.OnClientDied(notice);
449     context.mouseLocation_.OnClientDied(notice);
450     Transfer(context, event);
451 }
452 
RegisterEventListener(Context & context,const CooperateEvent & event)453 void StateMachine::RegisterEventListener(Context &context, const CooperateEvent &event)
454 {
455     RegisterEventListenerEvent notice = std::get<RegisterEventListenerEvent>(event.event);
456     context.mouseLocation_.AddListener(notice);
457 }
458 
UnregisterEventListener(Context & context,const CooperateEvent & event)459 void StateMachine::UnregisterEventListener(Context &context, const CooperateEvent &event)
460 {
461     UnregisterEventListenerEvent notice = std::get<UnregisterEventListenerEvent>(event.event);
462     context.mouseLocation_.RemoveListener(notice);
463 }
464 
OnBoardOnline(Context & context,const CooperateEvent & event)465 void StateMachine::OnBoardOnline(Context &context, const CooperateEvent &event)
466 {
467     CALL_INFO_TRACE;
468     DDMBoardOnlineEvent onlineEvent = std::get<DDMBoardOnlineEvent>(event.event);
469 
470     auto ret = onlineBoards_.insert(onlineEvent.networkId);
471     if (ret.second) {
472         FI_HILOGD("Watch \'%{public}s\'", Utility::Anonymize(onlineEvent.networkId).c_str());
473         Transfer(context, event);
474     }
475 }
476 
OnBoardOffline(Context & context,const CooperateEvent & event)477 void StateMachine::OnBoardOffline(Context &context, const CooperateEvent &event)
478 {
479     CALL_INFO_TRACE;
480     DDMBoardOfflineEvent offlineEvent = std::get<DDMBoardOfflineEvent>(event.event);
481 
482     if (auto iter = onlineBoards_.find(offlineEvent.networkId); iter != onlineBoards_.end()) {
483         onlineBoards_.erase(iter);
484         FI_HILOGD("Remove watch \'%{public}s\'", Utility::Anonymize(offlineEvent.networkId).c_str());
485         context.CloseDistributedFileConnection(offlineEvent.networkId);
486         Transfer(context, event);
487     }
488 }
489 
OnProfileChanged(Context & context,const CooperateEvent & event)490 void StateMachine::OnProfileChanged(Context &context, const CooperateEvent &event)
491 {
492     CALL_INFO_TRACE;
493     DDPCooperateSwitchChanged notice = std::get<DDPCooperateSwitchChanged>(event.event);
494     context.eventMgr_.OnProfileChanged(notice);
495     Transfer(context, event);
496 }
497 
OnPointerEvent(Context & context,const CooperateEvent & event)498 void StateMachine::OnPointerEvent(Context &context, const CooperateEvent &event)
499 {
500     CALL_DEBUG_ENTER;
501     InputPointerEvent pointerEvent = std::get<InputPointerEvent>(event.event);
502     Coordinate cursorPos = context.CursorPosition();
503     context.OnPointerEvent(pointerEvent);
504     pointerEvent.position = cursorPos;
505     Transfer(context, CooperateEvent { CooperateEventType::INPUT_POINTER_EVENT, pointerEvent });
506 }
507 
OnSoftbusSessionClosed(Context & context,const CooperateEvent & event)508 void StateMachine::OnSoftbusSessionClosed(Context &context, const CooperateEvent &event)
509 {
510     CALL_INFO_TRACE;
511     DSoftbusSessionClosed notice = std::get<DSoftbusSessionClosed>(event.event);
512     context.eventMgr_.OnSoftbusSessionClosed(notice);
513     context.inputDevMgr_.OnSoftbusSessionClosed(notice);
514     context.mouseLocation_.OnSoftbusSessionClosed(notice);
515     context.CloseDistributedFileConnection(notice.networkId);
516     Transfer(context, event);
517 }
518 
OnSoftbusSessionOpened(Context & context,const CooperateEvent & event)519 void StateMachine::OnSoftbusSessionOpened(Context &context, const CooperateEvent &event)
520 {
521     CALL_INFO_TRACE;
522     CHKPV(env_);
523     DSoftbusSessionOpened notice = std::get<DSoftbusSessionOpened>(event.event);
524     context.inputDevMgr_.OnSoftbusSessionOpened(notice);
525     env_->GetDSoftbus().StartHeartBeat(notice.networkId);
526     Transfer(context, event);
527 }
528 
OnHotPlugEvent(Context & context,const CooperateEvent & event)529 void StateMachine::OnHotPlugEvent(Context &context, const CooperateEvent &event)
530 {
531     CALL_INFO_TRACE;
532     InputHotplugEvent notice = std::get<InputHotplugEvent>(event.event);
533     context.inputDevMgr_.OnLocalHotPlug(notice);
534     Transfer(context, event);
535 }
536 
OnRemoteInputDevice(Context & context,const CooperateEvent & event)537 void StateMachine::OnRemoteInputDevice(Context &context, const CooperateEvent &event)
538 {
539     CALL_INFO_TRACE;
540     DSoftbusSyncInputDevice notice = std::get<DSoftbusSyncInputDevice>(event.event);
541     context.inputDevMgr_.OnRemoteInputDevice(notice);
542     Transfer(context, event);
543 }
544 
OnRemoteHotPlug(Context & context,const CooperateEvent & event)545 void StateMachine::OnRemoteHotPlug(Context &context, const CooperateEvent &event)
546 {
547     CALL_INFO_TRACE;
548     DSoftbusHotPlugEvent notice = std::get<DSoftbusHotPlugEvent>(event.event);
549     context.inputDevMgr_.OnRemoteHotPlug(notice);
550     Transfer(context, event);
551 }
552 
OnSoftbusSubscribeMouseLocation(Context & context,const CooperateEvent & event)553 void StateMachine::OnSoftbusSubscribeMouseLocation(Context &context, const CooperateEvent &event)
554 {
555     CALL_INFO_TRACE;
556     DSoftbusSubscribeMouseLocation notice = std::get<DSoftbusSubscribeMouseLocation>(event.event);
557     context.mouseLocation_.OnSubscribeMouseLocation(notice);
558 }
559 
OnSoftbusUnSubscribeMouseLocation(Context & context,const CooperateEvent & event)560 void StateMachine::OnSoftbusUnSubscribeMouseLocation(Context &context, const CooperateEvent &event)
561 {
562     CALL_INFO_TRACE;
563     DSoftbusUnSubscribeMouseLocation notice = std::get<DSoftbusUnSubscribeMouseLocation>(event.event);
564     context.mouseLocation_.OnUnSubscribeMouseLocation(notice);
565 }
566 
OnSoftbusReplySubscribeMouseLocation(Context & context,const CooperateEvent & event)567 void StateMachine::OnSoftbusReplySubscribeMouseLocation(Context &context, const CooperateEvent &event)
568 {
569     CALL_INFO_TRACE;
570     DSoftbusReplySubscribeMouseLocation notice = std::get<DSoftbusReplySubscribeMouseLocation>(event.event);
571     context.mouseLocation_.OnReplySubscribeMouseLocation(notice);
572 }
573 
OnSoftbusReplyUnSubscribeMouseLocation(Context & context,const CooperateEvent & event)574 void StateMachine::OnSoftbusReplyUnSubscribeMouseLocation(Context &context, const CooperateEvent &event)
575 {
576     CALL_INFO_TRACE;
577     DSoftbusReplyUnSubscribeMouseLocation notice = std::get<DSoftbusReplyUnSubscribeMouseLocation>(event.event);
578     context.mouseLocation_.OnReplyUnSubscribeMouseLocation(notice);
579 }
580 
OnSoftbusMouseLocation(Context & context,const CooperateEvent & event)581 void StateMachine::OnSoftbusMouseLocation(Context &context, const CooperateEvent &event)
582 {
583     CALL_DEBUG_ENTER;
584     DSoftbusSyncMouseLocation notice = std::get<DSoftbusSyncMouseLocation>(event.event);
585     context.mouseLocation_.OnRemoteMouseLocation(notice);
586 }
587 
OnRemoteStart(Context & context,const CooperateEvent & event)588 void StateMachine::OnRemoteStart(Context &context, const CooperateEvent &event)
589 {
590     CALL_DEBUG_ENTER;
591     CHKPV(env_);
592     DSoftbusStartCooperate startEvent = std::get<DSoftbusStartCooperate>(event.event);
593     CooperateRadarInfo radarInfo {
594         .funcName =  __FUNCTION__,
595         .bizState = static_cast<int32_t> (BizState::STATE_END),
596         .bizScene = static_cast<int32_t> (BizCooperateScene::SCENE_PASSIVE),
597         .hostName = "",
598         .localNetId = Utility::DFXRadarAnonymize(context.Local().c_str()),
599         .peerNetId = Utility::DFXRadarAnonymize(startEvent.originNetworkId.c_str())
600     };
601     bool checkSameAccount = env_->GetDDM().CheckSameAccountToLocal(startEvent.originNetworkId);
602     if (!checkSameAccount) {
603         radarInfo.bizStage = static_cast<int32_t> (BizCooperateStage::STAGE_PASSIVE_CHECK_SAME_ACCOUNT);
604         radarInfo.stageRes = static_cast<int32_t> (BizCooperateStageRes::RES_FAIL);
605         radarInfo.errCode = static_cast<int32_t> (CooperateRadarErrCode::PASSIVE_CHECK_SAME_ACCOUNT_FAILED);
606         CooperateRadar::ReportCooperateRadarInfo(radarInfo);
607     }
608     if (!isCooperateEnable_) {
609         radarInfo.bizStage = static_cast<int32_t> (BizCooperateStage::STAGE_CHECK_PEER_SWITCH);
610         radarInfo.stageRes = static_cast<int32_t> (BizCooperateStageRes::RES_FAIL);
611         radarInfo.errCode = static_cast<int32_t> (CooperateRadarErrCode::CHECK_PEER_SWITCH_FAILED);
612         CooperateRadar::ReportCooperateRadarInfo(radarInfo);
613     }
614     if (!checkSameAccount || !isCooperateEnable_) {
615         FI_HILOGE("CheckSameAccountToLocal failed, switch is : %{public}d, unchain", isCooperateEnable_);
616         CooperateEvent stopEvent(
617             CooperateEventType::STOP,
618             StopCooperateEvent {
619                 .isUnchained = true
620             }
621         );
622         Transfer(context, stopEvent);
623         return;
624     }
625     Transfer(context, event);
626 }
627 
OnRemoteStartWithOptions(Context & context,const CooperateEvent & event)628 void StateMachine::OnRemoteStartWithOptions(Context &context, const CooperateEvent &event)
629 {
630     CALL_DEBUG_ENTER;
631     DSoftbusCooperateOptions startEvent = std::get<DSoftbusCooperateOptions>(event.event);
632     CooperateRadarInfo radarInfo {
633         .funcName =  __FUNCTION__,
634         .bizState = static_cast<int32_t> (BizState::STATE_END),
635         .bizScene = static_cast<int32_t> (BizCooperateScene::SCENE_PASSIVE),
636         .hostName = "",
637         .localNetId = Utility::DFXRadarAnonymize(context.Local().c_str()),
638         .peerNetId = Utility::DFXRadarAnonymize(startEvent.originNetworkId.c_str())
639     };
640     bool checkSameAccount = env_->GetDDM().CheckSameAccountToLocal(startEvent.originNetworkId);
641     if (!checkSameAccount) {
642         radarInfo.bizStage = static_cast<int32_t> (BizCooperateStage::STAGE_PASSIVE_CHECK_SAME_ACCOUNT);
643         radarInfo.stageRes = static_cast<int32_t> (BizCooperateStageRes::RES_FAIL);
644         radarInfo.errCode = static_cast<int32_t> (CooperateRadarErrCode::PASSIVE_CHECK_SAME_ACCOUNT_FAILED);
645         CooperateRadar::ReportCooperateRadarInfo(radarInfo);
646     }
647     if (!isCooperateEnable_) {
648         radarInfo.bizStage = static_cast<int32_t> (BizCooperateStage::STAGE_CHECK_PEER_SWITCH);
649         radarInfo.stageRes = static_cast<int32_t> (BizCooperateStageRes::RES_FAIL);
650         radarInfo.errCode = static_cast<int32_t> (CooperateRadarErrCode::CHECK_PEER_SWITCH_FAILED);
651         CooperateRadar::ReportCooperateRadarInfo(radarInfo);
652     }
653     if (!checkSameAccount || !isCooperateEnable_) {
654         FI_HILOGE("CheckSameAccountToLocal failed, switch is : %{public}d, unchain", isCooperateEnable_);
655         CooperateEvent stopEvent(
656             CooperateEventType::STOP,
657             StopCooperateEvent {
658                 .isUnchained = true
659             }
660         );
661         Transfer(context, stopEvent);
662         return;
663     }
664     Transfer(context, event);
665 }
666 
UpdateVirtualDeviceIdMap(Context & context,const CooperateEvent & event)667 void StateMachine::UpdateVirtualDeviceIdMap(Context &context, const CooperateEvent &event)
668 {
669     CALL_DEBUG_ENTER;
670     UpdateVirtualDeviceIdMapEvent notice = std::get<UpdateVirtualDeviceIdMapEvent>(event.event);
671     context.inputEventBuilder_.UpdateVirtualDeviceIdMap(notice.remote2VirtualIds);
672 }
673 
Transfer(Context & context,const CooperateEvent & event)674 void StateMachine::Transfer(Context &context, const CooperateEvent &event)
675 {
676     states_[current_]->OnEvent(context, event);
677 }
678 
GetAppMgr()679 sptr<AppExecFwk::IAppMgr> StateMachine::GetAppMgr()
680 {
681     CALL_INFO_TRACE;
682     auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
683     CHKPP(saMgr);
684     auto appMgrObj = saMgr->GetSystemAbility(APP_MGR_SERVICE_ID);
685     CHKPP(appMgrObj);
686     return iface_cast<AppExecFwk::IAppMgr>(appMgrObj);
687 }
688 
RegisterApplicationStateObserver(Channel<CooperateEvent>::Sender sender,const EnableCooperateEvent & event)689 int32_t StateMachine::RegisterApplicationStateObserver(Channel<CooperateEvent>::Sender sender,
690     const EnableCooperateEvent &event)
691 {
692     CALL_INFO_TRACE;
693     auto bundleName = GetPackageName(event.tokenId);
694     clientBundleNames_.push_back(bundleName);
695     FI_HILOGI("Register application %{public}s state observer", bundleName.c_str());
696     auto appMgr = GetAppMgr();
697     CHKPR(appMgr, RET_ERR);
698     appStateObserver_ = sptr<AppStateObserver>::MakeSptr(sender, event.pid);
699     auto err = appMgr->RegisterApplicationStateObserver(appStateObserver_, clientBundleNames_);
700     if (err != RET_OK) {
701         appStateObserver_.clear();
702         FI_HILOGE("IAppMgr::RegisterApplicationStateObserver fail, error:%{public}d", err);
703         return RET_ERR;
704     }
705     return RET_OK;
706 }
707 
UnregisterApplicationStateObserver()708 void StateMachine::UnregisterApplicationStateObserver()
709 {
710     CALL_INFO_TRACE;
711     CHKPV(appStateObserver_);
712     auto appMgr = GetAppMgr();
713     CHKPV(appMgr);
714     FI_HILOGI("Unregister application associateassistant state observer");
715     auto err = appMgr->UnregisterApplicationStateObserver(appStateObserver_);
716     if (err != RET_OK) {
717         FI_HILOGE("IAppMgr::UnregisterApplicationStateObserver fail, error:%{public}d", err);
718     }
719     appStateObserver_.clear();
720 }
721 
UpdateApplicationStateObserver(int32_t clientPid)722 void StateMachine::UpdateApplicationStateObserver(int32_t clientPid)
723 {
724     CALL_INFO_TRACE;
725     CHKPV(appStateObserver_);
726     appStateObserver_->UpdateClientPid(clientPid);
727 }
728 
AddSessionObserver(Context & context,const EnableCooperateEvent & event)729 void StateMachine::AddSessionObserver(Context &context, const EnableCooperateEvent &event)
730 {
731     CALL_INFO_TRACE;
732     RegisterApplicationStateObserver(context.Sender(), event);
733 }
734 
GetPackageName(Security::AccessToken::AccessTokenID tokenId)735 std::string StateMachine::GetPackageName(Security::AccessToken::AccessTokenID tokenId)
736 {
737     CALL_INFO_TRACE;
738     std::string bundleName {"Default"};
739     int32_t tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
740     switch (tokenType) {
741         case Security::AccessToken::ATokenTypeEnum::TOKEN_HAP: {
742             Security::AccessToken::HapTokenInfo hapInfo;
743             if (Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo) != RET_OK) {
744                 FI_HILOGE("Get hap token info failed");
745             } else {
746                 bundleName = hapInfo.bundleName;
747             }
748             break;
749         }
750         case Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE:
751         case Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL: {
752             Security::AccessToken::NativeTokenInfo tokenInfo;
753             if (Security::AccessToken::AccessTokenKit::GetNativeTokenInfo(tokenId, tokenInfo) != RET_OK) {
754                 FI_HILOGE("Get native token info failed");
755             } else {
756                 bundleName = tokenInfo.processName;
757             }
758             break;
759         }
760         default: {
761             FI_HILOGW("token type not match");
762             break;
763         }
764     }
765     return bundleName;
766 }
767 
RemoveSessionObserver(Context & context,const DisableCooperateEvent & event)768 void StateMachine::RemoveSessionObserver(Context &context, const DisableCooperateEvent &event)
769 {
770     UnregisterApplicationStateObserver();
771 }
772 
OnCommonEvent(Context & context,const std::string & commonEvent)773 void StateMachine::OnCommonEvent(Context &context, const std::string &commonEvent)
774 {
775     FI_HILOGD("Current common event:%{public}s", commonEvent.c_str());
776     CHKPV(env_);
777     if (commonEvent == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON ||
778         commonEvent == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED) {
779         if ((screenEventTimer_ >= 0) && (env_->GetTimerManager().IsExist(screenEventTimer_))) {
780             env_->GetTimerManager().RemoveTimer(screenEventTimer_);
781             screenEventTimer_ = -1;
782         }
783     }
784     if (commonEvent == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF ||
785         commonEvent == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_LOCKED) {
786         FI_HILOGD("Receive common event:%{public}s, stop cooperate", commonEvent.c_str());
787         auto ret = context.Sender().Send(CooperateEvent(
788             CooperateEventType::STOP,
789             StopCooperateEvent{
790                 .isUnchained = false
791             }));
792         if (ret != Channel<CooperateEvent>::NO_ERROR) {
793             FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
794         }
795         screenEventTimer_ = env_->GetTimerManager().AddTimer(SCREEN_LOCKED_TIMEOUT, REPEAT_ONCE,
796             [sender = context.Sender(), this]() mutable {
797                 auto res = sender.Send(CooperateEvent(
798                     CooperateEventType::STOP,
799                     StopCooperateEvent{
800                         .isUnchained = true
801                     }));
802                 if (res != Channel<CooperateEvent>::NO_ERROR) {
803                     FI_HILOGE("Failed to send event via channel, error:%{public}d", res);
804                 }
805                 screenEventTimer_ = -1;
806             });
807     }
808 }
809 
AddMonitor(Context & context)810 void StateMachine::AddMonitor(Context &context)
811 {
812     CALL_INFO_TRACE;
813     if (monitorId_ >= 0) {
814         return;
815     }
816     CHKPV(env_);
817     monitorId_ = env_->GetInput().AddMonitor([&context, this] (
818             std::shared_ptr<MMI::PointerEvent> pointerEvent) mutable {
819             context.hotArea_.ProcessData(pointerEvent);
820             context.mouseLocation_.ProcessData(pointerEvent);
821 
822             MMI::PointerEvent::PointerItem pointerItem;
823             if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
824                 FI_HILOGE("Corrupted pointer event");
825                 return;
826             }
827             auto pointerAction = pointerEvent->GetPointerAction();
828             auto sourceType = pointerEvent->GetSourceType();
829             if (pointerEvent->HasFlag(MMI::InputEvent::EVENT_FLAG_SIMULATE) &&
830                 (pointerAction == MMI::PointerEvent::POINTER_ACTION_PULL_IN_WINDOW ||
831                 pointerAction == MMI::PointerEvent::POINTER_ACTION_PULL_OUT_WINDOW)) {
832                 FI_HILOGW("PointerAction:%{public}d is simulated, skip", pointerAction);
833                 return;
834             }
835             auto ret = context.Sender().Send(CooperateEvent(
836                 CooperateEventType::INPUT_POINTER_EVENT,
837                 InputPointerEvent {
838                     .deviceId = pointerEvent->GetDeviceId(),
839                     .pointerAction = pointerAction,
840                     .sourceType = sourceType,
841                     .position = Coordinate {
842                         .x = pointerItem.GetDisplayX(),
843                         .y = pointerItem.GetDisplayY(),
844                     },
845                     .currentDisplayId = pointerEvent->GetTargetDisplayId()
846                 }));
847             if (ret != Channel<CooperateEvent>::NO_ERROR) {
848                 FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
849             }
850         }, nullptr, MMI::HANDLE_EVENT_TYPE_MOUSE);
851     if (monitorId_ < 0) {
852         FI_HILOGE("MMI::Add Monitor fail");
853     }
854 }
855 
AddPreMonitor(Context & context)856 void StateMachine::AddPreMonitor(Context &context)
857 {
858     CALL_INFO_TRACE;
859     if (preMonitorId_ >= 0) {
860         return;
861     }
862     CHKPV(env_);
863     std::vector<int32_t> keys;
864     keys.push_back(MMI::KeyEvent::KEYCODE_KEY_PEN_AIR_MOUSE);
865     preMonitorId_ = env_->GetInput().AddPreMonitor(nullptr, [&context, this]
866         (std::shared_ptr<MMI::KeyEvent> keyEvent) mutable {
867             CHKPV(keyEvent);
868             if (keyEvent->GetKeyCode() == MMI::KeyEvent::KEYCODE_KEY_PEN_AIR_MOUSE) {
869                 if (keyEvent->GetKeyAction() == MMI::KeyEvent::KEY_ACTION_DOWN) {
870                     FI_HILOGI("Air mouse key down");
871                     env_->GetDeviceManager().SetPencilAirMouse(true);
872                 } else {
873                     FI_HILOGI("Air mouse key up or cancel or unknow");
874                     env_->GetDeviceManager().SetPencilAirMouse(false);
875                 }
876             }
877         }, MMI::HANDLE_EVENT_TYPE_PRE_KEY, keys);
878     if (preMonitorId_ < 0) {
879         FI_HILOGE("MMI::Add Monitor fail");
880     }
881 }
882 
RemoveMonitor(Context & context)883 void StateMachine::RemoveMonitor(Context &context)
884 {
885     CALL_INFO_TRACE;
886     CHKPV(env_);
887     if (monitorId_ < 0) {
888         return;
889     }
890     env_->GetInput().RemoveMonitor(monitorId_);
891     monitorId_ = -1;
892 }
893 
RemovePreMonitor(Context & context)894 void StateMachine::RemovePreMonitor(Context &context)
895 {
896     CALL_INFO_TRACE;
897     CHKPV(env_);
898     if (preMonitorId_ < 0) {
899         return;
900     }
901     env_->GetInput().RemovePreMonitor(preMonitorId_);
902     preMonitorId_ = -1;
903 }
904 
RemoveWatches(Context & context)905 void StateMachine::RemoveWatches(Context &context)
906 {
907     CALL_INFO_TRACE;
908     for (auto iter = onlineBoards_.begin();
909          iter != onlineBoards_.end(); iter = onlineBoards_.begin()) {
910         FI_HILOGD("Remove watch \'%{public}s\'", Utility::Anonymize(*iter).c_str());
911         onlineBoards_.erase(iter);
912     }
913 }
IsCooperateEnable()914 bool StateMachine::IsCooperateEnable()
915 {
916     return isCooperateEnable_;
917 }
918 
ResetCooperate(Context & context)919 void StateMachine::ResetCooperate(Context &context)
920 {
921     CALL_INFO_TRACE;
922     auto ret = context.Sender().Send(CooperateEvent(
923         CooperateEventType::STOP_ABOUT_VIRTUALTRACKPAD,
924         StopCooperateEvent {}));
925     if (ret != Channel<CooperateEvent>::NO_ERROR) {
926         FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
927     }
928 }
929 
CheckIsVirtualTrackpad(int32_t deviceId)930 bool StateMachine::CheckIsVirtualTrackpad(int32_t deviceId)
931 {
932     CALL_INFO_TRACE;
933     bool isLocalPointerDevice = false;
934     MMI::InputManager::GetInstance()->GetDevice(deviceId, [&isLocalPointerDevice, this] (
935         std::shared_ptr<MMI::InputDevice> device) -> bool {
936             CHKPR(device, false);
937             if (device->GetName() == VIRTUAL_TRACK_PAD_NAME) {
938                 isLocalPointerDevice = true;
939                 FI_HILOGI("Has virtualTrackpad");
940                 return isLocalPointerDevice;
941             }
942             return isLocalPointerDevice;
943         });
944     return isLocalPointerDevice;
945 }
946 
947 } // namespace Cooperate
948 } // namespace DeviceStatus
949 } // namespace Msdp
950 } // namespace OHOS
951