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