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