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_free.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 "CooperateFree"
23f857971dSopenharmony_ci
24f857971dSopenharmony_cinamespace OHOS {
25f857971dSopenharmony_cinamespace Msdp {
26f857971dSopenharmony_cinamespace DeviceStatus {
27f857971dSopenharmony_cinamespace Cooperate {
28f857971dSopenharmony_ci
29f857971dSopenharmony_ciCooperateFree::CooperateFree(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_ciCooperateFree::~CooperateFree()
38f857971dSopenharmony_ci{
39f857971dSopenharmony_ci    Initial::RemoveChains(initial_);
40f857971dSopenharmony_ci}
41f857971dSopenharmony_ci
42f857971dSopenharmony_civoid CooperateFree::OnEvent(Context &context, const CooperateEvent &event)
43f857971dSopenharmony_ci{
44f857971dSopenharmony_ci    current_->OnEvent(context, event);
45f857971dSopenharmony_ci}
46f857971dSopenharmony_ci
47f857971dSopenharmony_civoid CooperateFree::OnEnterState(Context &context)
48f857971dSopenharmony_ci{
49f857971dSopenharmony_ci    CALL_INFO_TRACE;
50f857971dSopenharmony_ci}
51f857971dSopenharmony_ci
52f857971dSopenharmony_civoid CooperateFree::OnLeaveState(Context &context)
53f857971dSopenharmony_ci{
54f857971dSopenharmony_ci    CALL_INFO_TRACE;
55f857971dSopenharmony_ci    UpdateCooperateFlagEvent event {
56f857971dSopenharmony_ci        .mask = COOPERATE_FLAG_HIDE_CURSOR,
57f857971dSopenharmony_ci    };
58f857971dSopenharmony_ci    context.UpdateCooperateFlag(event);
59f857971dSopenharmony_ci}
60f857971dSopenharmony_ci
61f857971dSopenharmony_civoid CooperateFree::SetPointerVisible(Context &context)
62f857971dSopenharmony_ci{
63f857971dSopenharmony_ci    CHKPV(env_);
64f857971dSopenharmony_ci    bool hasLocalPointerDevice =  env_->GetDeviceManager().HasLocalPointerDevice();
65f857971dSopenharmony_ci    bool visible = !context.NeedHideCursor() && hasLocalPointerDevice;
66f857971dSopenharmony_ci    FI_HILOGI("Set pointer visible:%{public}s, HasLocalPointerDevice:%{public}s",
67f857971dSopenharmony_ci        visible ? "true" : "false", hasLocalPointerDevice ? "true" : "false");
68f857971dSopenharmony_ci    env_->GetInput().SetPointerVisibility(visible, PRIORITY);
69f857971dSopenharmony_ci}
70f857971dSopenharmony_ci
71f857971dSopenharmony_civoid CooperateFree::UnchainConnections(Context &context, const StopCooperateEvent &event) const
72f857971dSopenharmony_ci{
73f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
74f857971dSopenharmony_ci    if (event.isUnchained) {
75f857971dSopenharmony_ci        FI_HILOGI("Unchain all connections");
76f857971dSopenharmony_ci        context.dsoftbus_.CloseAllSessions();
77f857971dSopenharmony_ci        context.eventMgr_.OnUnchain(event);
78f857971dSopenharmony_ci    }
79f857971dSopenharmony_ci}
80f857971dSopenharmony_ci
81f857971dSopenharmony_ciCooperateFree::Initial::Initial(CooperateFree &parent)
82f857971dSopenharmony_ci    : ICooperateStep(parent, nullptr), parent_(parent)
83f857971dSopenharmony_ci{
84f857971dSopenharmony_ci    AddHandler(CooperateEventType::START, [this](Context &context, const CooperateEvent &event) {
85f857971dSopenharmony_ci        this->OnStart(context, event);
86f857971dSopenharmony_ci    });
87f857971dSopenharmony_ci    AddHandler(CooperateEventType::STOP, [this](Context &context, const CooperateEvent &event) {
88f857971dSopenharmony_ci        this->OnStop(context, event);
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::APP_CLOSED, [this](Context &context, const CooperateEvent &event) {
94f857971dSopenharmony_ci        this->OnAppClosed(context, event);
95f857971dSopenharmony_ci    });
96f857971dSopenharmony_ci    AddHandler(CooperateEventType::DSOFTBUS_START_COOPERATE, [this](Context &context, const CooperateEvent &event) {
97f857971dSopenharmony_ci        this->OnRemoteStart(context, event);
98f857971dSopenharmony_ci    });
99f857971dSopenharmony_ci    AddHandler(CooperateEventType::INPUT_POINTER_EVENT, [this](Context &context, const CooperateEvent &event) {
100f857971dSopenharmony_ci        this->OnPointerEvent(context, event);
101f857971dSopenharmony_ci    });
102f857971dSopenharmony_ci}
103f857971dSopenharmony_ci
104f857971dSopenharmony_civoid CooperateFree::Initial::OnProgress(Context &context, const CooperateEvent &event)
105f857971dSopenharmony_ci{}
106f857971dSopenharmony_ci
107f857971dSopenharmony_civoid CooperateFree::Initial::OnReset(Context &context, const CooperateEvent &event)
108f857971dSopenharmony_ci{}
109f857971dSopenharmony_ci
110f857971dSopenharmony_civoid CooperateFree::Initial::BuildChains(std::shared_ptr<Initial> initial, CooperateFree &parent)
111f857971dSopenharmony_ci{}
112f857971dSopenharmony_ci
113f857971dSopenharmony_civoid CooperateFree::Initial::RemoveChains(std::shared_ptr<Initial> initial)
114f857971dSopenharmony_ci{}
115f857971dSopenharmony_ci
116f857971dSopenharmony_civoid CooperateFree::Initial::OnStart(Context &context, const CooperateEvent &event)
117f857971dSopenharmony_ci{
118f857971dSopenharmony_ci    CALL_INFO_TRACE;
119f857971dSopenharmony_ci    StartCooperateEvent notice = std::get<StartCooperateEvent>(event.event);
120f857971dSopenharmony_ci    FI_HILOGI("[start cooperation] With \'%{public}s\'", Utility::Anonymize(notice.remoteNetworkId).c_str());
121f857971dSopenharmony_ci    context.StartCooperate(notice);
122f857971dSopenharmony_ci    context.eventMgr_.StartCooperate(notice);
123f857971dSopenharmony_ci
124f857971dSopenharmony_ci    int32_t ret = context.dsoftbus_.OpenSession(context.Peer());
125f857971dSopenharmony_ci    if (ret != RET_OK) {
126f857971dSopenharmony_ci        FI_HILOGE("[start cooperation] Failed to connect to \'%{public}s\'",
127f857971dSopenharmony_ci            Utility::Anonymize(context.Peer()).c_str());
128f857971dSopenharmony_ci        int32_t errNum = (ret == RET_ERR ? static_cast<int32_t>(CoordinationErrCode::OPEN_SESSION_FAILED) : ret);
129f857971dSopenharmony_ci        DSoftbusStartCooperateFinished failNotice {
130f857971dSopenharmony_ci            .success = false,
131f857971dSopenharmony_ci            .errCode = errNum
132f857971dSopenharmony_ci        };
133f857971dSopenharmony_ci        context.eventMgr_.StartCooperateFinish(failNotice);
134f857971dSopenharmony_ci        return;
135f857971dSopenharmony_ci    }
136f857971dSopenharmony_ci    DSoftbusStartCooperate startNotice {
137f857971dSopenharmony_ci        .originNetworkId = context.Local(),
138f857971dSopenharmony_ci        .success = true,
139f857971dSopenharmony_ci        .cursorPos = context.NormalizedCursorPosition(),
140f857971dSopenharmony_ci    };
141f857971dSopenharmony_ci    context.OnStartCooperate(startNotice.extra);
142f857971dSopenharmony_ci    context.dsoftbus_.StartCooperate(context.Peer(), startNotice);
143f857971dSopenharmony_ci    context.inputEventInterceptor_.Enable(context);
144f857971dSopenharmony_ci    context.eventMgr_.StartCooperateFinish(startNotice);
145f857971dSopenharmony_ci    FI_HILOGI("[start cooperation] Cooperation with \'%{public}s\' established",
146f857971dSopenharmony_ci        Utility::Anonymize(context.Peer()).c_str());
147f857971dSopenharmony_ci    TransiteTo(context, CooperateState::COOPERATE_STATE_OUT);
148f857971dSopenharmony_ci    context.OnTransitionOut();
149f857971dSopenharmony_ci#ifdef ENABLE_PERFORMANCE_CHECK
150f857971dSopenharmony_ci    std::ostringstream ss;
151f857971dSopenharmony_ci    ss << "start_cooperation_with_ " << Utility::Anonymize(context.Peer()).c_str();
152f857971dSopenharmony_ci    context.FinishTrace(ss.str());
153f857971dSopenharmony_ci#endif // ENABLE_PERFORMANCE_CHECK
154f857971dSopenharmony_ci}
155f857971dSopenharmony_ci
156f857971dSopenharmony_civoid CooperateFree::Initial::OnStop(Context &context, const CooperateEvent &event)
157f857971dSopenharmony_ci{
158f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
159f857971dSopenharmony_ci    StopCooperateEvent param = std::get<StopCooperateEvent>(event.event);
160f857971dSopenharmony_ci    context.eventMgr_.StopCooperate(param);
161f857971dSopenharmony_ci    param.networkId = context.Peer();
162f857971dSopenharmony_ci    DSoftbusStopCooperateFinished notice {
163f857971dSopenharmony_ci        .networkId = context.Peer(),
164f857971dSopenharmony_ci        .normal = true,
165f857971dSopenharmony_ci    };
166f857971dSopenharmony_ci    context.eventMgr_.StopCooperateFinish(notice);
167f857971dSopenharmony_ci    parent_.UnchainConnections(context, param);
168f857971dSopenharmony_ci}
169f857971dSopenharmony_ci
170f857971dSopenharmony_civoid CooperateFree::Initial::OnDisable(Context &context, const CooperateEvent &event)
171f857971dSopenharmony_ci{
172f857971dSopenharmony_ci    FI_HILOGI("[disable cooperation] Stop cooperation");
173f857971dSopenharmony_ci    CHKPV(parent_.env_);
174f857971dSopenharmony_ci    bool hasLocalPointerDevice =  parent_.env_->GetDeviceManager().HasLocalPointerDevice();
175f857971dSopenharmony_ci    FI_HILOGI("HasLocalPointerDevice:%{public}s", hasLocalPointerDevice ? "true" : "false");
176f857971dSopenharmony_ci    parent_.env_->GetInput().SetPointerVisibility(hasLocalPointerDevice, PRIORITY);
177f857971dSopenharmony_ci}
178f857971dSopenharmony_ci
179f857971dSopenharmony_civoid CooperateFree::Initial::OnAppClosed(Context &context, const CooperateEvent &event)
180f857971dSopenharmony_ci{
181f857971dSopenharmony_ci    FI_HILOGI("[app closed] Close all connections");
182f857971dSopenharmony_ci    context.dsoftbus_.CloseAllSessions();
183f857971dSopenharmony_ci}
184f857971dSopenharmony_ci
185f857971dSopenharmony_civoid CooperateFree::Initial::OnRemoteStart(Context &context, const CooperateEvent &event)
186f857971dSopenharmony_ci{
187f857971dSopenharmony_ci    CALL_INFO_TRACE;
188f857971dSopenharmony_ci    DSoftbusStartCooperate notice = std::get<DSoftbusStartCooperate>(event.event);
189f857971dSopenharmony_ci    context.OnRemoteStartCooperate(notice.extra);
190f857971dSopenharmony_ci    context.eventMgr_.RemoteStart(notice);
191f857971dSopenharmony_ci    context.RemoteStartSuccess(notice);
192f857971dSopenharmony_ci    context.inputEventBuilder_.Enable(context);
193f857971dSopenharmony_ci    context.eventMgr_.RemoteStartFinish(notice);
194f857971dSopenharmony_ci    context.inputDevMgr_.AddVirtualInputDevice(context.Peer());
195f857971dSopenharmony_ci    FI_HILOGI("[remote start] Cooperation with \'%{public}s\' established", Utility::Anonymize(context.Peer()).c_str());
196f857971dSopenharmony_ci    TransiteTo(context, CooperateState::COOPERATE_STATE_IN);
197f857971dSopenharmony_ci    context.OnTransitionIn();
198f857971dSopenharmony_ci}
199f857971dSopenharmony_ci
200f857971dSopenharmony_civoid CooperateFree::Initial::OnPointerEvent(Context &context, const CooperateEvent &event)
201f857971dSopenharmony_ci{
202f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
203f857971dSopenharmony_ci    InputPointerEvent notice = std::get<InputPointerEvent>(event.event);
204f857971dSopenharmony_ci    if (InputEventBuilder::IsLocalEvent(notice) && context.NeedHideCursor()) {
205f857971dSopenharmony_ci        UpdateCooperateFlagEvent event {
206f857971dSopenharmony_ci            .mask = COOPERATE_FLAG_HIDE_CURSOR,
207f857971dSopenharmony_ci        };
208f857971dSopenharmony_ci        context.UpdateCooperateFlag(event);
209f857971dSopenharmony_ci        parent_.SetPointerVisible(context);
210f857971dSopenharmony_ci    }
211f857971dSopenharmony_ci}
212f857971dSopenharmony_ci} // namespace Cooperate
213f857971dSopenharmony_ci} // namespace DeviceStatus
214f857971dSopenharmony_ci} // namespace Msdp
215f857971dSopenharmony_ci} // namespace OHOS
216