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