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