• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "cooperate_out.h"
17 
18 #include "devicestatus_define.h"
19 #include "utility.h"
20 
21 #undef LOG_TAG
22 #define LOG_TAG "CooperateOut"
23 
24 namespace OHOS {
25 namespace Msdp {
26 namespace DeviceStatus {
27 namespace Cooperate {
28 
CooperateOut(IStateMachine & parent,IContext * env)29 CooperateOut::CooperateOut(IStateMachine &parent, IContext *env) : ICooperateState(parent), env_(env)
30 {
31     initial_ = std::make_shared<Initial>(*this);
32     Initial::BuildChains(initial_, *this);
33     current_ = initial_;
34 }
35 
~CooperateOut()36 CooperateOut::~CooperateOut()
37 {
38     CHKPV(initial_);
39     Initial::RemoveChains(initial_);
40 }
41 
OnEvent(Context & context,const CooperateEvent & event)42 void CooperateOut::OnEvent(Context &context, const CooperateEvent &event)
43 {
44     current_->OnEvent(context, event);
45 }
46 
OnEnterState(Context & context)47 void CooperateOut::OnEnterState(Context &context)
48 {
49     CALL_INFO_TRACE;
50     env_->GetInput().SetPointerVisibility(false);
51 }
52 
OnLeaveState(Context & context)53 void CooperateOut::OnLeaveState(Context &context)
54 {
55     CALL_INFO_TRACE;
56     SetPointerVisible(context);
57 }
58 
SetPointerVisible(Context & context)59 void CooperateOut::SetPointerVisible(Context &context)
60 {
61     CHKPV(env_);
62     bool hasLocalPointerDevice = env_->GetDeviceManager().HasLocalPointerDevice();
63     bool visible = !context.NeedHideCursor() && hasLocalPointerDevice;
64     FI_HILOGI("Set pointer visible:%{public}s, HasLocalPointerDevice:%{public}s", visible ? "true" : "false",
65         hasLocalPointerDevice ? "true" : "false");
66     env_->GetInput().SetPointerVisibility(visible, PRIORITY);
67 }
68 
OnSetCooperatePriv(uint32_t priv)69 void CooperateOut::OnSetCooperatePriv(uint32_t priv)
70 {
71     CALL_DEBUG_ENTER;
72     env_->GetDragManager().SetCooperatePriv(priv);
73 }
74 
BuildChains(std::shared_ptr<Initial> self,CooperateOut & parent)75 void CooperateOut::Initial::BuildChains(std::shared_ptr<Initial> self, CooperateOut &parent) { }
76 
RemoveChains(std::shared_ptr<Initial> self)77 void CooperateOut::Initial::RemoveChains(std::shared_ptr<Initial> self) { }
78 
Initial(CooperateOut & parent)79 CooperateOut::Initial::Initial(CooperateOut &parent) : ICooperateStep(parent, nullptr), parent_(parent)
80 {
81     AddHandler(CooperateEventType::DISABLE, [this](Context &context, const CooperateEvent &event) {
82         this->OnDisable(context, event);
83     });
84     AddHandler(CooperateEventType::START, [this](Context &context, const CooperateEvent &event) {
85         this->OnStart(context, event);
86     });
87     AddHandler(CooperateEventType::STOP, [this](Context &context, const CooperateEvent &event) {
88         this->OnStop(context, event);
89     });
90     AddHandler(CooperateEventType::APP_CLOSED, [this](Context &context, const CooperateEvent &event) {
91         this->OnAppClosed(context, event);
92     });
93     AddHandler(CooperateEventType::INPUT_HOTPLUG_EVENT, [this](Context &context, const CooperateEvent &event) {
94         this->OnHotplug(context, event);
95     });
96     AddHandler(CooperateEventType::INPUT_POINTER_EVENT, [this](Context &context, const CooperateEvent &event) {
97         this->OnPointerEvent(context, event);
98     });
99     AddHandler(CooperateEventType::DDM_BOARD_OFFLINE, [this](Context &context, const CooperateEvent &event) {
100         this->OnBoardOffline(context, event);
101     });
102     AddHandler(CooperateEventType::DDP_COOPERATE_SWITCH_CHANGED, [this](Context &context, const CooperateEvent &event) {
103         this->OnSwitchChanged(context, event);
104     });
105     AddHandler(CooperateEventType::DSOFTBUS_SESSION_CLOSED, [this](Context &context, const CooperateEvent &event) {
106         this->OnSoftbusSessionClosed(context, event);
107     });
108     AddHandler(CooperateEventType::DSOFTBUS_COME_BACK, [this](Context &context, const CooperateEvent &event) {
109         this->OnComeBack(context, event);
110     });
111     AddHandler(CooperateEventType::DSOFTBUS_START_COOPERATE, [this](Context &context, const CooperateEvent &event) {
112         this->OnRemoteStart(context, event);
113     });
114     AddHandler(CooperateEventType::DSOFTBUS_STOP_COOPERATE, [this](Context &context, const CooperateEvent &event) {
115         this->OnRemoteStop(context, event);
116     });
117     AddHandler(CooperateEventType::DSOFTBUS_RELAY_COOPERATE, [this](Context &context, const CooperateEvent &event) {
118         this->OnRelay(context, event);
119     });
120 }
121 
OnDisable(Context & context,const CooperateEvent & event)122 void CooperateOut::Initial::OnDisable(Context &context, const CooperateEvent &event)
123 {
124     FI_HILOGI("[disable cooperation] Stop cooperation");
125     parent_.StopCooperate(context, event);
126 }
127 
OnStart(Context & context,const CooperateEvent & event)128 void CooperateOut::Initial::OnStart(Context &context, const CooperateEvent &event)
129 {
130     StartCooperateEvent param = std::get<StartCooperateEvent>(event.event);
131 
132     context.eventMgr_.StartCooperate(param);
133     FI_HILOGI("[start] Start cooperation with \'%{public}s\', report success when out",
134         Utility::Anonymize(context.Peer()).c_str());
135     DSoftbusStartCooperateFinished failNotice { .success = false,
136         .errCode = static_cast<int32_t>(CoordinationErrCode::UNEXPECTED_START_CALL) };
137     context.eventMgr_.StartCooperateFinish(failNotice);
138 }
139 
OnStop(Context & context,const CooperateEvent & event)140 void CooperateOut::Initial::OnStop(Context &context, const CooperateEvent &event)
141 {
142     StopCooperateEvent param = std::get<StopCooperateEvent>(event.event);
143 
144     context.eventMgr_.StopCooperate(param);
145     FI_HILOGI("[stop] Stop cooperation with \'%{public}s\', unchain:%{public}d",
146         Utility::Anonymize(context.Peer()).c_str(), param.isUnchained);
147     parent_.StopCooperate(context, event);
148 
149     DSoftbusStopCooperateFinished notice {
150         .normal = true,
151     };
152     context.eventMgr_.StopCooperateFinish(notice);
153 
154     parent_.UnchainConnections(context, param);
155 }
156 
OnComeBack(Context & context,const CooperateEvent & event)157 void CooperateOut::Initial::OnComeBack(Context &context, const CooperateEvent &event)
158 {
159     CALL_INFO_TRACE;
160     DSoftbusComeBack notice = std::get<DSoftbusComeBack>(event.event);
161 
162     if (!context.IsPeer(notice.networkId)) {
163         return;
164     }
165     FI_HILOGI("[come back] From \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
166     context.OnRemoteStartCooperate(notice.extra);
167     parent_.OnSetCooperatePriv(notice.extra.priv);
168     DSoftbusStartCooperate startEvent {
169         .networkId = notice.networkId,
170     };
171     context.eventMgr_.RemoteStart(startEvent);
172     context.inputEventInterceptor_.Disable();
173 
174     context.RemoteStartSuccess(notice);
175     context.eventMgr_.RemoteStartFinish(notice);
176     TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
177     context.OnBack();
178 }
179 
OnRemoteStart(Context & context,const CooperateEvent & event)180 void CooperateOut::Initial::OnRemoteStart(Context &context, const CooperateEvent &event)
181 {
182     DSoftbusStartCooperate notice = std::get<DSoftbusStartCooperate>(event.event);
183 
184     if (context.IsLocal(notice.networkId)) {
185         return;
186     }
187     FI_HILOGI("[remote start] Request from \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
188     if (context.IsPeer(notice.networkId)) {
189         FI_HILOGI("[remote start] Reset on request from peer");
190         parent_.StopCooperate(context, event);
191         return;
192     }
193     context.OnRemoteStartCooperate(notice.extra);
194     context.eventMgr_.RemoteStart(notice);
195     context.inputEventInterceptor_.Disable();
196 
197     DSoftbusStopCooperate stopNotice {};
198     context.dsoftbus_.StopCooperate(context.Peer(), stopNotice);
199 
200     context.RemoteStartSuccess(notice);
201     context.inputEventBuilder_.Enable(context);
202     context.eventMgr_.RemoteStartFinish(notice);
203     FI_HILOGI("[remote start] Cooperation with \'%{public}s\' established", Utility::Anonymize(context.Peer()).c_str());
204     TransiteTo(context, CooperateState::COOPERATE_STATE_IN);
205     context.OnTransitionIn();
206 }
207 
OnRemoteStop(Context & context,const CooperateEvent & event)208 void CooperateOut::Initial::OnRemoteStop(Context &context, const CooperateEvent &event)
209 {
210     DSoftbusStopCooperate notice = std::get<DSoftbusStopCooperate>(event.event);
211 
212     if (!context.IsPeer(notice.networkId)) {
213         return;
214     }
215     FI_HILOGI("[remote stop] Notification from \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
216     context.eventMgr_.RemoteStop(notice);
217     context.inputEventInterceptor_.Disable();
218     context.ResetCursorPosition();
219     context.eventMgr_.RemoteStopFinish(notice);
220     TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
221     context.OnResetCooperation();
222 }
223 
OnRelay(Context & context,const CooperateEvent & event)224 void CooperateOut::Initial::OnRelay(Context &context, const CooperateEvent &event)
225 {
226     DSoftbusRelayCooperate notice = std::get<DSoftbusRelayCooperate>(event.event);
227     if (!context.IsPeer(notice.networkId)) {
228         return;
229     }
230     DSoftbusRelayCooperateFinished resp {
231         .targetNetworkId = notice.targetNetworkId,
232     };
233 
234     int32_t ret = context.dsoftbus_.OpenSession(notice.targetNetworkId);
235     if (ret != RET_OK) {
236         FI_HILOGE("[relay cooperate] Failed to connect to \'%{public}s\'",
237             Utility::Anonymize(notice.targetNetworkId).c_str());
238         resp.normal = false;
239         context.dsoftbus_.RelayCooperateFinish(notice.networkId, resp);
240         return;
241     }
242 
243     resp.normal = true;
244     context.dsoftbus_.RelayCooperateFinish(notice.networkId, resp);
245 
246     context.RelayCooperate(notice);
247     context.inputEventInterceptor_.Update(context);
248     FI_HILOGI("[relay cooperate] Relay cooperation to \'%{public}s\'", Utility::Anonymize(context.Peer()).c_str());
249     context.OnRelayCooperation(context.Peer(), context.NormalizedCursorPosition());
250 }
251 
OnHotplug(Context & context,const CooperateEvent & event)252 void CooperateOut::Initial::OnHotplug(Context &context, const CooperateEvent &event)
253 {
254     InputHotplugEvent notice = std::get<InputHotplugEvent>(event.event);
255     if (notice.deviceId != context.StartDeviceId()) {
256         return;
257     }
258     FI_HILOGI("Stop cooperation on unplug of dedicated pointer");
259     parent_.StopCooperate(context, event);
260 }
261 
OnAppClosed(Context & context,const CooperateEvent & event)262 void CooperateOut::Initial::OnAppClosed(Context &context, const CooperateEvent &event)
263 {
264     FI_HILOGI("[app closed] Close all connections");
265     context.dsoftbus_.CloseAllSessions();
266     FI_HILOGI("[app closed] Stop cooperation");
267     parent_.StopCooperate(context, event);
268 }
269 
OnPointerEvent(Context & context,const CooperateEvent & event)270 void CooperateOut::Initial::OnPointerEvent(Context &context, const CooperateEvent &event)
271 {
272     InputPointerEvent notice = std::get<InputPointerEvent>(event.event);
273 
274     if ((notice.sourceType != MMI::PointerEvent::SOURCE_TYPE_MOUSE) || (notice.deviceId == context.StartDeviceId())) {
275         return;
276     }
277     FI_HILOGI("Stop cooperation on operation of undedicated pointer");
278     parent_.StopCooperate(context, event);
279 }
280 
OnBoardOffline(Context & context,const CooperateEvent & event)281 void CooperateOut::Initial::OnBoardOffline(Context &context, const CooperateEvent &event)
282 {
283     DDMBoardOfflineEvent notice = std::get<DDMBoardOfflineEvent>(event.event);
284 
285     if (!context.IsPeer(notice.networkId)) {
286         return;
287     }
288     FI_HILOGI("[board offline] Peer(\'%{public}s\') is offline", Utility::Anonymize(notice.networkId).c_str());
289     parent_.StopCooperate(context, event);
290 }
291 
OnSwitchChanged(Context & context,const CooperateEvent & event)292 void CooperateOut::Initial::OnSwitchChanged(Context &context, const CooperateEvent &event)
293 {
294     DDPCooperateSwitchChanged notice = std::get<DDPCooperateSwitchChanged>(event.event);
295 
296     if (!context.IsPeer(notice.networkId) || notice.normal) {
297         return;
298     }
299     FI_HILOGI("[switch off] Peer(\'%{public}s\') switch off", Utility::Anonymize(notice.networkId).c_str());
300     parent_.StopCooperate(context, event);
301 }
302 
OnSoftbusSessionClosed(Context & context,const CooperateEvent & event)303 void CooperateOut::Initial::OnSoftbusSessionClosed(Context &context, const CooperateEvent &event)
304 {
305     DSoftbusSessionClosed notice = std::get<DSoftbusSessionClosed>(event.event);
306 
307     if (!context.IsPeer(notice.networkId)) {
308         return;
309     }
310     FI_HILOGI(
311         "[dsoftbus session closed] Disconnected with \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
312     parent_.StopCooperate(context, event);
313 }
314 
OnProgress(Context & context,const CooperateEvent & event)315 void CooperateOut::Initial::OnProgress(Context &context, const CooperateEvent &event) { }
316 
OnReset(Context & context,const CooperateEvent & event)317 void CooperateOut::Initial::OnReset(Context &context, const CooperateEvent &event) { }
318 
StopCooperate(Context & context,const CooperateEvent & event)319 void CooperateOut::StopCooperate(Context &context, const CooperateEvent &event)
320 {
321     context.inputEventInterceptor_.Disable();
322 
323     DSoftbusStopCooperate notice {};
324     context.dsoftbus_.StopCooperate(context.Peer(), notice);
325 
326     context.ResetCursorPosition();
327     TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
328     context.OnResetCooperation();
329 }
330 
UnchainConnections(Context & context,const StopCooperateEvent & event) const331 void CooperateOut::UnchainConnections(Context &context, const StopCooperateEvent &event) const
332 {
333     if (event.isUnchained) {
334         FI_HILOGI("Unchain all connections");
335         context.dsoftbus_.CloseAllSessions();
336         context.eventMgr_.OnUnchain(event);
337     }
338 }
339 } // namespace Cooperate
340 } // namespace DeviceStatus
341 } // namespace Msdp
342 } // namespace OHOS
343