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