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