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