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
29 namespace {
30 const std::string FINGER_PRINT { "fingerprint_mouse" };
31 }
32
CooperateFree(IStateMachine & parent,IContext * env)33 CooperateFree::CooperateFree(IStateMachine &parent, IContext *env) : ICooperateState(parent), env_(env)
34 {
35 initial_ = std::make_shared<Initial>(*this);
36 Initial::BuildChains(initial_, *this);
37 current_ = initial_;
38 }
39
~CooperateFree()40 CooperateFree::~CooperateFree()
41 {
42 Initial::RemoveChains(initial_);
43 }
44
OnEvent(Context & context,const CooperateEvent & event)45 void CooperateFree::OnEvent(Context &context, const CooperateEvent &event)
46 {
47 current_->OnEvent(context, event);
48 }
49
OnEnterState(Context & context)50 void CooperateFree::OnEnterState(Context &context)
51 {
52 CALL_INFO_TRACE;
53 bool hasLocalPointerDevice = HasLocalPointerDevice();
54 FI_HILOGI("HasLocalPointerDevice:%{public}s", hasLocalPointerDevice ? "true" : "false");
55 bool visible = !context.NeedHideCursor() && hasLocalPointerDevice;
56 env_->GetInput().SetPointerVisibility(visible, 1);
57 }
58
OnLeaveState(Context & context)59 void CooperateFree::OnLeaveState(Context &context)
60 {
61 CALL_INFO_TRACE;
62 UpdateCooperateFlagEvent event {
63 .mask = COOPERATE_FLAG_HIDE_CURSOR,
64 };
65 context.UpdateCooperateFlag(event);
66 }
67
HasLocalPointerDevice() const68 bool CooperateFree::HasLocalPointerDevice() const
69 {
70 return env_->GetDeviceManager().AnyOf([this](std::shared_ptr<IDevice> dev) {
71 if ((dev == nullptr) || (dev->GetName() == FINGER_PRINT)) {
72 return false;
73 }
74 return (dev->IsPointerDevice() && !dev->IsRemote());
75 });
76 }
77
HasLocalKeyboardDevice() const78 bool CooperateFree::HasLocalKeyboardDevice() const
79 {
80 return env_->GetDeviceManager().AnyOf([this](std::shared_ptr<IDevice> dev) {
81 CHKPF(dev);
82 return (dev->IsKeyboard() && !dev->IsRemote());
83 });
84 }
85
UnchainConnections(Context & context,const StopCooperateEvent & event) const86 void CooperateFree::UnchainConnections(Context &context, const StopCooperateEvent &event) const
87 {
88 CALL_INFO_TRACE;
89 if (event.isUnchained) {
90 FI_HILOGI("Unchain all connections");
91 context.dsoftbus_.CloseAllSessions();
92 context.eventMgr_.OnUnchain(event);
93 }
94 }
95
Initial(CooperateFree & parent)96 CooperateFree::Initial::Initial(CooperateFree &parent) : ICooperateStep(parent, nullptr), parent_(parent)
97 {
98 AddHandler(CooperateEventType::START, [this](Context &context, const CooperateEvent &event) {
99 this->OnStart(context, event);
100 });
101 AddHandler(CooperateEventType::STOP, [this](Context &context, const CooperateEvent &event) {
102 this->OnStop(context, event);
103 });
104 AddHandler(CooperateEventType::APP_CLOSED, [this](Context &context, const CooperateEvent &event) {
105 this->OnAppClosed(context, event);
106 });
107 AddHandler(CooperateEventType::DSOFTBUS_START_COOPERATE, [this](Context &context, const CooperateEvent &event) {
108 this->OnRemoteStart(context, event);
109 });
110 }
111
OnProgress(Context & context,const CooperateEvent & event)112 void CooperateFree::Initial::OnProgress(Context &context, const CooperateEvent &event) { }
113
OnReset(Context & context,const CooperateEvent & event)114 void CooperateFree::Initial::OnReset(Context &context, const CooperateEvent &event) { }
115
BuildChains(std::shared_ptr<Initial> initial,CooperateFree & parent)116 void CooperateFree::Initial::BuildChains(std::shared_ptr<Initial> initial, CooperateFree &parent) { }
117
RemoveChains(std::shared_ptr<Initial> initial)118 void CooperateFree::Initial::RemoveChains(std::shared_ptr<Initial> initial) { }
119
OnStart(Context & context,const CooperateEvent & event)120 void CooperateFree::Initial::OnStart(Context &context, const CooperateEvent &event)
121 {
122 CALL_INFO_TRACE;
123 StartCooperateEvent notice = std::get<StartCooperateEvent>(event.event);
124 FI_HILOGI("[start cooperation] With \'%{public}s\'", Utility::Anonymize(notice.remoteNetworkId).c_str());
125 context.StartCooperate(notice);
126 context.eventMgr_.StartCooperate(notice);
127
128 int32_t ret = context.dsoftbus_.OpenSession(context.Peer());
129 if (ret != RET_OK) {
130 FI_HILOGE(
131 "[start cooperation] Failed to connect to \'%{public}s\'", Utility::Anonymize(context.Peer()).c_str());
132 int32_t errNum = (ret == RET_ERR ? static_cast<int32_t>(CoordinationErrCode::OPEN_SESSION_FAILED) : ret);
133 DSoftbusStartCooperateFinished failNotice { .success = false, .errCode = errNum };
134 context.eventMgr_.StartCooperateFinish(failNotice);
135 return;
136 }
137 DSoftbusStartCooperate startNotice {
138 .originNetworkId = context.Local(),
139 .success = true,
140 .cursorPos = context.NormalizedCursorPosition(),
141 };
142 context.OnStartCooperate(startNotice.extra);
143 context.dsoftbus_.StartCooperate(context.Peer(), startNotice);
144 context.inputEventInterceptor_.Enable(context);
145 context.eventMgr_.StartCooperateFinish(startNotice);
146 FI_HILOGI(
147 "[start cooperation] Cooperation with \'%{public}s\' established", Utility::Anonymize(context.Peer()).c_str());
148 TransiteTo(context, CooperateState::COOPERATE_STATE_OUT);
149 context.OnTransitionOut();
150 #ifdef ENABLE_PERFORMANCE_CHECK
151 std::ostringstream ss;
152 ss << "start_cooperation_with_ " << Utility::Anonymize(context.Peer()).c_str();
153 context.FinishTrace(ss.str());
154 #endif // ENABLE_PERFORMANCE_CHECK
155 }
156
OnStop(Context & context,const CooperateEvent & event)157 void CooperateFree::Initial::OnStop(Context &context, const CooperateEvent &event)
158 {
159 CALL_INFO_TRACE;
160 StopCooperateEvent notice = std::get<StopCooperateEvent>(event.event);
161 parent_.UnchainConnections(context, notice);
162 }
163
OnAppClosed(Context & context,const CooperateEvent & event)164 void CooperateFree::Initial::OnAppClosed(Context &context, const CooperateEvent &event)
165 {
166 FI_HILOGI("[app closed] Close all connections");
167 context.dsoftbus_.CloseAllSessions();
168 }
169
OnRemoteStart(Context & context,const CooperateEvent & event)170 void CooperateFree::Initial::OnRemoteStart(Context &context, const CooperateEvent &event)
171 {
172 CALL_INFO_TRACE;
173 DSoftbusStartCooperate notice = std::get<DSoftbusStartCooperate>(event.event);
174 context.OnRemoteStartCooperate(notice.extra);
175 context.eventMgr_.RemoteStart(notice);
176 context.RemoteStartSuccess(notice);
177 context.inputEventBuilder_.Enable(context);
178 context.eventMgr_.RemoteStartFinish(notice);
179 context.inputDevMgr_.AddVirtualInputDevice(context.Peer());
180 FI_HILOGI("[remote start] Cooperation with \'%{public}s\' established", Utility::Anonymize(context.Peer()).c_str());
181 TransiteTo(context, CooperateState::COOPERATE_STATE_IN);
182 context.OnTransitionIn();
183 }
184 } // namespace Cooperate
185 } // namespace DeviceStatus
186 } // namespace Msdp
187 } // namespace OHOS
188