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