1f857971dSopenharmony_ci/*
2f857971dSopenharmony_ci * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
3f857971dSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4f857971dSopenharmony_ci * you may not use this file except in compliance with the License.
5f857971dSopenharmony_ci * You may obtain a copy of the License at
6f857971dSopenharmony_ci *
7f857971dSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8f857971dSopenharmony_ci *
9f857971dSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10f857971dSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11f857971dSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12f857971dSopenharmony_ci * See the License for the specific language governing permissions and
13f857971dSopenharmony_ci * limitations under the License.
14f857971dSopenharmony_ci */
15f857971dSopenharmony_ci
16f857971dSopenharmony_ci#include "cooperate_in.h"
17f857971dSopenharmony_ci
18f857971dSopenharmony_ci#include "devicestatus_define.h"
19f857971dSopenharmony_ci#include "utility.h"
20f857971dSopenharmony_ci
21f857971dSopenharmony_ci#undef LOG_TAG
22f857971dSopenharmony_ci#define LOG_TAG "CooperateIn"
23f857971dSopenharmony_ci
24f857971dSopenharmony_cinamespace OHOS {
25f857971dSopenharmony_cinamespace Msdp {
26f857971dSopenharmony_cinamespace DeviceStatus {
27f857971dSopenharmony_cinamespace Cooperate {
28f857971dSopenharmony_ci
29f857971dSopenharmony_ciCooperateIn::CooperateIn(IStateMachine &parent, IContext *env)
30f857971dSopenharmony_ci    : ICooperateState(parent), env_(env)
31f857971dSopenharmony_ci{
32f857971dSopenharmony_ci    initial_ = std::make_shared<Initial>(*this);
33f857971dSopenharmony_ci    Initial::BuildChains(initial_, *this);
34f857971dSopenharmony_ci    current_ = initial_;
35f857971dSopenharmony_ci}
36f857971dSopenharmony_ci
37f857971dSopenharmony_ciCooperateIn::~CooperateIn()
38f857971dSopenharmony_ci{
39f857971dSopenharmony_ci    Initial::RemoveChains(initial_);
40f857971dSopenharmony_ci}
41f857971dSopenharmony_ci
42f857971dSopenharmony_civoid CooperateIn::OnEvent(Context &context, const CooperateEvent &event)
43f857971dSopenharmony_ci{
44f857971dSopenharmony_ci    current_->OnEvent(context, event);
45f857971dSopenharmony_ci}
46f857971dSopenharmony_ci
47f857971dSopenharmony_civoid CooperateIn::OnEnterState(Context &context)
48f857971dSopenharmony_ci{
49f857971dSopenharmony_ci    CALL_INFO_TRACE;
50f857971dSopenharmony_ci    env_->GetInput().SetPointerVisibility(!context.NeedHideCursor());
51f857971dSopenharmony_ci}
52f857971dSopenharmony_ci
53f857971dSopenharmony_civoid CooperateIn::OnLeaveState(Context & context)
54f857971dSopenharmony_ci{
55f857971dSopenharmony_ci    CALL_INFO_TRACE;
56f857971dSopenharmony_ci    UpdateCooperateFlagEvent event {
57f857971dSopenharmony_ci        .mask = COOPERATE_FLAG_HIDE_CURSOR,
58f857971dSopenharmony_ci        .flag = COOPERATE_FLAG_HIDE_CURSOR,
59f857971dSopenharmony_ci    };
60f857971dSopenharmony_ci    context.UpdateCooperateFlag(event);
61f857971dSopenharmony_ci    CHKPV(env_);
62f857971dSopenharmony_ci    env_->GetInput().SetPointerVisibility(false);
63f857971dSopenharmony_ci}
64f857971dSopenharmony_ci
65f857971dSopenharmony_cistd::set<int32_t> CooperateIn::Initial::filterPointerActions_ {
66f857971dSopenharmony_ci    MMI::PointerEvent::POINTER_ACTION_ENTER_WINDOW,
67f857971dSopenharmony_ci    MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW,
68f857971dSopenharmony_ci    MMI::PointerEvent::POINTER_ACTION_PULL_IN_WINDOW,
69f857971dSopenharmony_ci    MMI::PointerEvent::POINTER_ACTION_PULL_OUT_WINDOW,
70f857971dSopenharmony_ci};
71f857971dSopenharmony_ci
72f857971dSopenharmony_civoid CooperateIn::Initial::BuildChains(std::shared_ptr<Initial> self, CooperateIn &parent)
73f857971dSopenharmony_ci{
74f857971dSopenharmony_ci    auto s11 = std::make_shared<RelayConfirmation>(parent, self);
75f857971dSopenharmony_ci    self->relay_ = s11;
76f857971dSopenharmony_ci    s11->SetNext(self);
77f857971dSopenharmony_ci}
78f857971dSopenharmony_ci
79f857971dSopenharmony_civoid CooperateIn::Initial::RemoveChains(std::shared_ptr<Initial> self)
80f857971dSopenharmony_ci{
81f857971dSopenharmony_ci    if (self->relay_ != nullptr) {
82f857971dSopenharmony_ci        self->relay_->SetNext(nullptr);
83f857971dSopenharmony_ci        self->relay_ = nullptr;
84f857971dSopenharmony_ci    }
85f857971dSopenharmony_ci}
86f857971dSopenharmony_ci
87f857971dSopenharmony_ciCooperateIn::Initial::Initial(CooperateIn &parent)
88f857971dSopenharmony_ci    : ICooperateStep(parent, nullptr), parent_(parent)
89f857971dSopenharmony_ci{
90f857971dSopenharmony_ci    AddHandler(CooperateEventType::DISABLE, [this](Context &context, const CooperateEvent &event) {
91f857971dSopenharmony_ci        this->OnDisable(context, event);
92f857971dSopenharmony_ci    });
93f857971dSopenharmony_ci    AddHandler(CooperateEventType::START, [this](Context &context, const CooperateEvent &event) {
94f857971dSopenharmony_ci        this->OnStart(context, event);
95f857971dSopenharmony_ci    });
96f857971dSopenharmony_ci    AddHandler(CooperateEventType::STOP, [this](Context &context, const CooperateEvent &event) {
97f857971dSopenharmony_ci        this->OnStop(context, event);
98f857971dSopenharmony_ci    });
99f857971dSopenharmony_ci    AddHandler(CooperateEventType::APP_CLOSED, [this](Context &context, const CooperateEvent &event) {
100f857971dSopenharmony_ci        this->OnAppClosed(context, event);
101f857971dSopenharmony_ci    });
102f857971dSopenharmony_ci    AddHandler(CooperateEventType::INPUT_POINTER_EVENT, [this](Context &context, const CooperateEvent &event) {
103f857971dSopenharmony_ci        this->OnPointerEvent(context, event);
104f857971dSopenharmony_ci    });
105f857971dSopenharmony_ci    AddHandler(CooperateEventType::DDM_BOARD_OFFLINE, [this](Context &context, const CooperateEvent &event) {
106f857971dSopenharmony_ci        this->OnBoardOffline(context, event);
107f857971dSopenharmony_ci    });
108f857971dSopenharmony_ci    AddHandler(CooperateEventType::DDP_COOPERATE_SWITCH_CHANGED,
109f857971dSopenharmony_ci        [this](Context &context, const CooperateEvent &event) {
110f857971dSopenharmony_ci            this->OnSwitchChanged(context, event);
111f857971dSopenharmony_ci    });
112f857971dSopenharmony_ci    AddHandler(CooperateEventType::DSOFTBUS_SESSION_CLOSED,
113f857971dSopenharmony_ci        [this](Context &context, const CooperateEvent &event) {
114f857971dSopenharmony_ci            this->OnSoftbusSessionClosed(context, event);
115f857971dSopenharmony_ci    });
116f857971dSopenharmony_ci    AddHandler(CooperateEventType::DSOFTBUS_START_COOPERATE,
117f857971dSopenharmony_ci        [this](Context &context, const CooperateEvent &event) {
118f857971dSopenharmony_ci            this->OnRemoteStart(context, event);
119f857971dSopenharmony_ci    });
120f857971dSopenharmony_ci    AddHandler(CooperateEventType::DSOFTBUS_STOP_COOPERATE,
121f857971dSopenharmony_ci        [this](Context &context, const CooperateEvent &event) {
122f857971dSopenharmony_ci            this->OnRemoteStop(context, event);
123f857971dSopenharmony_ci    });
124f857971dSopenharmony_ci    AddHandler(CooperateEventType::UPDATE_COOPERATE_FLAG,
125f857971dSopenharmony_ci        [this](Context &context, const CooperateEvent &event) {
126f857971dSopenharmony_ci            this->OnUpdateCooperateFlag(context, event);
127f857971dSopenharmony_ci    });
128f857971dSopenharmony_ci    AddHandler(CooperateEventType::DSOFTBUS_INPUT_DEV_SYNC,
129f857971dSopenharmony_ci        [this](Context &context, const CooperateEvent &event) {
130f857971dSopenharmony_ci            this->OnRemoteInputDevice(context, event);
131f857971dSopenharmony_ci    });
132f857971dSopenharmony_ci}
133f857971dSopenharmony_ci
134f857971dSopenharmony_civoid CooperateIn::Initial::OnDisable(Context &context, const CooperateEvent &event)
135f857971dSopenharmony_ci{
136f857971dSopenharmony_ci    FI_HILOGI("[disable cooperation] Stop cooperation");
137f857971dSopenharmony_ci    parent_.StopCooperate(context, event);
138f857971dSopenharmony_ci}
139f857971dSopenharmony_ci
140f857971dSopenharmony_civoid CooperateIn::Initial::OnStart(Context &context, const CooperateEvent &event)
141f857971dSopenharmony_ci{
142f857971dSopenharmony_ci    CALL_INFO_TRACE;
143f857971dSopenharmony_ci    StartCooperateEvent startEvent = std::get<StartCooperateEvent>(event.event);
144f857971dSopenharmony_ci
145f857971dSopenharmony_ci    if (context.IsLocal(startEvent.remoteNetworkId)) {
146f857971dSopenharmony_ci        DSoftbusStartCooperateFinished result {
147f857971dSopenharmony_ci            .success = false,
148f857971dSopenharmony_ci            .errCode = static_cast<int32_t>(CoordinationErrCode::UNEXPECTED_START_CALL)
149f857971dSopenharmony_ci        };
150f857971dSopenharmony_ci        context.eventMgr_.StartCooperateFinish(result);
151f857971dSopenharmony_ci        return;
152f857971dSopenharmony_ci    }
153f857971dSopenharmony_ci    FI_HILOGI("[start] start cooperation(%{public}s, %{public}d)",
154f857971dSopenharmony_ci        Utility::Anonymize(startEvent.remoteNetworkId).c_str(), startEvent.startDeviceId);
155f857971dSopenharmony_ci    context.eventMgr_.StartCooperate(startEvent);
156f857971dSopenharmony_ci
157f857971dSopenharmony_ci    if (context.IsPeer(startEvent.remoteNetworkId)) {
158f857971dSopenharmony_ci        OnComeBack(context, event);
159f857971dSopenharmony_ci    } else {
160f857971dSopenharmony_ci        OnRelay(context, event);
161f857971dSopenharmony_ci    }
162f857971dSopenharmony_ci}
163f857971dSopenharmony_ci
164f857971dSopenharmony_civoid CooperateIn::Initial::OnComeBack(Context &context, const CooperateEvent &event)
165f857971dSopenharmony_ci{
166f857971dSopenharmony_ci    CALL_INFO_TRACE;
167f857971dSopenharmony_ci    context.inputEventBuilder_.Disable();
168f857971dSopenharmony_ci    FI_HILOGI("[come back] To \'%{public}s\'", Utility::Anonymize(context.Peer()).c_str());
169f857971dSopenharmony_ci    DSoftbusComeBack notice {
170f857971dSopenharmony_ci        .originNetworkId = context.Local(),
171f857971dSopenharmony_ci        .success = true,
172f857971dSopenharmony_ci        .cursorPos = context.NormalizedCursorPosition(),
173f857971dSopenharmony_ci    };
174f857971dSopenharmony_ci    context.OnStartCooperate(notice.extra);
175f857971dSopenharmony_ci    if (context.dsoftbus_.ComeBack(context.Peer(), notice) != RET_OK) {
176f857971dSopenharmony_ci        notice.success = false;
177f857971dSopenharmony_ci        notice.errCode = static_cast<int32_t>(CoordinationErrCode::SEND_PACKET_FAILED);
178f857971dSopenharmony_ci    }
179f857971dSopenharmony_ci    context.eventMgr_.StartCooperateFinish(notice);
180f857971dSopenharmony_ci    context.inputDevMgr_.RemoveVirtualInputDevice(context.Peer());
181f857971dSopenharmony_ci    TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
182f857971dSopenharmony_ci    context.OnBack();
183f857971dSopenharmony_ci}
184f857971dSopenharmony_ci
185f857971dSopenharmony_civoid CooperateIn::Initial::OnRelay(Context &context, const CooperateEvent &event)
186f857971dSopenharmony_ci{
187f857971dSopenharmony_ci    CALL_INFO_TRACE;
188f857971dSopenharmony_ci    StartCooperateEvent startEvent = std::get<StartCooperateEvent>(event.event);
189f857971dSopenharmony_ci    parent_.process_.StartCooperate(context, startEvent);
190f857971dSopenharmony_ci    FI_HILOGI("[relay cooperate] To \'%{public}s\'", Utility::Anonymize(parent_.process_.Peer()).c_str());
191f857971dSopenharmony_ci
192f857971dSopenharmony_ci    if (relay_ != nullptr) {
193f857971dSopenharmony_ci        Switch(relay_);
194f857971dSopenharmony_ci        relay_->OnProgress(context, event);
195f857971dSopenharmony_ci    }
196f857971dSopenharmony_ci}
197f857971dSopenharmony_ci
198f857971dSopenharmony_civoid CooperateIn::Initial::OnStop(Context &context, const CooperateEvent &event)
199f857971dSopenharmony_ci{
200f857971dSopenharmony_ci    CALL_INFO_TRACE;
201f857971dSopenharmony_ci    StopCooperateEvent param = std::get<StopCooperateEvent>(event.event);
202f857971dSopenharmony_ci
203f857971dSopenharmony_ci    context.eventMgr_.StopCooperate(param);
204f857971dSopenharmony_ci    parent_.StopCooperate(context, event);
205f857971dSopenharmony_ci
206f857971dSopenharmony_ci    param.networkId = context.Peer();
207f857971dSopenharmony_ci    DSoftbusStopCooperateFinished notice {
208f857971dSopenharmony_ci        .networkId = context.Peer(),
209f857971dSopenharmony_ci        .normal = true,
210f857971dSopenharmony_ci    };
211f857971dSopenharmony_ci    context.eventMgr_.StopCooperateFinish(notice);
212f857971dSopenharmony_ci
213f857971dSopenharmony_ci    parent_.UnchainConnections(context, param);
214f857971dSopenharmony_ci}
215f857971dSopenharmony_ci
216f857971dSopenharmony_civoid CooperateIn::Initial::OnRemoteStart(Context &context, const CooperateEvent &event)
217f857971dSopenharmony_ci{
218f857971dSopenharmony_ci    CALL_INFO_TRACE;
219f857971dSopenharmony_ci    DSoftbusStartCooperate notice = std::get<DSoftbusStartCooperate>(event.event);
220f857971dSopenharmony_ci
221f857971dSopenharmony_ci    if (context.IsPeer(notice.networkId) || context.IsLocal(notice.networkId)) {
222f857971dSopenharmony_ci        return;
223f857971dSopenharmony_ci    }
224f857971dSopenharmony_ci    context.OnResetCooperation();
225f857971dSopenharmony_ci    context.OnRemoteStartCooperate(notice.extra);
226f857971dSopenharmony_ci    context.eventMgr_.RemoteStart(notice);
227f857971dSopenharmony_ci
228f857971dSopenharmony_ci    DSoftbusStopCooperate stopNotice {};
229f857971dSopenharmony_ci    context.dsoftbus_.StopCooperate(context.Peer(), stopNotice);
230f857971dSopenharmony_ci
231f857971dSopenharmony_ci    context.RemoteStartSuccess(notice);
232f857971dSopenharmony_ci    context.inputEventBuilder_.Update(context);
233f857971dSopenharmony_ci    context.eventMgr_.RemoteStartFinish(notice);
234f857971dSopenharmony_ci    FI_HILOGI("[remote start] Cooperation with \'%{public}s\' established", Utility::Anonymize(context.Peer()).c_str());
235f857971dSopenharmony_ci    context.OnTransitionIn();
236f857971dSopenharmony_ci}
237f857971dSopenharmony_ci
238f857971dSopenharmony_civoid CooperateIn::Initial::OnRemoteStop(Context &context, const CooperateEvent &event)
239f857971dSopenharmony_ci{
240f857971dSopenharmony_ci    DSoftbusStopCooperate notice = std::get<DSoftbusStopCooperate>(event.event);
241f857971dSopenharmony_ci
242f857971dSopenharmony_ci    if (!context.IsPeer(notice.networkId)) {
243f857971dSopenharmony_ci        return;
244f857971dSopenharmony_ci    }
245f857971dSopenharmony_ci    FI_HILOGI("[remote stop] Notification from \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
246f857971dSopenharmony_ci    context.eventMgr_.RemoteStop(notice);
247f857971dSopenharmony_ci    context.inputEventBuilder_.Disable();
248f857971dSopenharmony_ci    context.eventMgr_.RemoteStopFinish(notice);
249f857971dSopenharmony_ci    context.inputDevMgr_.RemoveVirtualInputDevice(context.Peer());
250f857971dSopenharmony_ci    TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
251f857971dSopenharmony_ci    context.OnResetCooperation();
252f857971dSopenharmony_ci}
253f857971dSopenharmony_ci
254f857971dSopenharmony_civoid CooperateIn::Initial::OnAppClosed(Context &context, const CooperateEvent &event)
255f857971dSopenharmony_ci{
256f857971dSopenharmony_ci    FI_HILOGI("[app closed] Close all connections");
257f857971dSopenharmony_ci    context.dsoftbus_.CloseAllSessions();
258f857971dSopenharmony_ci    FI_HILOGI("[app closed] Stop cooperation");
259f857971dSopenharmony_ci    parent_.StopCooperate(context, event);
260f857971dSopenharmony_ci}
261f857971dSopenharmony_ci
262f857971dSopenharmony_civoid CooperateIn::Initial::OnPointerEvent(Context &context, const CooperateEvent &event)
263f857971dSopenharmony_ci{
264f857971dSopenharmony_ci    InputPointerEvent notice = std::get<InputPointerEvent>(event.event);
265f857971dSopenharmony_ci
266f857971dSopenharmony_ci    if ((notice.sourceType != MMI::PointerEvent::SOURCE_TYPE_MOUSE) ||
267f857971dSopenharmony_ci        (filterPointerActions_.find(notice.pointerAction) != filterPointerActions_.end()) ||
268f857971dSopenharmony_ci        !InputEventBuilder::IsLocalEvent(notice)) {
269f857971dSopenharmony_ci        return;
270f857971dSopenharmony_ci    }
271f857971dSopenharmony_ci    FI_HILOGI("Stop cooperation on operation of local pointer");
272f857971dSopenharmony_ci    context.OnPointerEvent(notice);
273f857971dSopenharmony_ci    parent_.StopCooperate(context, event);
274f857971dSopenharmony_ci}
275f857971dSopenharmony_ci
276f857971dSopenharmony_civoid CooperateIn::Initial::OnBoardOffline(Context &context, const CooperateEvent &event)
277f857971dSopenharmony_ci{
278f857971dSopenharmony_ci    DDMBoardOfflineEvent notice = std::get<DDMBoardOfflineEvent>(event.event);
279f857971dSopenharmony_ci
280f857971dSopenharmony_ci    if (!context.IsPeer(notice.networkId)) {
281f857971dSopenharmony_ci        return;
282f857971dSopenharmony_ci    }
283f857971dSopenharmony_ci    FI_HILOGI("[board offline] Peer(\'%{public}s\') is offline", Utility::Anonymize(notice.networkId).c_str());
284f857971dSopenharmony_ci    parent_.StopCooperate(context, event);
285f857971dSopenharmony_ci}
286f857971dSopenharmony_ci
287f857971dSopenharmony_civoid CooperateIn::Initial::OnSwitchChanged(Context &context, const CooperateEvent &event)
288f857971dSopenharmony_ci{
289f857971dSopenharmony_ci    DDPCooperateSwitchChanged notice = std::get<DDPCooperateSwitchChanged>(event.event);
290f857971dSopenharmony_ci
291f857971dSopenharmony_ci    if (!context.IsPeer(notice.networkId) || notice.normal) {
292f857971dSopenharmony_ci        return;
293f857971dSopenharmony_ci    }
294f857971dSopenharmony_ci    FI_HILOGI("[switch off] Peer(\'%{public}s\') switch off", Utility::Anonymize(notice.networkId).c_str());
295f857971dSopenharmony_ci    parent_.StopCooperate(context, event);
296f857971dSopenharmony_ci}
297f857971dSopenharmony_ci
298f857971dSopenharmony_civoid CooperateIn::Initial::OnSoftbusSessionClosed(Context &context, const CooperateEvent &event)
299f857971dSopenharmony_ci{
300f857971dSopenharmony_ci    DSoftbusSessionClosed notice = std::get<DSoftbusSessionClosed>(event.event);
301f857971dSopenharmony_ci
302f857971dSopenharmony_ci    if (!context.IsPeer(notice.networkId)) {
303f857971dSopenharmony_ci        return;
304f857971dSopenharmony_ci    }
305f857971dSopenharmony_ci    FI_HILOGI("[softbus session closed] Disconnected with \'%{public}s\'",
306f857971dSopenharmony_ci        Utility::Anonymize(notice.networkId).c_str());
307f857971dSopenharmony_ci    parent_.StopCooperate(context, event);
308f857971dSopenharmony_ci    context.eventMgr_.OnSoftbusSessionClosed(notice);
309f857971dSopenharmony_ci}
310f857971dSopenharmony_ci
311f857971dSopenharmony_civoid CooperateIn::Initial::OnRemoteInputDevice(Context &context, const CooperateEvent &event)
312f857971dSopenharmony_ci{
313f857971dSopenharmony_ci    CALL_INFO_TRACE;
314f857971dSopenharmony_ci    DSoftbusSyncInputDevice notice = std::get<DSoftbusSyncInputDevice>(event.event);
315f857971dSopenharmony_ci    if (!context.IsPeer(notice.networkId)) {
316f857971dSopenharmony_ci        return;
317f857971dSopenharmony_ci    }
318f857971dSopenharmony_ci    FI_HILOGI("Remote input device from \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
319f857971dSopenharmony_ci    context.inputDevMgr_.AddVirtualInputDevice(notice.networkId);
320f857971dSopenharmony_ci}
321f857971dSopenharmony_ci
322f857971dSopenharmony_civoid CooperateIn::Initial::OnRemoteHotPlug(Context &context, const CooperateEvent &event)
323f857971dSopenharmony_ci{
324f857971dSopenharmony_ci    DSoftbusHotPlugEvent notice = std::get<DSoftbusHotPlugEvent>(event.event);
325f857971dSopenharmony_ci    if (!context.IsPeer(notice.networkId)) {
326f857971dSopenharmony_ci        return;
327f857971dSopenharmony_ci    }
328f857971dSopenharmony_ci    FI_HILOGI("Remote hot plug event from \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
329f857971dSopenharmony_ci}
330f857971dSopenharmony_ci
331f857971dSopenharmony_civoid CooperateIn::Initial::OnUpdateCooperateFlag(Context &context, const CooperateEvent &event)
332f857971dSopenharmony_ci{
333f857971dSopenharmony_ci    UpdateCooperateFlagEvent notice = std::get<UpdateCooperateFlagEvent>(event.event);
334f857971dSopenharmony_ci    uint32_t changed = (notice.mask & (context.CooperateFlag() ^ notice.flag));
335f857971dSopenharmony_ci    context.UpdateCooperateFlag(notice);
336f857971dSopenharmony_ci
337f857971dSopenharmony_ci    if (changed & COOPERATE_FLAG_FREEZE_CURSOR) {
338f857971dSopenharmony_ci        FI_HILOGI("Toggle freezing state of cursor");
339f857971dSopenharmony_ci        if (notice.flag & COOPERATE_FLAG_FREEZE_CURSOR) {
340f857971dSopenharmony_ci            context.inputEventBuilder_.Freeze();
341f857971dSopenharmony_ci        } else {
342f857971dSopenharmony_ci            context.inputEventBuilder_.Thaw();
343f857971dSopenharmony_ci        }
344f857971dSopenharmony_ci    }
345f857971dSopenharmony_ci}
346f857971dSopenharmony_ci
347f857971dSopenharmony_civoid CooperateIn::Initial::OnProgress(Context &context, const CooperateEvent &event)
348f857971dSopenharmony_ci{}
349f857971dSopenharmony_ci
350f857971dSopenharmony_civoid CooperateIn::Initial::OnReset(Context &context, const CooperateEvent &event)
351f857971dSopenharmony_ci{}
352f857971dSopenharmony_ci
353f857971dSopenharmony_ciCooperateIn::RelayConfirmation::RelayConfirmation(CooperateIn &parent, std::shared_ptr<ICooperateStep> prev)
354f857971dSopenharmony_ci    : ICooperateStep(parent, prev), parent_(parent)
355f857971dSopenharmony_ci{
356f857971dSopenharmony_ci    AddHandler(CooperateEventType::DISABLE, [this](Context &context, const CooperateEvent &event) {
357f857971dSopenharmony_ci        this->OnDisable(context, event);
358f857971dSopenharmony_ci    });
359f857971dSopenharmony_ci    AddHandler(CooperateEventType::STOP, [this](Context &context, const CooperateEvent &event) {
360f857971dSopenharmony_ci        this->OnStop(context, event);
361f857971dSopenharmony_ci    });
362f857971dSopenharmony_ci    AddHandler(CooperateEventType::APP_CLOSED, [this](Context &context, const CooperateEvent &event) {
363f857971dSopenharmony_ci        this->OnAppClosed(context, event);
364f857971dSopenharmony_ci    });
365f857971dSopenharmony_ci    AddHandler(CooperateEventType::INPUT_POINTER_EVENT,
366f857971dSopenharmony_ci        [this](Context &context, const CooperateEvent &event) {
367f857971dSopenharmony_ci            this->OnPointerEvent(context, event);
368f857971dSopenharmony_ci    });
369f857971dSopenharmony_ci    AddHandler(CooperateEventType::DDM_BOARD_OFFLINE,
370f857971dSopenharmony_ci        [this](Context &context, const CooperateEvent &event) {
371f857971dSopenharmony_ci            this->OnBoardOffline(context, event);
372f857971dSopenharmony_ci    });
373f857971dSopenharmony_ci    AddHandler(CooperateEventType::DDP_COOPERATE_SWITCH_CHANGED,
374f857971dSopenharmony_ci        [this](Context &context, const CooperateEvent &event) {
375f857971dSopenharmony_ci            this->OnSwitchChanged(context, event);
376f857971dSopenharmony_ci    });
377f857971dSopenharmony_ci    AddHandler(CooperateEventType::DSOFTBUS_SESSION_CLOSED,
378f857971dSopenharmony_ci        [this](Context &context, const CooperateEvent &event) {
379f857971dSopenharmony_ci            this->OnSoftbusSessionClosed(context, event);
380f857971dSopenharmony_ci    });
381f857971dSopenharmony_ci    AddHandler(CooperateEventType::DSOFTBUS_RELAY_COOPERATE_FINISHED,
382f857971dSopenharmony_ci        [this](Context &context, const CooperateEvent &event) {
383f857971dSopenharmony_ci            this->OnResponse(context, event);
384f857971dSopenharmony_ci    });
385f857971dSopenharmony_ci    AddHandler(CooperateEventType::DSOFTBUS_START_COOPERATE,
386f857971dSopenharmony_ci        [this](Context &context, const CooperateEvent &event) {
387f857971dSopenharmony_ci            this->OnRemoteStart(context, event);
388f857971dSopenharmony_ci    });
389f857971dSopenharmony_ci    AddHandler(CooperateEventType::DSOFTBUS_STOP_COOPERATE,
390f857971dSopenharmony_ci        [this](Context &context, const CooperateEvent &event) {
391f857971dSopenharmony_ci            this->OnRemoteStop(context, event);
392f857971dSopenharmony_ci    });
393f857971dSopenharmony_ci}
394f857971dSopenharmony_ci
395f857971dSopenharmony_civoid CooperateIn::RelayConfirmation::OnDisable(Context &context, const CooperateEvent &event)
396f857971dSopenharmony_ci{
397f857971dSopenharmony_ci    FI_HILOGI("[relay cooperate] Disable cooperation");
398f857971dSopenharmony_ci    parent_.StopCooperate(context, event);
399f857971dSopenharmony_ci    OnReset(context, event);
400f857971dSopenharmony_ci}
401f857971dSopenharmony_ci
402f857971dSopenharmony_civoid CooperateIn::RelayConfirmation::OnStop(Context &context, const CooperateEvent &event)
403f857971dSopenharmony_ci{
404f857971dSopenharmony_ci    FI_HILOGI("[relay cooperate] Stop cooperation");
405f857971dSopenharmony_ci    parent_.StopCooperate(context, event);
406f857971dSopenharmony_ci    OnReset(context, event);
407f857971dSopenharmony_ci
408f857971dSopenharmony_ci    StopCooperateEvent param = std::get<StopCooperateEvent>(event.event);
409f857971dSopenharmony_ci    parent_.UnchainConnections(context, param);
410f857971dSopenharmony_ci}
411f857971dSopenharmony_ci
412f857971dSopenharmony_civoid CooperateIn::RelayConfirmation::OnRemoteStart(Context &context, const CooperateEvent &event)
413f857971dSopenharmony_ci{
414f857971dSopenharmony_ci    CALL_INFO_TRACE;
415f857971dSopenharmony_ci    DSoftbusStartCooperate notice = std::get<DSoftbusStartCooperate>(event.event);
416f857971dSopenharmony_ci
417f857971dSopenharmony_ci    if (context.IsPeer(notice.networkId) || context.IsLocal(notice.networkId)) {
418f857971dSopenharmony_ci        return;
419f857971dSopenharmony_ci    }
420f857971dSopenharmony_ci    FI_HILOGI("[remote start] Notification from %{public}s", Utility::Anonymize(notice.networkId).c_str());
421f857971dSopenharmony_ci    if (parent_.process_.IsPeer(notice.networkId)) {
422f857971dSopenharmony_ci        auto ret = context.Sender().Send(event);
423f857971dSopenharmony_ci        if (ret != Channel<CooperateEvent>::NO_ERROR) {
424f857971dSopenharmony_ci            FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
425f857971dSopenharmony_ci        }
426f857971dSopenharmony_ci        OnReset(context, event);
427f857971dSopenharmony_ci        return;
428f857971dSopenharmony_ci    }
429f857971dSopenharmony_ci    parent_.env_->GetTimerManager().AddTimer(DEFAULT_COOLING_TIME, REPEAT_ONCE,
430f857971dSopenharmony_ci        [sender = context.Sender(), event]() mutable {
431f857971dSopenharmony_ci            auto ret = sender.Send(event);
432f857971dSopenharmony_ci            if (ret != Channel<CooperateEvent>::NO_ERROR) {
433f857971dSopenharmony_ci                FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
434f857971dSopenharmony_ci            }
435f857971dSopenharmony_ci        });
436f857971dSopenharmony_ci}
437f857971dSopenharmony_ci
438f857971dSopenharmony_civoid CooperateIn::RelayConfirmation::OnRemoteStop(Context &context, const CooperateEvent &event)
439f857971dSopenharmony_ci{
440f857971dSopenharmony_ci    DSoftbusStopCooperate notice = std::get<DSoftbusStopCooperate>(event.event);
441f857971dSopenharmony_ci
442f857971dSopenharmony_ci    if (!context.IsPeer(notice.networkId)) {
443f857971dSopenharmony_ci        return;
444f857971dSopenharmony_ci    }
445f857971dSopenharmony_ci    FI_HILOGI("[remote stop] Notification from %{public}s", Utility::Anonymize(notice.networkId).c_str());
446f857971dSopenharmony_ci    auto ret = context.Sender().Send(event);
447f857971dSopenharmony_ci    if (ret != Channel<CooperateEvent>::NO_ERROR) {
448f857971dSopenharmony_ci        FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
449f857971dSopenharmony_ci    }
450f857971dSopenharmony_ci    OnReset(context, event);
451f857971dSopenharmony_ci}
452f857971dSopenharmony_ci
453f857971dSopenharmony_civoid CooperateIn::RelayConfirmation::OnAppClosed(Context &context, const CooperateEvent &event)
454f857971dSopenharmony_ci{
455f857971dSopenharmony_ci    FI_HILOGI("[app closed] Close all connections");
456f857971dSopenharmony_ci    context.dsoftbus_.CloseAllSessions();
457f857971dSopenharmony_ci    FI_HILOGI("[relay cooperate] Stop cooperation on app closed");
458f857971dSopenharmony_ci    parent_.StopCooperate(context, event);
459f857971dSopenharmony_ci    OnReset(context, event);
460f857971dSopenharmony_ci}
461f857971dSopenharmony_ci
462f857971dSopenharmony_civoid CooperateIn::RelayConfirmation::OnPointerEvent(Context &context, const CooperateEvent &event)
463f857971dSopenharmony_ci{
464f857971dSopenharmony_ci    InputPointerEvent notice = std::get<InputPointerEvent>(event.event);
465f857971dSopenharmony_ci
466f857971dSopenharmony_ci    if ((notice.sourceType != MMI::PointerEvent::SOURCE_TYPE_MOUSE) ||
467f857971dSopenharmony_ci        !InputEventBuilder::IsLocalEvent(notice)) {
468f857971dSopenharmony_ci        return;
469f857971dSopenharmony_ci    }
470f857971dSopenharmony_ci    FI_HILOGI("[relay cooperate] Stop cooperation on operation of local pointer");
471f857971dSopenharmony_ci    context.OnPointerEvent(notice);
472f857971dSopenharmony_ci    parent_.StopCooperate(context, event);
473f857971dSopenharmony_ci    OnReset(context, event);
474f857971dSopenharmony_ci}
475f857971dSopenharmony_ci
476f857971dSopenharmony_civoid CooperateIn::RelayConfirmation::OnBoardOffline(Context &context, const CooperateEvent &event)
477f857971dSopenharmony_ci{
478f857971dSopenharmony_ci    DDMBoardOfflineEvent notice = std::get<DDMBoardOfflineEvent>(event.event);
479f857971dSopenharmony_ci
480f857971dSopenharmony_ci    if (!context.IsPeer(notice.networkId) && !parent_.process_.IsPeer(notice.networkId)) {
481f857971dSopenharmony_ci        return;
482f857971dSopenharmony_ci    }
483f857971dSopenharmony_ci    FI_HILOGI("[relay cooperate] Peer(%{public}s) is offline", Utility::Anonymize(notice.networkId).c_str());
484f857971dSopenharmony_ci    if (context.IsPeer(notice.networkId)) {
485f857971dSopenharmony_ci        parent_.StopCooperate(context, event);
486f857971dSopenharmony_ci    }
487f857971dSopenharmony_ci    OnReset(context, event);
488f857971dSopenharmony_ci}
489f857971dSopenharmony_ci
490f857971dSopenharmony_civoid CooperateIn::RelayConfirmation::OnSwitchChanged(Context &context, const CooperateEvent &event)
491f857971dSopenharmony_ci{
492f857971dSopenharmony_ci    DDPCooperateSwitchChanged notice = std::get<DDPCooperateSwitchChanged>(event.event);
493f857971dSopenharmony_ci
494f857971dSopenharmony_ci    if (notice.normal ||
495f857971dSopenharmony_ci        (!context.IsPeer(notice.networkId) &&
496f857971dSopenharmony_ci         !parent_.process_.IsPeer(notice.networkId))) {
497f857971dSopenharmony_ci        return;
498f857971dSopenharmony_ci    }
499f857971dSopenharmony_ci    FI_HILOGI("[relay cooperate] Peer(\'%{public}s\') switch off", Utility::Anonymize(notice.networkId).c_str());
500f857971dSopenharmony_ci    if (context.IsPeer(notice.networkId)) {
501f857971dSopenharmony_ci        parent_.StopCooperate(context, event);
502f857971dSopenharmony_ci    }
503f857971dSopenharmony_ci    OnReset(context, event);
504f857971dSopenharmony_ci}
505f857971dSopenharmony_ci
506f857971dSopenharmony_civoid CooperateIn::RelayConfirmation::OnSoftbusSessionClosed(Context &context, const CooperateEvent &event)
507f857971dSopenharmony_ci{
508f857971dSopenharmony_ci    DSoftbusSessionClosed notice = std::get<DSoftbusSessionClosed>(event.event);
509f857971dSopenharmony_ci
510f857971dSopenharmony_ci    if (!context.IsPeer(notice.networkId) && !parent_.process_.IsPeer(notice.networkId)) {
511f857971dSopenharmony_ci        return;
512f857971dSopenharmony_ci    }
513f857971dSopenharmony_ci    FI_HILOGI("[relay cooperate] Disconnected with \'%{public}s\'", Utility::Anonymize(notice.networkId).c_str());
514f857971dSopenharmony_ci    if (context.IsPeer(notice.networkId)) {
515f857971dSopenharmony_ci        parent_.StopCooperate(context, event);
516f857971dSopenharmony_ci    }
517f857971dSopenharmony_ci    OnReset(context, event);
518f857971dSopenharmony_ci}
519f857971dSopenharmony_ci
520f857971dSopenharmony_civoid CooperateIn::RelayConfirmation::OnResponse(Context &context, const CooperateEvent &event)
521f857971dSopenharmony_ci{
522f857971dSopenharmony_ci    DSoftbusRelayCooperateFinished notice = std::get<DSoftbusRelayCooperateFinished>(event.event);
523f857971dSopenharmony_ci
524f857971dSopenharmony_ci    if (!context.IsPeer(notice.networkId)) {
525f857971dSopenharmony_ci        return;
526f857971dSopenharmony_ci    }
527f857971dSopenharmony_ci    FI_HILOGI("[relay cooperate] \'%{public}s\' respond", Utility::Anonymize(notice.networkId).c_str());
528f857971dSopenharmony_ci    parent_.env_->GetTimerManager().RemoveTimer(timerId_);
529f857971dSopenharmony_ci    if (notice.normal) {
530f857971dSopenharmony_ci        OnNormal(context, event);
531f857971dSopenharmony_ci        Proceed(context, event);
532f857971dSopenharmony_ci    } else {
533f857971dSopenharmony_ci        OnReset(context, event);
534f857971dSopenharmony_ci    }
535f857971dSopenharmony_ci}
536f857971dSopenharmony_ci
537f857971dSopenharmony_civoid CooperateIn::RelayConfirmation::OnNormal(Context &context, const CooperateEvent &event)
538f857971dSopenharmony_ci{
539f857971dSopenharmony_ci    FI_HILOGI("[relay cooperate] Cooperation with \'%{public}s\' established",
540f857971dSopenharmony_ci        Utility::Anonymize(parent_.process_.Peer()).c_str());
541f857971dSopenharmony_ci    context.inputEventBuilder_.Disable();
542f857971dSopenharmony_ci
543f857971dSopenharmony_ci    DSoftbusStartCooperate notice {
544f857971dSopenharmony_ci        .originNetworkId = context.Peer(),
545f857971dSopenharmony_ci        .success = true,
546f857971dSopenharmony_ci        .cursorPos = context.NormalizedCursorPosition(),
547f857971dSopenharmony_ci    };
548f857971dSopenharmony_ci    context.OnStartCooperate(notice.extra);
549f857971dSopenharmony_ci    context.dsoftbus_.StartCooperate(parent_.process_.Peer(), notice);
550f857971dSopenharmony_ci
551f857971dSopenharmony_ci    context.eventMgr_.StartCooperateFinish(notice);
552f857971dSopenharmony_ci    context.inputDevMgr_.RemoveVirtualInputDevice(context.Peer());
553f857971dSopenharmony_ci    TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
554f857971dSopenharmony_ci    context.OnRelayCooperation(parent_.process_.Peer(), context.NormalizedCursorPosition());
555f857971dSopenharmony_ci}
556f857971dSopenharmony_ci
557f857971dSopenharmony_civoid CooperateIn::RelayConfirmation::OnProgress(Context &context, const CooperateEvent &event)
558f857971dSopenharmony_ci{
559f857971dSopenharmony_ci    std::string remoteNetworkId = parent_.process_.Peer();
560f857971dSopenharmony_ci    FI_HILOGI("[relay cooperate] Connect \'%{public}s\'", Utility::Anonymize(remoteNetworkId).c_str());
561f857971dSopenharmony_ci    int32_t ret = context.dsoftbus_.OpenSession(remoteNetworkId);
562f857971dSopenharmony_ci    if (ret != RET_OK) {
563f857971dSopenharmony_ci        FI_HILOGE("[relay cooperate] Failed to connect to \'%{public}s\'", Utility::Anonymize(remoteNetworkId).c_str());
564f857971dSopenharmony_ci        OnReset(context, event);
565f857971dSopenharmony_ci        return;
566f857971dSopenharmony_ci    }
567f857971dSopenharmony_ci
568f857971dSopenharmony_ci    FI_HILOGI("[relay cooperate] Notify origin(\'%{public}s\')", Utility::Anonymize(context.Peer()).c_str());
569f857971dSopenharmony_ci    DSoftbusRelayCooperate notice {
570f857971dSopenharmony_ci        .targetNetworkId = parent_.process_.Peer(),
571f857971dSopenharmony_ci    };
572f857971dSopenharmony_ci    context.dsoftbus_.RelayCooperate(context.Peer(), notice);
573f857971dSopenharmony_ci
574f857971dSopenharmony_ci    timerId_ = parent_.env_->GetTimerManager().AddTimer(DEFAULT_TIMEOUT, REPEAT_ONCE,
575f857971dSopenharmony_ci        [sender = context.Sender(), remoteNetworkId = context.Peer()]() mutable {
576f857971dSopenharmony_ci            auto ret = sender.Send(CooperateEvent(
577f857971dSopenharmony_ci                CooperateEventType::DSOFTBUS_RELAY_COOPERATE_FINISHED,
578f857971dSopenharmony_ci                DSoftbusRelayCooperateFinished {
579f857971dSopenharmony_ci                    .networkId = remoteNetworkId,
580f857971dSopenharmony_ci                    .normal = false,
581f857971dSopenharmony_ci                }));
582f857971dSopenharmony_ci            if (ret != Channel<CooperateEvent>::NO_ERROR) {
583f857971dSopenharmony_ci                FI_HILOGE("Failed to send event via channel, error:%{public}d", ret);
584f857971dSopenharmony_ci            }
585f857971dSopenharmony_ci        });
586f857971dSopenharmony_ci}
587f857971dSopenharmony_ci
588f857971dSopenharmony_civoid CooperateIn::RelayConfirmation::OnReset(Context &context, const CooperateEvent &event)
589f857971dSopenharmony_ci{
590f857971dSopenharmony_ci    FI_HILOGI("[relay cooperate] reset cooperation with \'%{public}s\'",
591f857971dSopenharmony_ci        Utility::Anonymize(parent_.process_.Peer()).c_str());
592f857971dSopenharmony_ci    DSoftbusStartCooperateFinished result {
593f857971dSopenharmony_ci        .success = false
594f857971dSopenharmony_ci    };
595f857971dSopenharmony_ci    context.eventMgr_.StartCooperateFinish(result);
596f857971dSopenharmony_ci    Reset(context, event);
597f857971dSopenharmony_ci}
598f857971dSopenharmony_ci
599f857971dSopenharmony_civoid CooperateIn::StopCooperate(Context &context, const CooperateEvent &event)
600f857971dSopenharmony_ci{
601f857971dSopenharmony_ci    FI_HILOGI("Stop cooperation with \'%{public}s\'", Utility::Anonymize(context.Peer()).c_str());
602f857971dSopenharmony_ci    context.inputEventBuilder_.Disable();
603f857971dSopenharmony_ci    context.UpdateCursorPosition();
604f857971dSopenharmony_ci
605f857971dSopenharmony_ci    DSoftbusStopCooperate notice {};
606f857971dSopenharmony_ci    context.dsoftbus_.StopCooperate(context.Peer(), notice);
607f857971dSopenharmony_ci    context.inputDevMgr_.RemoveVirtualInputDevice(context.Peer());
608f857971dSopenharmony_ci    TransiteTo(context, CooperateState::COOPERATE_STATE_FREE);
609f857971dSopenharmony_ci    context.OnResetCooperation();
610f857971dSopenharmony_ci    SetPointerVisible(context);
611f857971dSopenharmony_ci}
612f857971dSopenharmony_ci
613f857971dSopenharmony_civoid CooperateIn::SetPointerVisible(Context &context)
614f857971dSopenharmony_ci{
615f857971dSopenharmony_ci    CHKPV(env_);
616f857971dSopenharmony_ci    bool hasLocalPointerDevice =  env_->GetDeviceManager().HasLocalPointerDevice();
617f857971dSopenharmony_ci    env_->GetInput().SetPointerVisibility(hasLocalPointerDevice, PRIORITY);
618f857971dSopenharmony_ci}
619f857971dSopenharmony_ci
620f857971dSopenharmony_civoid CooperateIn::UnchainConnections(Context &context, const StopCooperateEvent &event) const
621f857971dSopenharmony_ci{
622f857971dSopenharmony_ci    if (event.isUnchained) {
623f857971dSopenharmony_ci        FI_HILOGI("Unchain all connections");
624f857971dSopenharmony_ci        context.dsoftbus_.CloseAllSessions();
625f857971dSopenharmony_ci        context.eventMgr_.OnUnchain(event);
626f857971dSopenharmony_ci    }
627f857971dSopenharmony_ci}
628f857971dSopenharmony_ci} // namespace Cooperate
629f857971dSopenharmony_ci} // namespace DeviceStatus
630f857971dSopenharmony_ci} // namespace Msdp
631f857971dSopenharmony_ci} // namespace OHOS
632