• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "cooperate_free.h"
17 #include "cooperate_hisysevent.h"
18 
19 #include "devicestatus_define.h"
20 #include "utility.h"
21 
22 #undef LOG_TAG
23 #define LOG_TAG "CooperateFree"
24 
25 namespace OHOS {
26 namespace Msdp {
27 namespace DeviceStatus {
28 namespace Cooperate {
29 
CooperateFree(IStateMachine & parent,IContext * env)30 CooperateFree::CooperateFree(IStateMachine &parent, IContext *env)
31     : ICooperateState(parent), env_(env)
32 {
33     initial_ = std::make_shared<Initial>(*this);
34     Initial::BuildChains(initial_, *this);
35     current_ = initial_;
36 }
37 
~CooperateFree()38 CooperateFree::~CooperateFree()
39 {
40     Initial::RemoveChains(initial_);
41 }
42 
OnEvent(Context & context,const CooperateEvent & event)43 void CooperateFree::OnEvent(Context &context, const CooperateEvent &event)
44 {
45     current_->OnEvent(context, event);
46 }
47 
OnEnterState(Context & context)48 void CooperateFree::OnEnterState(Context &context)
49 {
50     CALL_INFO_TRACE;
51 }
52 
OnLeaveState(Context & context)53 void CooperateFree::OnLeaveState(Context &context)
54 {
55     CALL_INFO_TRACE;
56     UpdateCooperateFlagEvent event {
57         .mask = COOPERATE_FLAG_HIDE_CURSOR,
58     };
59     context.UpdateCooperateFlag(event);
60 }
61 
SetPointerVisible(Context & context)62 void CooperateFree::SetPointerVisible(Context &context)
63 {
64     CHKPV(env_);
65     bool hasLocalPointerDevice =  env_->GetDeviceManager().HasLocalPointerDevice() ||
66         env_->GetInput().HasLocalPointerDevice();
67     bool visible = !context.NeedHideCursor() && hasLocalPointerDevice;
68     FI_HILOGI("Set pointer visible:%{public}s, HasLocalPointerDevice:%{public}s",
69         visible ? "true" : "false", hasLocalPointerDevice ? "true" : "false");
70     env_->GetInput().SetPointerVisibility(visible, PRIORITY);
71 }
72 
UnchainConnections(Context & context,const StopCooperateEvent & event) const73 void CooperateFree::UnchainConnections(Context &context, const StopCooperateEvent &event) const
74 {
75     CALL_DEBUG_ENTER;
76     if (event.isUnchained) {
77         FI_HILOGI("Unchain all connections");
78         context.dsoftbus_.CloseAllSessions();
79         context.eventMgr_.OnUnchain(event);
80     }
81 }
82 
SimulateShowPointerEvent()83 void CooperateFree::SimulateShowPointerEvent()
84 {
85     CALL_INFO_TRACE;
86     CHKPV(env_);
87     auto pointerEvent = OHOS::MMI::PointerEvent::Create();
88     OHOS::MMI::PointerEvent::PointerItem item;
89     item.SetPointerId(0);
90     item.SetRawDx(0);
91     item.SetRawDy(0);
92     CHKPV(pointerEvent);
93     pointerEvent->SetPointerAction(OHOS::MMI::PointerEvent::POINTER_ACTION_MOVE);
94     pointerEvent->AddFlag(OHOS::MMI::InputEvent::EVENT_FLAG_RAW_POINTER_MOVEMENT);
95     pointerEvent->SetPointerId(0);
96     pointerEvent->SetSourceType(OHOS::MMI::PointerEvent::SOURCE_TYPE_MOUSE);
97     pointerEvent->AddPointerItem(item);
98     env_->GetInput().SimulateInputEvent(pointerEvent);
99 }
100 
Initial(CooperateFree & parent)101 CooperateFree::Initial::Initial(CooperateFree &parent)
102     : ICooperateStep(parent, nullptr), parent_(parent)
103 {
104     AddHandler(CooperateEventType::START, [this](Context &context, const CooperateEvent &event) {
105         this->OnStart(context, event);
106     });
107     AddHandler(CooperateEventType::WITH_OPTIONS_START, [this](Context &context, const CooperateEvent &event) {
108         this->OnStartWithOptions(context, event);
109     });
110     AddHandler(CooperateEventType::STOP, [this](Context &context, const CooperateEvent &event) {
111         this->OnStop(context, event);
112     });
113     AddHandler(CooperateEventType::DISABLE, [this](Context &context, const CooperateEvent &event) {
114         this->OnDisable(context, event);
115     });
116     AddHandler(CooperateEventType::APP_CLOSED, [this](Context &context, const CooperateEvent &event) {
117         this->OnAppClosed(context, event);
118     });
119     AddHandler(CooperateEventType::DSOFTBUS_START_COOPERATE, [this](Context &context, const CooperateEvent &event) {
120         this->OnRemoteStart(context, event);
121     });
122     AddHandler(CooperateEventType::INPUT_POINTER_EVENT, [this](Context &context, const CooperateEvent &event) {
123         this->OnPointerEvent(context, event);
124     });
125     AddHandler(CooperateEventType::UPDATE_COOPERATE_FLAG,
126         [this](Context &context, const CooperateEvent &event) {
127             this->OnUpdateCooperateFlag(context, event);
128     });
129     AddHandler(CooperateEventType::DSOFTBUS_COOPERATE_WITH_OPTIONS,
130         [this](Context &context, const CooperateEvent &event) {
131             this->OnRemoteStartWithOptions(context, event);
132     });
133 }
134 
OnProgress(Context & context,const CooperateEvent & event)135 void CooperateFree::Initial::OnProgress(Context &context, const CooperateEvent &event)
136 {}
137 
OnProgressWithOptions(Context & context,const CooperateEvent & event)138 void CooperateFree::Initial::OnProgressWithOptions(Context &context, const CooperateEvent &event)
139 {}
140 
OnReset(Context & context,const CooperateEvent & event)141 void CooperateFree::Initial::OnReset(Context &context, const CooperateEvent &event)
142 {}
143 
BuildChains(std::shared_ptr<Initial> initial,CooperateFree & parent)144 void CooperateFree::Initial::BuildChains(std::shared_ptr<Initial> initial, CooperateFree &parent)
145 {}
146 
RemoveChains(std::shared_ptr<Initial> initial)147 void CooperateFree::Initial::RemoveChains(std::shared_ptr<Initial> initial)
148 {}
149 
OnStart(Context & context,const CooperateEvent & event)150 void CooperateFree::Initial::OnStart(Context &context, const CooperateEvent &event)
151 {
152     CALL_INFO_TRACE;
153     StartCooperateEvent notice = std::get<StartCooperateEvent>(event.event);
154     FI_HILOGI("[start cooperation] With \'%{public}s\'", Utility::Anonymize(notice.remoteNetworkId).c_str());
155     context.StartCooperate(notice);
156     context.eventMgr_.StartCooperate(notice);
157 
158     if (parent_.env_->GetDragManager().GetDragState() == DragState::MOTION_DRAGGING) {
159         FI_HILOGE("Not allow cooperate");
160         NotAollowCooperateWhenMotionDragging result {
161             .pid = notice.pid,
162             .userData = notice.userData,
163             .networkId = notice.remoteNetworkId,
164             .success = false,
165             .errCode = static_cast<int32_t>(CoordinationErrCode::NOT_AOLLOW_COOPERATE_WHEN_MOTION_DRAGGING)
166         };
167         context.eventMgr_.ErrorNotAollowCooperateWhenMotionDragging(result);
168         return;
169     }
170     int32_t ret = context.dsoftbus_.OpenSession(context.Peer());
171     if (ret != RET_OK) {
172         FI_HILOGE("[start cooperation] Failed to connect to \'%{public}s\'",
173             Utility::Anonymize(context.Peer()).c_str());
174         CooperateRadarInfo radarInfo {
175             .funcName = __FUNCTION__,
176             .bizState = static_cast<int32_t> (BizState::STATE_END),
177             .bizStage = static_cast<int32_t> (BizCooperateStage::STAGE_OPEN_DSOFTBUS_SESSION),
178             .stageRes = static_cast<int32_t> (BizCooperateStageRes::RES_FAIL),
179             .bizScene = static_cast<int32_t> (BizCooperateScene::SCENE_ACTIVE),
180             .errCode = static_cast<int32_t> (CooperateRadarErrCode::OPEN_DSOFTBUS_SESSION_FAILED),
181             .localNetId = Utility::DFXRadarAnonymize(context.Local().c_str()),
182             .peerNetId = Utility::DFXRadarAnonymize(notice.remoteNetworkId.c_str())
183         };
184         CooperateRadar::ReportCooperateRadarInfo(radarInfo);
185         int32_t errNum = (ret == RET_ERR ? static_cast<int32_t>(CoordinationErrCode::OPEN_SESSION_FAILED) : ret);
186         DSoftbusStartCooperateFinished failNotice {
187             .success = false,
188             .errCode = errNum
189         };
190         context.eventMgr_.StartCooperateFinish(failNotice);
191         return;
192     }
193     DSoftbusStartCooperate startNotice {
194         .originNetworkId = context.Local(),
195         .success = true,
196         .cursorPos = context.NormalizedCursorPosition(),
197         .pointerSpeed = context.GetPointerSpeed(),
198         .touchPadSpeed = context.GetTouchPadSpeed(),
199     };
200     context.OnStartCooperate(startNotice.extra);
201     context.dsoftbus_.StartCooperate(context.Peer(), startNotice);
202     context.inputEventInterceptor_.Enable(context);
203     context.eventMgr_.StartCooperateFinish(startNotice);
204     FI_HILOGI("[start cooperation] Cooperation with \'%{public}s\' established",
205         Utility::Anonymize(context.Peer()).c_str());
206     TransiteTo(context, CooperateState::COOPERATE_STATE_OUT);
207     context.OnTransitionOut();
208 #ifdef ENABLE_PERFORMANCE_CHECK
209     std::ostringstream ss;
210     ss << "start_cooperation_with_ " << Utility::Anonymize(context.Peer()).c_str();
211     context.FinishTrace(ss.str());
212 #endif // ENABLE_PERFORMANCE_CHECK
213 }
214 
OnStop(Context & context,const CooperateEvent & event)215 void CooperateFree::Initial::OnStop(Context &context, const CooperateEvent &event)
216 {
217     CALL_INFO_TRACE;
218     StopCooperateEvent param = std::get<StopCooperateEvent>(event.event);
219     context.eventMgr_.StopCooperate(param);
220     param.networkId = context.Peer();
221     DSoftbusStopCooperateFinished notice {
222         .networkId = context.Peer(),
223         .normal = true,
224     };
225     context.eventMgr_.StopCooperateFinish(notice);
226     context.inputDevMgr_.RemoveVirtualInputDevice(context.Peer());
227     parent_.UnchainConnections(context, param);
228 }
229 
OnStartWithOptions(Context & context,const CooperateEvent & event)230 void CooperateFree::Initial::OnStartWithOptions(Context &context, const CooperateEvent &event)
231 {
232     CALL_INFO_TRACE;
233     StartWithOptionsEvent notice = std::get<StartWithOptionsEvent>(event.event);
234     FI_HILOGI("[start cooperation With Options] With \'%{public}s\'",
235         Utility::Anonymize(notice.remoteNetworkId).c_str());
236     context.StartCooperateWithOptions(notice);
237     context.eventMgr_.StartCooperateWithOptions(notice);
238     int32_t ret = context.dsoftbus_.OpenSession(context.Peer());
239     if (ret != RET_OK) {
240         FI_HILOGE("[start cooperation] Failed to connect to \'%{public}s\'",
241             Utility::Anonymize(context.Peer()).c_str());
242         int32_t errNum = (ret == RET_ERR ? static_cast<int32_t>(CoordinationErrCode::OPEN_SESSION_FAILED) : ret);
243         DSoftbusStartCooperateFinished failNotice {
244             .success = false,
245             .errCode = errNum
246         };
247         context.eventMgr_.StartCooperateFinish(failNotice);
248         return;
249     }
250     DSoftbusCooperateOptions startNotice {
251         .originNetworkId = context.Local(),
252         .success = true,
253         .cooperateOptions = {notice.displayX, notice.displayY, notice.displayId},
254     };
255     context.OnStartCooperate(startNotice.extra);
256     context.dsoftbus_.StartCooperateWithOptions(context.Peer(), startNotice);
257     context.inputEventInterceptor_.Enable(context);
258     context.eventMgr_.StartCooperateWithOptinsFinish(startNotice);
259     FI_HILOGI("[start cooperation] Cooperation with \'%{public}s\' established",
260         Utility::Anonymize(context.Peer()).c_str());
261     TransiteTo(context, CooperateState::COOPERATE_STATE_OUT);
262     context.OnTransitionOut();
263 #ifdef ENABLE_PERFORMANCE_CHECK
264     std::ostringstream ss;
265     ss << "start_cooperation_with_ " << Utility::Anonymize(context.Peer()).c_str();
266     context.FinishTrace(ss.str());
267 #endif // ENABLE_PERFORMANCE_CHECK
268 }
269 
OnDisable(Context & context,const CooperateEvent & event)270 void CooperateFree::Initial::OnDisable(Context &context, const CooperateEvent &event)
271 {
272     FI_HILOGI("[disable cooperation] Stop cooperation");
273     CHKPV(parent_.env_);
274     auto dragState = parent_.env_->GetDragManager().GetDragState();
275     if (dragState == DragState::START && parent_.env_->GetDragManager().IsCrossDragging()) {
276         FI_HILOGI("reset cooperation");
277         context.OnResetCooperation();
278     } else if (dragState == DragState::START) {
279         FI_HILOGI("drag state is start");
280         return;
281     }
282     bool hasLocalPointerDevice =  parent_.env_->GetDeviceManager().HasLocalPointerDevice() ||
283         parent_.env_->GetInput().HasLocalPointerDevice();
284     FI_HILOGI("HasLocalPointerDevice:%{public}s", hasLocalPointerDevice ? "true" : "false");
285     context.inputDevMgr_.RemoveVirtualInputDevice(context.Peer());
286     parent_.env_->GetInput().SetPointerVisibility(hasLocalPointerDevice, PRIORITY);
287 }
288 
OnAppClosed(Context & context,const CooperateEvent & event)289 void CooperateFree::Initial::OnAppClosed(Context &context, const CooperateEvent &event)
290 {
291     FI_HILOGI("[app closed] Close all connections");
292     context.inputDevMgr_.RemoveVirtualInputDevice(context.Peer());
293     context.dsoftbus_.CloseAllSessions();
294 }
295 
OnRemoteStart(Context & context,const CooperateEvent & event)296 void CooperateFree::Initial::OnRemoteStart(Context &context, const CooperateEvent &event)
297 {
298     CALL_INFO_TRACE;
299     DSoftbusStartCooperate notice = std::get<DSoftbusStartCooperate>(event.event);
300     context.StorePeerPointerSpeed(notice.pointerSpeed);
301     context.StorePeerTouchPadSpeed(notice.touchPadSpeed);
302     context.OnRemoteStartCooperate(notice.extra);
303     context.eventMgr_.RemoteStart(notice);
304     context.RemoteStartSuccess(notice);
305     context.inputEventBuilder_.Enable(context);
306     context.eventMgr_.RemoteStartFinish(notice);
307     context.inputDevMgr_.AddVirtualInputDevice(context.Peer());
308     FI_HILOGI("[remote start] Cooperation with \'%{public}s\' established", Utility::Anonymize(context.Peer()).c_str());
309     TransiteTo(context, CooperateState::COOPERATE_STATE_IN);
310     context.OnTransitionIn();
311     if (!context.NeedFreezeCursor()) {
312         parent_.SimulateShowPointerEvent();
313     }
314 }
315 
OnRemoteStartWithOptions(Context & context,const CooperateEvent & event)316 void CooperateFree::Initial::OnRemoteStartWithOptions(Context &context, const CooperateEvent &event)
317 {
318     CALL_INFO_TRACE;
319     DSoftbusCooperateOptions notice = std::get<DSoftbusCooperateOptions>(event.event);
320     context.OnRemoteStartCooperate(notice.extra);
321     context.eventMgr_.RemoteStartWithOptions(notice);
322     context.OnRemoteStart(notice);
323     context.inputEventBuilder_.Enable(context);
324     context.eventMgr_.RemoteStartWithOptionsFinish(notice);
325     context.inputDevMgr_.AddVirtualInputDevice(context.Peer());
326     FI_HILOGI("[remote start with options] Cooperation with \'%{public}s\' established",
327         Utility::Anonymize(context.Peer()).c_str());
328     TransiteTo(context, CooperateState::COOPERATE_STATE_IN);
329     context.OnTransitionIn();
330 }
331 
OnPointerEvent(Context & context,const CooperateEvent & event)332 void CooperateFree::Initial::OnPointerEvent(Context &context, const CooperateEvent &event)
333 {
334     CALL_DEBUG_ENTER;
335     if (context.NeedHideCursor() && context.IsCooperateWithCrossDrag()) {
336         FI_HILOGD("Hide cursor before dragData rcvd when come back");
337         return;
338     }
339     InputPointerEvent notice = std::get<InputPointerEvent>(event.event);
340     CHKPV(parent_.env_);
341     if (auto dragState = parent_.env_->GetDragManager().GetDragState(); dragState == DragState::START) {
342         FI_HILOGD("Current dragState:START");
343         return;
344     }
345     if (InputEventBuilder::IsLocalEvent(notice) && context.NeedHideCursor()) {
346         UpdateCooperateFlagEvent event {
347             .mask = COOPERATE_FLAG_HIDE_CURSOR,
348         };
349         context.UpdateCooperateFlag(event);
350         parent_.SetPointerVisible(context);
351     }
352 }
353 
OnUpdateCooperateFlag(Context & context,const CooperateEvent & event)354 void CooperateFree::Initial::OnUpdateCooperateFlag(Context &context, const CooperateEvent &event)
355 {
356     CALL_INFO_TRACE;
357     UpdateCooperateFlagEvent notice = std::get<UpdateCooperateFlagEvent>(event.event);
358     context.UpdateCooperateFlag(notice);
359 }
360 } // namespace Cooperate
361 } // namespace DeviceStatus
362 } // namespace Msdp
363 } // namespace OHOS
364