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 "event_manager.h" 17 18#include "cooperate_hisysevent.h" 19#include "devicestatus_define.h" 20#include "utility.h" 21 22#undef LOG_TAG 23#define LOG_TAG "EventManager" 24 25namespace OHOS { 26namespace Msdp { 27namespace DeviceStatus { 28namespace Cooperate { 29 30EventManager::EventManager(IContext *env) 31 : env_(env) 32{} 33 34void EventManager::RegisterListener(const RegisterListenerEvent &event) 35{ 36 CALL_INFO_TRACE; 37 std::shared_ptr<EventInfo> eventInfo = std::make_shared<EventInfo>(); 38 eventInfo->type = EventType::LISTENER; 39 eventInfo->msgId = MessageId::COORDINATION_ADD_LISTENER; 40 eventInfo->pid = event.pid; 41 42 FI_HILOGI("Add cooperate listener (%{public}d)", eventInfo->pid); 43 auto iter = std::find_if(listeners_.begin(), listeners_.end(), 44 [eventInfo](const auto &item) { 45 return ((item != nullptr) && (item->pid == eventInfo->pid)); 46 }); 47 if (iter != listeners_.end()) { 48 *iter = eventInfo; 49 } else { 50 listeners_.emplace_back(eventInfo); 51 } 52} 53 54void EventManager::UnregisterListener(const UnregisterListenerEvent &event) 55{ 56 FI_HILOGI("Remove cooperate listener (%{public}d)", event.pid); 57 listeners_.erase(std::remove_if(listeners_.begin(), listeners_.end(), 58 [pid = event.pid](const auto &item) { 59 return ((item == nullptr) || (item->pid == pid)); 60 }), listeners_.end()); 61} 62 63void EventManager::EnableCooperate(const EnableCooperateEvent &event) 64{ 65 CALL_INFO_TRACE; 66 CooperateNotice notice { 67 .pid = event.pid, 68 .msgId = MessageId::COORDINATION_MESSAGE, 69 .userData = event.userData, 70 .msg = CoordinationMessage::PREPARE 71 }; 72 NotifyCooperateMessage(notice); 73} 74 75void EventManager::DisableCooperate(const DisableCooperateEvent &event) 76{ 77 CALL_INFO_TRACE; 78 CooperateNotice notice { 79 .pid = event.pid, 80 .msgId = MessageId::COORDINATION_MESSAGE, 81 .userData = event.userData, 82 .msg = CoordinationMessage::UNPREPARE 83 }; 84 NotifyCooperateMessage(notice); 85} 86 87void EventManager::StartCooperate(const StartCooperateEvent &event) 88{ 89 std::shared_ptr<EventInfo> eventInfo = std::make_shared<EventInfo>(); 90 eventInfo->type = EventType::START; 91 eventInfo->msgId = MessageId::COORDINATION_MESSAGE; 92 eventInfo->pid = event.pid; 93 eventInfo->networkId = event.remoteNetworkId; 94 eventInfo->userData = event.userData; 95 calls_[EventType::START] = eventInfo; 96} 97 98void EventManager::StartCooperateFinish(const DSoftbusStartCooperateFinished &event) 99{ 100 std::shared_ptr<EventInfo> eventInfo = calls_[EventType::START]; 101 CHKPV(eventInfo); 102 CooperateNotice notice { 103 .pid = eventInfo->pid, 104 .msgId = eventInfo->msgId, 105 .userData = eventInfo->userData, 106 .networkId = eventInfo->networkId, 107 .msg = (event.success ? CoordinationMessage::ACTIVATE_SUCCESS : CoordinationMessage::ACTIVATE_FAIL), 108 .errCode = event.errCode 109 }; 110 calls_[EventType::START] = nullptr; 111 NotifyCooperateMessage(notice); 112} 113 114void EventManager::RemoteStart(const DSoftbusStartCooperate &event) 115{ 116 CALL_INFO_TRACE; 117 OnCooperateMessage(CoordinationMessage::ACTIVATE, event.networkId); 118} 119 120void EventManager::RemoteStartFinish(const DSoftbusStartCooperateFinished &event) 121{ 122 CALL_INFO_TRACE; 123 CoordinationMessage msg { event.success ? 124 CoordinationMessage::ACTIVATE_SUCCESS : 125 CoordinationMessage::ACTIVATE_FAIL }; 126 OnCooperateMessage(msg, event.networkId); 127 if (msg == CoordinationMessage::ACTIVATE_SUCCESS) { 128 CooperateDFX::WriteRemoteStart(OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR); 129 } else { 130 CooperateDFX::WriteRemoteStart(OHOS::HiviewDFX::HiSysEvent::EventType::FAULT); 131 } 132} 133 134void EventManager::OnUnchain(const StopCooperateEvent &event) 135{ 136 CALL_INFO_TRACE; 137 OnCooperateMessage(CoordinationMessage::SESSION_CLOSED, std::string()); 138} 139 140void EventManager::StopCooperate(const StopCooperateEvent &event) 141{ 142 std::shared_ptr<EventInfo> eventInfo = std::make_shared<EventInfo>(); 143 eventInfo->type = EventType::STOP; 144 eventInfo->msgId = MessageId::COORDINATION_MESSAGE; 145 eventInfo->pid = event.pid; 146 eventInfo->userData = event.userData; 147 calls_[EventType::STOP] = eventInfo; 148} 149 150void EventManager::StopCooperateFinish(const DSoftbusStopCooperateFinished &event) 151{ 152 std::shared_ptr<EventInfo> eventInfo = calls_[EventType::STOP]; 153 CHKPV(eventInfo); 154 CooperateNotice notice { 155 .pid = eventInfo->pid, 156 .msgId = eventInfo->msgId, 157 .userData = eventInfo->userData, 158 .networkId = eventInfo->networkId, 159 .msg = (event.normal ? CoordinationMessage::DEACTIVATE_SUCCESS : CoordinationMessage::DEACTIVATE_FAIL), 160 .errCode = event.errCode 161 }; 162 NotifyCooperateMessage(notice); 163 calls_[EventType::STOP] = nullptr; 164} 165 166void EventManager::RemoteStop(const DSoftbusStopCooperate &event) 167{ 168 CALL_DEBUG_ENTER; 169} 170 171void EventManager::RemoteStopFinish(const DSoftbusStopCooperateFinished &event) 172{ 173 CALL_DEBUG_ENTER; 174} 175 176void EventManager::OnProfileChanged(const DDPCooperateSwitchChanged &event) 177{ 178 CALL_INFO_TRACE; 179 FI_HILOGI("Switch status of \'%{public}s\' has changed to %{public}d", 180 Utility::Anonymize(event.networkId).c_str(), event.normal); 181 CoordinationMessage msg = (event.normal ? CoordinationMessage::PREPARE : CoordinationMessage::UNPREPARE); 182 OnCooperateMessage(msg, event.networkId); 183} 184 185void EventManager::OnSoftbusSessionClosed(const DSoftbusSessionClosed &event) 186{ 187 FI_HILOGI("Connection with \'%{public}s\' is closed", Utility::Anonymize(event.networkId).c_str()); 188 OnCooperateMessage(CoordinationMessage::SESSION_CLOSED, event.networkId); 189} 190 191void EventManager::GetCooperateState(const CooperateStateNotice ¬ice) 192{ 193 CALL_INFO_TRACE; 194 NotifyCooperateState(notice); 195} 196 197void EventManager::OnCooperateMessage(CoordinationMessage msg, const std::string &networkId) 198{ 199 CALL_INFO_TRACE; 200 for (auto iter = listeners_.begin(); iter != listeners_.end(); ++iter) { 201 std::shared_ptr<EventInfo> listener = *iter; 202 CHKPC(listener); 203 FI_HILOGD("Notify cooperate listener (%{public}d, %{public}d)", listener->pid, listener->msgId); 204 CooperateNotice notice { 205 .pid = listener->pid, 206 .msgId = listener->msgId, 207 .userData = listener->userData, 208 .networkId = networkId, 209 .msg = msg 210 }; 211 NotifyCooperateMessage(notice); 212 } 213} 214 215void EventManager::OnClientDied(const ClientDiedEvent &event) 216{ 217 FI_HILOGI("Remove client died listener, pid: %{public}d", event.pid); 218 for (auto iter = listeners_.begin(); iter != listeners_.end();) { 219 std::shared_ptr<EventInfo> listener = *iter; 220 CHKPC(listener); 221 if (event.pid == listener->pid) { 222 iter = listeners_.erase(iter); 223 break; 224 } else { 225 ++iter; 226 } 227 } 228} 229 230void EventManager::NotifyCooperateMessage(const CooperateNotice ¬ice) 231{ 232 auto session = env_->GetSocketSessionManager().FindSessionByPid(notice.pid); 233 CHKPV(session); 234 NetPacket pkt(notice.msgId); 235 pkt << notice.userData << notice.networkId << static_cast<int32_t>(notice.msg) << notice.errCode; 236 if (pkt.ChkRWError()) { 237 FI_HILOGE("Packet write data failed"); 238 return; 239 } 240 if (!session->SendMsg(pkt)) { 241 FI_HILOGE("Sending failed"); 242 } 243} 244 245void EventManager::NotifyCooperateState(const CooperateStateNotice ¬ice) 246{ 247 CALL_INFO_TRACE; 248 CHKPV(env_); 249 auto session = env_->GetSocketSessionManager().FindSessionByPid(notice.pid); 250 CHKPV(session); 251 NetPacket pkt(notice.msgId); 252 pkt << notice.userData << notice.state << static_cast<int32_t>(notice.errCode); 253 if (pkt.ChkRWError()) { 254 FI_HILOGE("Packet write data failed"); 255 return; 256 } 257 if (!session->SendMsg(pkt)) { 258 FI_HILOGE("Sending failed"); 259 return; 260 } 261} 262} // namespace Cooperate 263} // namespace DeviceStatus 264} // namespace Msdp 265} // namespace OHOS 266