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 
26 namespace OHOS {
27 namespace Msdp {
28 namespace DeviceStatus {
29 namespace Cooperate {
30 
EventManager(IContext *env)31 EventManager::EventManager(IContext *env)
32     : env_(env)
33 {}
34 
RegisterListener(const RegisterListenerEvent &event)35 void 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 
UnregisterListener(const UnregisterListenerEvent &event)55 void 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 
EnableCooperate(const EnableCooperateEvent &event)64 void 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 
DisableCooperate(const DisableCooperateEvent &event)76 void 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 
StartCooperate(const StartCooperateEvent &event)88 void 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 
StartCooperateFinish(const DSoftbusStartCooperateFinished &event)99 void 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 
RemoteStart(const DSoftbusStartCooperate &event)115 void EventManager::RemoteStart(const DSoftbusStartCooperate &event)
116 {
117     CALL_INFO_TRACE;
118     OnCooperateMessage(CoordinationMessage::ACTIVATE, event.networkId);
119 }
120 
RemoteStartFinish(const DSoftbusStartCooperateFinished &event)121 void 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 
OnUnchain(const StopCooperateEvent &event)139 void EventManager::OnUnchain(const StopCooperateEvent &event)
140 {
141     CALL_INFO_TRACE;
142     OnCooperateMessage(CoordinationMessage::SESSION_CLOSED, event.networkId);
143 }
144 
StopCooperate(const StopCooperateEvent &event)145 void 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 
StopCooperateFinish(const DSoftbusStopCooperateFinished &event)155 void 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 
RemoteStop(const DSoftbusStopCooperate &event)171 void EventManager::RemoteStop(const DSoftbusStopCooperate &event)
172 {
173     CALL_DEBUG_ENTER;
174 }
175 
RemoteStopFinish(const DSoftbusStopCooperateFinished &event)176 void EventManager::RemoteStopFinish(const DSoftbusStopCooperateFinished &event)
177 {
178     CALL_DEBUG_ENTER;
179 }
180 
OnProfileChanged(const DDPCooperateSwitchChanged &event)181 void 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 
OnSoftbusSessionClosed(const DSoftbusSessionClosed &event)190 void 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 
GetCooperateState(const CooperateStateNotice &notice)196 void EventManager::GetCooperateState(const CooperateStateNotice &notice)
197 {
198     CALL_INFO_TRACE;
199     NotifyCooperateState(notice);
200 }
201 
OnCooperateMessage(CoordinationMessage msg, const std::string &networkId)202 void 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 
OnClientDied(const ClientDiedEvent &event)220 void 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 
NotifyCooperateMessage(const CooperateNotice &notice)235 void EventManager::NotifyCooperateMessage(const CooperateNotice &notice)
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 
NotifyCooperateState(const CooperateStateNotice &notice)254 void EventManager::NotifyCooperateState(const CooperateStateNotice &notice)
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