• 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         env_->GetDeviceManager().HasPencilAirMouse();
68     bool visible = !context.NeedHideCursor() && hasLocalPointerDevice;
69     FI_HILOGI("Set pointer visible:%{public}s, HasLocalPointerDevice:%{public}s",
70         visible ? "true" : "false", hasLocalPointerDevice ? "true" : "false");
71     env_->GetInput().SetPointerVisibility(visible, PRIORITY);
72 }
73 
UnchainConnections(Context & context,const StopCooperateEvent & event) const74 void CooperateFree::UnchainConnections(Context &context, const StopCooperateEvent &event) const
75 {
76     CALL_DEBUG_ENTER;
77     if (event.isUnchained) {
78         FI_HILOGI("Unchain all connections");
79         context.dsoftbus_.CloseAllSessions();
80         context.eventMgr_.OnUnchain(event);
81     }
82 }
83 
SimulateShowPointerEvent()84 void CooperateFree::SimulateShowPointerEvent()
85 {
86     CALL_INFO_TRACE;
87     CHKPV(env_);
88     auto pointerEvent = OHOS::MMI::PointerEvent::Create();
89     OHOS::MMI::PointerEvent::PointerItem item;
90     item.SetPointerId(0);
91     item.SetRawDx(0);
92     item.SetRawDy(0);
93     CHKPV(pointerEvent);
94     pointerEvent->SetPointerAction(OHOS::MMI::PointerEvent::POINTER_ACTION_MOVE);
95     pointerEvent->AddFlag(OHOS::MMI::InputEvent::EVENT_FLAG_RAW_POINTER_MOVEMENT);
96     pointerEvent->SetPointerId(0);
97     pointerEvent->SetSourceType(OHOS::MMI::PointerEvent::SOURCE_TYPE_MOUSE);
98     pointerEvent->AddPointerItem(item);
99     env_->GetInput().SimulateInputEvent(pointerEvent);
100 }
101 
Initial(CooperateFree & parent)102 CooperateFree::Initial::Initial(CooperateFree &parent)
103     : ICooperateStep(parent, nullptr), parent_(parent)
104 {
105     AddHandler(CooperateEventType::START, [this](Context &context, const CooperateEvent &event) {
106         this->OnStart(context, event);
107     });
108     AddHandler(CooperateEventType::WITH_OPTIONS_START, [this](Context &context, const CooperateEvent &event) {
109         this->OnStartWithOptions(context, event);
110     });
111     AddHandler(CooperateEventType::STOP, [this](Context &context, const CooperateEvent &event) {
112         this->OnStop(context, event);
113     });
114     AddHandler(CooperateEventType::DISABLE, [this](Context &context, const CooperateEvent &event) {
115         this->OnDisable(context, event);
116     });
117     AddHandler(CooperateEventType::APP_CLOSED, [this](Context &context, const CooperateEvent &event) {
118         this->OnAppClosed(context, event);
119     });
120     AddHandler(CooperateEventType::DSOFTBUS_START_COOPERATE, [this](Context &context, const CooperateEvent &event) {
121         this->OnRemoteStart(context, event);
122     });
123     AddHandler(CooperateEventType::INPUT_POINTER_EVENT, [this](Context &context, const CooperateEvent &event) {
124         this->OnPointerEvent(context, event);
125     });
126     AddHandler(CooperateEventType::UPDATE_COOPERATE_FLAG,
127         [this](Context &context, const CooperateEvent &event) {
128             this->OnUpdateCooperateFlag(context, event);
129     });
130     AddHandler(CooperateEventType::DSOFTBUS_COOPERATE_WITH_OPTIONS,
131         [this](Context &context, const CooperateEvent &event) {
132             this->OnRemoteStartWithOptions(context, event);
133     });
134 }
135 
OnProgress(Context & context,const CooperateEvent & event)136 void CooperateFree::Initial::OnProgress(Context &context, const CooperateEvent &event)
137 {}
138 
OnProgressWithOptions(Context & context,const CooperateEvent & event)139 void CooperateFree::Initial::OnProgressWithOptions(Context &context, const CooperateEvent &event)
140 {}
141 
OnReset(Context & context,const CooperateEvent & event)142 void CooperateFree::Initial::OnReset(Context &context, const CooperateEvent &event)
143 {}
144 
BuildChains(std::shared_ptr<Initial> initial,CooperateFree & parent)145 void CooperateFree::Initial::BuildChains(std::shared_ptr<Initial> initial, CooperateFree &parent)
146 {}
147 
RemoveChains(std::shared_ptr<Initial> initial)148 void CooperateFree::Initial::RemoveChains(std::shared_ptr<Initial> initial)
149 {}
150 
OnStart(Context & context,const CooperateEvent & event)151 void CooperateFree::Initial::OnStart(Context &context, const CooperateEvent &event)
152 {
153     CALL_INFO_TRACE;
154     StartCooperateEvent notice = std::get<StartCooperateEvent>(event.event);
155     FI_HILOGI("[start cooperation] With \'%{public}s\'", Utility::Anonymize(notice.remoteNetworkId).c_str());
156     context.StartCooperate(notice);
157     context.eventMgr_.StartCooperate(notice);
158 
159     CHKPV(parent_.env_);
160     if (parent_.env_->GetDragManager().GetDragState() == DragState::MOTION_DRAGGING) {
161         FI_HILOGE("Not allow cooperate");
162         NotAollowCooperateWhenMotionDragging result {
163             .pid = notice.pid,
164             .userData = notice.userData,
165             .networkId = notice.remoteNetworkId,
166             .success = false,
167             .errCode = static_cast<int32_t>(CoordinationErrCode::NOT_AOLLOW_COOPERATE_WHEN_MOTION_DRAGGING)
168         };
169         context.eventMgr_.ErrorNotAollowCooperateWhenMotionDragging(result);
170         return;
171     }
172     int32_t ret = context.dsoftbus_.OpenSession(context.Peer());
173     if (ret != RET_OK) {
174         CooperateFail(context, ret);
175         return;
176     }
177     InitiatorPointerVisible(false);
178     ret = context.dsoftbus_.CheckDeviceOnline(context.Peer());
179     if (ret != RET_OK) {
180         FI_HILOGE("CheckDeviceOnline failed, networkId:%{public}s", Utility::Anonymize(context.Peer()).c_str());
181         InitiatorPointerVisible(true);
182         return;
183     }
184     DSoftbusStartCooperate startNotice {
185         .originNetworkId = context.Local(),
186         .success = true,
187         .cursorPos = context.NormalizedCursorPosition(),
188         .pointerSpeed = context.GetPointerSpeed(),
189         .touchPadSpeed = context.GetTouchPadSpeed(),
190         .uid = notice.uid,
191     };
192     context.OnStartCooperate(startNotice.extra);
193     ret = context.dsoftbus_.StartCooperate(context.Peer(), startNotice);
194     if (ret != RET_OK) {
195         InitiatorPointerVisible(true);
196         return;
197     }
198     ret = context.inputEventInterceptor_.Enable(context);
199     if (ret != RET_OK) {
200         InitiatorPointerVisible(true);
201         return;
202     }
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 
InitiatorPointerVisible(bool visible)215 void CooperateFree::Initial::InitiatorPointerVisible(bool visible)
216 {
217     FI_HILOGI("Set pointer visible:%{public}s", visible ? "true" : "false");
218     CHKPV(parent_.env_);
219     parent_.env_->GetInput().SetPointerVisibility(visible);
220 }
221 
CooperateFail(Context & context,int32_t ret)222 void CooperateFree::Initial::CooperateFail(Context &context, int32_t ret)
223 {
224     CALL_INFO_TRACE;
225     if (ret != RET_OK) {
226         FI_HILOGE("[start cooperation] Failed to connect to \'%{public}s\'",
227             Utility::Anonymize(context.Peer()).c_str());
228         CooperateRadarInfo radarInfo {
229             .funcName = __FUNCTION__,
230             .bizState = static_cast<int32_t> (BizState::STATE_END),
231             .bizStage = static_cast<int32_t> (BizCooperateStage::STAGE_OPEN_DSOFTBUS_SESSION),
232             .stageRes = static_cast<int32_t> (BizCooperateStageRes::RES_FAIL),
233             .bizScene = static_cast<int32_t> (BizCooperateScene::SCENE_ACTIVE),
234             .errCode = static_cast<int32_t> (CooperateRadarErrCode::OPEN_DSOFTBUS_SESSION_FAILED),
235             .localNetId = Utility::DFXRadarAnonymize(context.Local().c_str()),
236             .peerNetId = Utility::DFXRadarAnonymize(context.Peer().c_str())
237         };
238         CooperateRadar::ReportCooperateRadarInfo(radarInfo);
239         int32_t errNum = (ret == RET_ERR ? static_cast<int32_t>(CoordinationErrCode::OPEN_SESSION_FAILED) : ret);
240         DSoftbusStartCooperateFinished failNotice {
241             .success = false,
242             .errCode = errNum
243         };
244         context.eventMgr_.StartCooperateFinish(failNotice);
245         return;
246     }
247 }
248 
OnStop(Context & context,const CooperateEvent & event)249 void CooperateFree::Initial::OnStop(Context &context, const CooperateEvent &event)
250 {
251     CALL_INFO_TRACE;
252     StopCooperateEvent param = std::get<StopCooperateEvent>(event.event);
253     context.eventMgr_.StopCooperate(param);
254     param.networkId = context.Peer();
255     DSoftbusStopCooperateFinished notice {
256         .networkId = context.Peer(),
257         .normal = true,
258     };
259     context.eventMgr_.StopCooperateFinish(notice);
260     parent_.UnchainConnections(context, param);
261 }
262 
OnStartWithOptions(Context & context,const CooperateEvent & event)263 void CooperateFree::Initial::OnStartWithOptions(Context &context, const CooperateEvent &event)
264 {
265     CALL_INFO_TRACE;
266     CHKPV(parent_.env_);
267     StartWithOptionsEvent notice = std::get<StartWithOptionsEvent>(event.event);
268     FI_HILOGI("[start With] With \'%{public}s\'", Utility::Anonymize(notice.remoteNetworkId).c_str());
269     context.StartCooperateWithOptions(notice);
270     context.eventMgr_.StartCooperateWithOptions(notice);
271     if (parent_.env_->GetDragManager().GetDragState() == DragState::MOTION_DRAGGING) {
272         FI_HILOGE("Not allow cooperate");
273         NotAollowCooperateWhenMotionDragging result {
274             .pid = notice.pid,
275             .userData = notice.userData,
276             .networkId = notice.remoteNetworkId,
277             .success = false,
278             .errCode = static_cast<int32_t>(CoordinationErrCode::NOT_AOLLOW_COOPERATE_WHEN_MOTION_DRAGGING)
279         };
280         context.eventMgr_.ErrorNotAollowCooperateWhenMotionDragging(result);
281         return;
282     }
283     int32_t ret = context.dsoftbus_.OpenSession(context.Peer());
284     if (ret != RET_OK) {
285         FI_HILOGE("[start cooperation] Failed to connect\'%{public}s\'", Utility::Anonymize(context.Peer()).c_str());
286         int32_t errNum = (ret == RET_ERR ? static_cast<int32_t>(CoordinationErrCode::OPEN_SESSION_FAILED) : ret);
287         DSoftbusStartCooperateFinished failNotice {
288             .success = false,
289             .errCode = errNum
290         };
291         context.eventMgr_.StartCooperateFinish(failNotice);
292         return;
293     }
294     DSoftbusCooperateOptions startNotice {
295         .originNetworkId = context.Local(),
296         .success = true,
297         .cooperateOptions = {notice.displayX, notice.displayY, notice.displayId},
298         .pointerSpeed = context.GetPointerSpeed(),
299         .touchPadSpeed = context.GetTouchPadSpeed(),
300     };
301     context.OnStartCooperate(startNotice.extra);
302     context.dsoftbus_.StartCooperateWithOptions(context.Peer(), startNotice);
303     context.inputEventInterceptor_.Enable(context);
304     context.eventMgr_.StartCooperateWithOptionsFinish(startNotice);
305     FI_HILOGI("[start cooperation] Cooperation with \'%{public}s\' established",
306         Utility::Anonymize(context.Peer()).c_str());
307     TransiteTo(context, CooperateState::COOPERATE_STATE_OUT);
308     context.OnTransitionOut();
309 #ifdef ENABLE_PERFORMANCE_CHECK
310     std::ostringstream ss;
311     ss << "start_cooperation_with_ " << Utility::Anonymize(context.Peer()).c_str();
312     context.FinishTrace(ss.str());
313 #endif // ENABLE_PERFORMANCE_CHECK
314 }
315 
OnDisable(Context & context,const CooperateEvent & event)316 void CooperateFree::Initial::OnDisable(Context &context, const CooperateEvent &event)
317 {
318     FI_HILOGI("[disable cooperation] Stop cooperation");
319     CHKPV(parent_.env_);
320     auto dragState = parent_.env_->GetDragManager().GetDragState();
321     if (dragState == DragState::START && parent_.env_->GetDragManager().IsCrossDragging()) {
322         FI_HILOGI("reset cooperation");
323         context.OnResetCooperation();
324     } else if (dragState == DragState::START) {
325         FI_HILOGI("drag state is start");
326         return;
327     }
328     bool hasLocalPointerDevice =  parent_.env_->GetDeviceManager().HasLocalPointerDevice() ||
329         parent_.env_->GetInput().HasLocalPointerDevice() ||
330         parent_.env_->GetDeviceManager().HasPencilAirMouse();
331     FI_HILOGI("HasLocalPointerDevice:%{public}s", hasLocalPointerDevice ? "true" : "false");
332     parent_.env_->GetInput().SetPointerVisibility(hasLocalPointerDevice, PRIORITY);
333 }
334 
OnAppClosed(Context & context,const CooperateEvent & event)335 void CooperateFree::Initial::OnAppClosed(Context &context, const CooperateEvent &event)
336 {
337     FI_HILOGI("[app closed] Close all connections");
338     context.inputDevMgr_.RemoveVirtualInputDevice(context.Peer());
339     context.dsoftbus_.CloseAllSessions();
340 }
341 
OnRemoteStart(Context & context,const CooperateEvent & event)342 void CooperateFree::Initial::OnRemoteStart(Context &context, const CooperateEvent &event)
343 {
344     CALL_INFO_TRACE;
345     DSoftbusStartCooperate notice = std::get<DSoftbusStartCooperate>(event.event);
346     context.StorePeerPointerSpeed(notice.pointerSpeed);
347     context.StorePeerTouchPadSpeed(notice.touchPadSpeed);
348     context.OnRemoteStartCooperate(notice.extra);
349     context.eventMgr_.RemoteStart(notice);
350     context.RemoteStartSuccess(notice);
351     context.inputEventBuilder_.Enable(context);
352     context.eventMgr_.RemoteStartFinish(notice);
353     context.inputDevMgr_.AddVirtualInputDevice(context.Peer());
354     FI_HILOGI("[remote start] Cooperation with \'%{public}s\' established", Utility::Anonymize(context.Peer()).c_str());
355     TransiteTo(context, CooperateState::COOPERATE_STATE_IN);
356     context.OnTransitionIn();
357     if (!context.NeedFreezeCursor()) {
358         parent_.SimulateShowPointerEvent();
359     }
360 }
361 
OnRemoteStartWithOptions(Context & context,const CooperateEvent & event)362 void CooperateFree::Initial::OnRemoteStartWithOptions(Context &context, const CooperateEvent &event)
363 {
364     CALL_INFO_TRACE;
365     DSoftbusCooperateOptions notice = std::get<DSoftbusCooperateOptions>(event.event);
366     context.StorePeerPointerSpeed(notice.pointerSpeed);
367     context.StorePeerTouchPadSpeed(notice.touchPadSpeed);
368     context.OnRemoteStartCooperate(notice.extra);
369     context.eventMgr_.RemoteStartWithOptions(notice);
370     context.AdjustPointerPos(notice);
371     context.OnRemoteStart(notice);
372     context.inputEventBuilder_.Enable(context);
373     context.eventMgr_.RemoteStartWithOptionsFinish(notice);
374     context.inputDevMgr_.AddVirtualInputDevice(context.Peer());
375     FI_HILOGI("[remote start with options] Cooperation with \'%{public}s\' established",
376         Utility::Anonymize(context.Peer()).c_str());
377     TransiteTo(context, CooperateState::COOPERATE_STATE_IN);
378     context.OnTransitionIn();
379     if (!context.NeedFreezeCursor()) {
380         parent_.SimulateShowPointerEvent();
381     }
382 }
383 
OnPointerEvent(Context & context,const CooperateEvent & event)384 void CooperateFree::Initial::OnPointerEvent(Context &context, const CooperateEvent &event)
385 {
386     CALL_DEBUG_ENTER;
387     if (context.NeedHideCursor() && context.IsCooperateWithCrossDrag()) {
388         FI_HILOGD("Hide cursor before dragData rcvd when come back");
389         return;
390     }
391     InputPointerEvent notice = std::get<InputPointerEvent>(event.event);
392     CHKPV(parent_.env_);
393     if (auto dragState = parent_.env_->GetDragManager().GetDragState(); dragState == DragState::START) {
394         FI_HILOGD("Current dragState:START");
395         return;
396     }
397     if (InputEventBuilder::IsLocalEvent(notice) && context.NeedHideCursor()) {
398         UpdateCooperateFlagEvent event {
399             .mask = COOPERATE_FLAG_HIDE_CURSOR,
400         };
401         context.UpdateCooperateFlag(event);
402         parent_.SetPointerVisible(context);
403     }
404 }
405 
OnUpdateCooperateFlag(Context & context,const CooperateEvent & event)406 void CooperateFree::Initial::OnUpdateCooperateFlag(Context &context, const CooperateEvent &event)
407 {
408     CALL_INFO_TRACE;
409     UpdateCooperateFlagEvent notice = std::get<UpdateCooperateFlagEvent>(event.event);
410     context.UpdateCooperateFlag(notice);
411 }
412 } // namespace Cooperate
413 } // namespace DeviceStatus
414 } // namespace Msdp
415 } // namespace OHOS
416