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