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