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 #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("Report to handler");
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::REGISTER_EVENT_LISTENER,
104         [this](Context &context, const CooperateEvent &event) {
105             this->RegisterEventListener(context, event);
106     });
107     AddHandler(CooperateEventType::UNREGISTER_EVENT_LISTENER,
108         [this](Context &context, const CooperateEvent &event) {
109             this->UnregisterEventListener(context, event);
110     });
111     AddHandler(CooperateEventType::DDM_BOARD_ONLINE,
112         [this](Context &context, const CooperateEvent &event) {
113             this->OnBoardOnline(context, event);
114     });
115     AddHandler(CooperateEventType::DDM_BOARD_OFFLINE,
116         [this](Context &context, const CooperateEvent &event) {
117             this->OnBoardOffline(context, event);
118     });
119     AddHandler(CooperateEventType::DDP_COOPERATE_SWITCH_CHANGED,
120         [this](Context &context, const CooperateEvent &event) {
121             this->OnProfileChanged(context, event);
122     });
123     AddHandler(CooperateEventType::INPUT_POINTER_EVENT,
124         [this](Context &context, const CooperateEvent &event) {
125             this->OnPointerEvent(context, event);
126     });
127     AddHandler(CooperateEventType::APP_CLOSED, [this](Context &context, const CooperateEvent &event) {
128         this->OnProcessClientDied(context, event);
129     });
130     AddHandler(CooperateEventType::DSOFTBUS_SESSION_OPENED,
131         [this](Context &context, const CooperateEvent &event) {
132             this->OnSoftbusSessionOpened(context, event);
133     });
134     AddHandler(CooperateEventType::DSOFTBUS_SESSION_CLOSED,
135         [this](Context &context, const CooperateEvent &event) {
136             this->OnSoftbusSessionClosed(context, event);
137     });
138     AddHandler(CooperateEventType::DSOFTBUS_SUBSCRIBE_MOUSE_LOCATION,
139         [this](Context &context, const CooperateEvent &event) {
140             this->OnSoftbusSubscribeMouseLocation(context, event);
141     });
142     AddHandler(CooperateEventType::DSOFTBUS_UNSUBSCRIBE_MOUSE_LOCATION,
143         [this](Context &context, const CooperateEvent &event) {
144             this->OnSoftbusUnSubscribeMouseLocation(context, event);
145     });
146     AddHandler(CooperateEventType::DSOFTBUS_REPLY_SUBSCRIBE_MOUSE_LOCATION,
147         [this](Context &context, const CooperateEvent &event) {
148             this->OnSoftbusReplySubscribeMouseLocation(context, event);
149     });
150     AddHandler(CooperateEventType::DSOFTBUS_REPLY_UNSUBSCRIBE_MOUSE_LOCATION,
151         [this](Context &context, const CooperateEvent &event) {
152             this->OnSoftbusReplyUnSubscribeMouseLocation(context, event);
153     });
154     AddHandler(CooperateEventType::DSOFTBUS_MOUSE_LOCATION,
155         [this](Context &context, const CooperateEvent &event) {
156             this->OnSoftbusMouseLocation(context, event);
157     });
158     AddHandler(CooperateEventType::DSOFTBUS_START_COOPERATE,
159         [this](Context &context, const CooperateEvent &event) {
160             this->OnRemoteStart(context, event);
161     });
162     AddHandler(CooperateEventType::INPUT_HOTPLUG_EVENT,
163         [this](Context &context, const CooperateEvent &event) {
164             this->OnHotPlugEvent(context, event);
165     });
166     AddHandler(CooperateEventType::DSOFTBUS_INPUT_DEV_HOT_PLUG,
167         [this](Context &context, const CooperateEvent &event) {
168             this->OnRemoteHotPlug(context, event);
169     });
170     AddHandler(CooperateEventType::DSOFTBUS_INPUT_DEV_SYNC,
171         [this](Context &context, const CooperateEvent &event) {
172             this->OnRemoteInputDevice(context, event);
173     });
174     AddHandler(CooperateEventType::STOP, [this](Context &context, const CooperateEvent &event) {
175         this->StopCooperate(context, event);
176     });
177 }
178 
OnEvent(Context &context, const CooperateEvent &event)179 void StateMachine::OnEvent(Context &context, const CooperateEvent &event)
180 {
181     if (auto iter = handlers_.find(event.type); iter != handlers_.end()) {
182         iter->second(context, event);
183     } else {
184         Transfer(context, event);
185     }
186 }
187 
TransiteTo(Context &context, CooperateState state)188 void StateMachine::TransiteTo(Context &context, CooperateState state)
189 {
190     if ((state >= COOPERATE_STATE_FREE) &&
191         (state < N_COOPERATE_STATES) &&
192         (state != current_)) {
193         states_[current_]->OnLeaveState(context);
194         current_ = state;
195         states_[current_]->OnEnterState(context);
196         auto curState = static_cast<OHOS::Msdp::DeviceStatus::CooperateState>(state);
197         CooperateDFX::WriteCooperateState(curState);
198     }
199 }
200 
AddHandler(CooperateEventType event, std::function<void(Context&, const CooperateEvent&)> handler)201 void StateMachine::AddHandler(CooperateEventType event, std::function<void(Context&, const CooperateEvent&)> handler)
202 {
203     handlers_.emplace(event, handler);
204 }
205 
OnQuit(Context &context)206 void StateMachine::OnQuit(Context &context)
207 {
208     CALL_DEBUG_ENTER;
209     RemoveWatches(context);
210     RemoveMonitor(context);
211 }
212 
AddObserver(Context &context, const CooperateEvent &event)213 void StateMachine::AddObserver(Context &context, const CooperateEvent &event)
214 {
215     AddObserverEvent notice = std::get<AddObserverEvent>(event.event);
216     context.AddObserver(notice.observer);
217 }
218 
RemoveObserver(Context &context, const CooperateEvent &event)219 void StateMachine::RemoveObserver(Context &context, const CooperateEvent &event)
220 {
221     RemoveObserverEvent notice = std::get<RemoveObserverEvent>(event.event);
222     context.RemoveObserver(notice.observer);
223 }
224 
RegisterListener(Context &context, const CooperateEvent &event)225 void StateMachine::RegisterListener(Context &context, const CooperateEvent &event)
226 {
227     RegisterListenerEvent notice = std::get<RegisterListenerEvent>(event.event);
228     context.eventMgr_.RegisterListener(notice);
229 }
230 
UnregisterListener(Context &context, const CooperateEvent &event)231 void StateMachine::UnregisterListener(Context &context, const CooperateEvent &event)
232 {
233     UnregisterListenerEvent notice = std::get<UnregisterListenerEvent>(event.event);
234     context.eventMgr_.UnregisterListener(notice);
235 }
236 
RegisterHotAreaListener(Context &context, const CooperateEvent &event)237 void StateMachine::RegisterHotAreaListener(Context &context, const CooperateEvent &event)
238 {
239     RegisterHotareaListenerEvent notice = std::get<RegisterHotareaListenerEvent>(event.event);
240     context.hotArea_.AddListener(notice);
241 }
242 
UnregisterHotAreaListener(Context &context, const CooperateEvent &event)243 void StateMachine::UnregisterHotAreaListener(Context &context, const CooperateEvent &event)
244 {
245     UnregisterHotareaListenerEvent notice = std::get<UnregisterHotareaListenerEvent>(event.event);
246     context.hotArea_.RemoveListener(notice);
247 }
248 
EnableCooperate(Context &context, const CooperateEvent &event)249 void StateMachine::EnableCooperate(Context &context, const CooperateEvent &event)
250 {
251     CALL_INFO_TRACE;
252     EnableCooperateEvent enableEvent = std::get<EnableCooperateEvent>(event.event);
253     context.EnableCooperate(enableEvent);
254     context.eventMgr_.EnableCooperate(enableEvent);
255     context.hotArea_.EnableCooperate(enableEvent);
256     observer_ = CommonEventObserver::CreateCommonEventObserver(
257         [&context, this] (const std::string &commonEvent) {
258             OnCommonEvent(context, commonEvent);
259         }
260     );
261     context.commonEvent_.AddObserver(observer_);
262     AddSessionObserver(context, enableEvent);
263     AddMonitor(context);
264     Transfer(context, event);
265 }
266 
DisableCooperate(Context &context, const CooperateEvent &event)267 void StateMachine::DisableCooperate(Context &context, const CooperateEvent &event)
268 {
269     CALL_INFO_TRACE;
270     DisableCooperateEvent disableEvent = std::get<DisableCooperateEvent>(event.event);
271     context.DisableCooperate(disableEvent);
272     context.eventMgr_.DisableCooperate(disableEvent);
273     context.commonEvent_.RemoveObserver(observer_);
274     RemoveSessionObserver(context, disableEvent);
275     RemoveMonitor(context);
276     Transfer(context, event);
277 }
278 
StartCooperate(Context &context, const CooperateEvent &event)279 void StateMachine::StartCooperate(Context &context, const CooperateEvent &event)
280 {
281     CALL_INFO_TRACE;
282     StartCooperateEvent startEvent = std::get<StartCooperateEvent>(event.event);
283     if (!context.ddm_.CheckSameAccountToLocal(startEvent.remoteNetworkId)) {
284         FI_HILOGE("CheckSameAccountToLocal failed");
285         startEvent.errCode->set_value(COMMON_PERMISSION_CHECK_ERROR);
286         return;
287     }
288     UpdateApplicationStateObserver(startEvent.pid);
289     if (!context.IsAllowCooperate()) {
290         FI_HILOGI("Not allow cooperate");
291         startEvent.errCode->set_value(COMMON_NOT_ALLOWED_DISTRIBUTED);
292         return;
293     }
294     startEvent.errCode->set_value(RET_OK);
295     Transfer(context, event);
296 }
297 
StopCooperate(Context &context, const CooperateEvent &event)298 void StateMachine::StopCooperate(Context &context, const CooperateEvent &event)
299 {
300     CALL_INFO_TRACE;
301     context.CloseDistributedFileConnection(context.Peer());
302     Transfer(context, event);
303 }
304 
GetCooperateState(Context &context, const CooperateEvent &event)305 void StateMachine::GetCooperateState(Context &context, const CooperateEvent &event)
306 {
307     CALL_INFO_TRACE;
308     GetCooperateStateEvent stateEvent = std::get<GetCooperateStateEvent>(event.event);
309     UpdateApplicationStateObserver(stateEvent.pid);
310     bool switchStatus { false };
311     EventManager::CooperateStateNotice notice {
312         .pid = stateEvent.pid,
313         .msgId = MessageId::COORDINATION_GET_STATE,
314         .userData = stateEvent.userData,
315         .state = switchStatus,
316     };
317     context.eventMgr_.GetCooperateState(notice);
318 }
319 
OnProcessClientDied(Context &context, const CooperateEvent &event)320 void StateMachine::OnProcessClientDied(Context &context, const CooperateEvent &event)
321 {
322     CALL_INFO_TRACE;
323     ClientDiedEvent notice = std::get<ClientDiedEvent>(event.event);
324     context.eventMgr_.OnClientDied(notice);
325     context.hotArea_.OnClientDied(notice);
326     context.mouseLocation_.OnClientDied(notice);
327     Transfer(context, event);
328 }
329 
RegisterEventListener(Context &context, const CooperateEvent &event)330 void StateMachine::RegisterEventListener(Context &context, const CooperateEvent &event)
331 {
332     RegisterEventListenerEvent notice = std::get<RegisterEventListenerEvent>(event.event);
333     context.mouseLocation_.AddListener(notice);
334 }
335 
UnregisterEventListener(Context &context, const CooperateEvent &event)336 void StateMachine::UnregisterEventListener(Context &context, const CooperateEvent &event)
337 {
338     UnregisterEventListenerEvent notice = std::get<UnregisterEventListenerEvent>(event.event);
339     context.mouseLocation_.RemoveListener(notice);
340 }
341 
OnBoardOnline(Context &context, const CooperateEvent &event)342 void StateMachine::OnBoardOnline(Context &context, const CooperateEvent &event)
343 {
344     CALL_INFO_TRACE;
345     DDMBoardOnlineEvent onlineEvent = std::get<DDMBoardOnlineEvent>(event.event);
346 
347     auto ret = onlineBoards_.insert(onlineEvent.networkId);
348     if (ret.second) {
349         FI_HILOGD("Watch \'%{public}s\'", Utility::Anonymize(onlineEvent.networkId).c_str());
350         Transfer(context, event);
351     }
352 }
353 
OnBoardOffline(Context &context, const CooperateEvent &event)354 void StateMachine::OnBoardOffline(Context &context, const CooperateEvent &event)
355 {
356     CALL_INFO_TRACE;
357     DDMBoardOfflineEvent offlineEvent = std::get<DDMBoardOfflineEvent>(event.event);
358 
359     if (auto iter = onlineBoards_.find(offlineEvent.networkId); iter != onlineBoards_.end()) {
360         onlineBoards_.erase(iter);
361         FI_HILOGD("Remove watch \'%{public}s\'", Utility::Anonymize(offlineEvent.networkId).c_str());
362         context.CloseDistributedFileConnection(offlineEvent.networkId);
363         Transfer(context, event);
364     }
365 }
366 
OnProfileChanged(Context &context, const CooperateEvent &event)367 void StateMachine::OnProfileChanged(Context &context, const CooperateEvent &event)
368 {
369     CALL_INFO_TRACE;
370     DDPCooperateSwitchChanged notice = std::get<DDPCooperateSwitchChanged>(event.event);
371     context.eventMgr_.OnProfileChanged(notice);
372     Transfer(context, event);
373 }
374 
OnPointerEvent(Context &context, const CooperateEvent &event)375 void StateMachine::OnPointerEvent(Context &context, const CooperateEvent &event)
376 {
377     CALL_DEBUG_ENTER;
378     InputPointerEvent pointerEvent = std::get<InputPointerEvent>(event.event);
379     Coordinate cursorPos = context.CursorPosition();
380     context.OnPointerEvent(pointerEvent);
381     pointerEvent.position = cursorPos;
382     Transfer(context, CooperateEvent { CooperateEventType::INPUT_POINTER_EVENT, pointerEvent });
383 }
384 
OnSoftbusSessionClosed(Context &context, const CooperateEvent &event)385 void StateMachine::OnSoftbusSessionClosed(Context &context, const CooperateEvent &event)
386 {
387     CALL_INFO_TRACE;
388     DSoftbusSessionClosed notice = std::get<DSoftbusSessionClosed>(event.event);
389     context.eventMgr_.OnSoftbusSessionClosed(notice);
390     context.inputDevMgr_.OnSoftbusSessionClosed(notice);
391     context.CloseDistributedFileConnection(notice.networkId);
392     Transfer(context, event);
393 }
394 
OnSoftbusSessionOpened(Context &context, const CooperateEvent &event)395 void StateMachine::OnSoftbusSessionOpened(Context &context, const CooperateEvent &event)
396 {
397     CALL_INFO_TRACE;
398     DSoftbusSessionOpened notice = std::get<DSoftbusSessionOpened>(event.event);
399     context.inputDevMgr_.OnSoftbusSessionOpened(notice);
400     Transfer(context, event);
401 }
402 
OnHotPlugEvent(Context &context, const CooperateEvent &event)403 void StateMachine::OnHotPlugEvent(Context &context, const CooperateEvent &event)
404 {
405     CALL_INFO_TRACE;
406     InputHotplugEvent notice = std::get<InputHotplugEvent>(event.event);
407     context.inputDevMgr_.OnLocalHotPlug(notice);
408     Transfer(context, event);
409 }
410 
OnRemoteInputDevice(Context &context, const CooperateEvent &event)411 void StateMachine::OnRemoteInputDevice(Context &context, const CooperateEvent &event)
412 {
413     CALL_INFO_TRACE;
414     DSoftbusSyncInputDevice notice = std::get<DSoftbusSyncInputDevice>(event.event);
415     context.inputDevMgr_.OnRemoteInputDevice(notice);
416     Transfer(context, event);
417 }
418 
OnRemoteHotPlug(Context &context, const CooperateEvent &event)419 void StateMachine::OnRemoteHotPlug(Context &context, const CooperateEvent &event)
420 {
421     CALL_INFO_TRACE;
422     DSoftbusHotPlugEvent notice = std::get<DSoftbusHotPlugEvent>(event.event);
423     context.inputDevMgr_.OnRemoteHotPlug(notice);
424     Transfer(context, event);
425 }
426 
OnSoftbusSubscribeMouseLocation(Context &context, const CooperateEvent &event)427 void StateMachine::OnSoftbusSubscribeMouseLocation(Context &context, const CooperateEvent &event)
428 {
429     CALL_INFO_TRACE;
430     DSoftbusSubscribeMouseLocation notice = std::get<DSoftbusSubscribeMouseLocation>(event.event);
431     context.mouseLocation_.OnSubscribeMouseLocation(notice);
432 }
433 
OnSoftbusUnSubscribeMouseLocation(Context &context, const CooperateEvent &event)434 void StateMachine::OnSoftbusUnSubscribeMouseLocation(Context &context, const CooperateEvent &event)
435 {
436     CALL_INFO_TRACE;
437     DSoftbusUnSubscribeMouseLocation notice = std::get<DSoftbusUnSubscribeMouseLocation>(event.event);
438     context.mouseLocation_.OnUnSubscribeMouseLocation(notice);
439 }
440 
OnSoftbusReplySubscribeMouseLocation(Context &context, const CooperateEvent &event)441 void StateMachine::OnSoftbusReplySubscribeMouseLocation(Context &context, const CooperateEvent &event)
442 {
443     CALL_INFO_TRACE;
444     DSoftbusReplySubscribeMouseLocation notice = std::get<DSoftbusReplySubscribeMouseLocation>(event.event);
445     context.mouseLocation_.OnReplySubscribeMouseLocation(notice);
446 }
447 
OnSoftbusReplyUnSubscribeMouseLocation(Context &context, const CooperateEvent &event)448 void StateMachine::OnSoftbusReplyUnSubscribeMouseLocation(Context &context, const CooperateEvent &event)
449 {
450     CALL_INFO_TRACE;
451     DSoftbusReplyUnSubscribeMouseLocation notice = std::get<DSoftbusReplyUnSubscribeMouseLocation>(event.event);
452     context.mouseLocation_.OnReplyUnSubscribeMouseLocation(notice);
453 }
454 
OnSoftbusMouseLocation(Context &context, const CooperateEvent &event)455 void StateMachine::OnSoftbusMouseLocation(Context &context, const CooperateEvent &event)
456 {
457     CALL_DEBUG_ENTER;
458     DSoftbusSyncMouseLocation notice = std::get<DSoftbusSyncMouseLocation>(event.event);
459     context.mouseLocation_.OnRemoteMouseLocation(notice);
460 }
461 
OnRemoteStart(Context &context, const CooperateEvent &event)462 void StateMachine::OnRemoteStart(Context &context, const CooperateEvent &event)
463 {
464     DSoftbusStartCooperate startEvent = std::get<DSoftbusStartCooperate>(event.event);
465     if (!context.ddm_.CheckSameAccountToLocal(startEvent.originNetworkId)) {
466         FI_HILOGE("CheckSameAccountToLocal failed, unchain link");
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     CALL_INFO_TRACE;
581     FI_HILOGI("Current common event:%{public}s", commonEvent.c_str());
582     if (commonEvent == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_OFF ||
583         commonEvent == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_LOCKED) {
584         FI_HILOGI("Receive common event:%{public}s, stop cooperate", commonEvent.c_str());
585         CooperateEvent stopEvent(
586             CooperateEventType::STOP,
587             StopCooperateEvent{
588                 .isUnchained = false
589             }
590         );
591         Transfer(context, stopEvent);
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(
603         [sender = context.Sender(), &hotArea = context.hotArea_, &mouseLocation = context.mouseLocation_] (
604             std::shared_ptr<MMI::PointerEvent> pointerEvent) mutable {
605             hotArea.ProcessData(pointerEvent);
606             mouseLocation.ProcessData(pointerEvent);
607 
608             MMI::PointerEvent::PointerItem pointerItem;
609             if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
610                 FI_HILOGE("Corrupted pointer event");
611                 return;
612             }
613             auto ret = sender.Send(CooperateEvent(
614                 CooperateEventType::INPUT_POINTER_EVENT,
615                 InputPointerEvent {
616                     .deviceId = pointerEvent->GetDeviceId(),
617                     .pointerAction = pointerEvent->GetPointerAction(),
618                     .sourceType = pointerEvent->GetSourceType(),
619                     .position = Coordinate {
620                         .x = pointerItem.GetDisplayX(),
621                         .y = pointerItem.GetDisplayY(),
622                     }
623                 }));
624             if (ret != Channel<CooperateEvent>::NO_ERROR) {
625                 FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
626             }
627         });
628     if (monitorId_ < 0) {
629         FI_HILOGE("MMI::Add Monitor fail");
630     }
631 }
632 
RemoveMonitor(Context &context)633 void StateMachine::RemoveMonitor(Context &context)
634 {
635     CALL_INFO_TRACE;
636     if (monitorId_ < 0) {
637         return;
638     }
639     env_->GetInput().RemoveMonitor(monitorId_);
640     monitorId_ = -1;
641 }
642 
RemoveWatches(Context &context)643 void StateMachine::RemoveWatches(Context &context)
644 {
645     CALL_INFO_TRACE;
646     for (auto iter = onlineBoards_.begin();
647          iter != onlineBoards_.end(); iter = onlineBoards_.begin()) {
648         FI_HILOGD("Remove watch \'%{public}s\'", Utility::Anonymize(*iter).c_str());
649         onlineBoards_.erase(iter);
650     }
651 }
652 } // namespace Cooperate
653 } // namespace DeviceStatus
654 } // namespace Msdp
655 } // namespace OHOS
656