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