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 
25 namespace OHOS {
26 namespace Msdp {
27 namespace DeviceStatus {
28 namespace Cooperate {
29 
EventManager(IContext * env)30 EventManager::EventManager(IContext *env)
31     : env_(env)
32 {}
33 
RegisterListener(const RegisterListenerEvent & event)34 void 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 
UnregisterListener(const UnregisterListenerEvent & event)54 void 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 
EnableCooperate(const EnableCooperateEvent & event)63 void 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 
DisableCooperate(const DisableCooperateEvent & event)75 void 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 
StartCooperate(const StartCooperateEvent & event)87 void 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 
StartCooperateFinish(const DSoftbusStartCooperateFinished & event)98 void EventManager::StartCooperateFinish(const DSoftbusStartCooperateFinished &event)
99 {
100         .msgId = eventInfo->msgId,
101         .userData = eventInfo->userData,
102         .networkId = eventInfo->networkId,
103         .msg = (event.success ? CoordinationMessage::ACTIVATE_SUCCESS : CoordinationMessage::ACTIVATE_FAIL),
104         .errCode = event.errCode
105     };
106     calls_[EventType::START] = nullptr;
107     NotifyCooperateMessage(notice);
108 }
109 
RemoteStart(const DSoftbusStartCooperate & event)110 void EventManager::RemoteStart(const DSoftbusStartCooperate &event)
111 {
112     CALL_INFO_TRACE;
113     OnCooperateMessage(CoordinationMessage::ACTIVATE, event.networkId);
114 }
115 
RemoteStartFinish(const DSoftbusStartCooperateFinished & event)116 void EventManager::RemoteStartFinish(const DSoftbusStartCooperateFinished &event)
117 {
118     CALL_INFO_TRACE;
119     CoordinationMessage msg { event.success ?
120                               CoordinationMessage::ACTIVATE_SUCCESS :
121                               CoordinationMessage::ACTIVATE_FAIL };
122     OnCooperateMessage(msg, event.networkId);
123     if (msg == CoordinationMessage::ACTIVATE_SUCCESS) {
124         CooperateDFX::WriteRemoteStart(OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR);
125     } else {
126         CooperateDFX::WriteRemoteStart(OHOS::HiviewDFX::HiSysEvent::EventType::FAULT);
127     }
128 }
129 
OnUnchain(const StopCooperateEvent & event)130 void EventManager::OnUnchain(const StopCooperateEvent &event)
131 {
132     CALL_INFO_TRACE;
133     OnCooperateMessage(CoordinationMessage::SESSION_CLOSED, std::string());
134 }
135 
StopCooperate(const StopCooperateEvent & event)136 void EventManager::StopCooperate(const StopCooperateEvent &event)
137 {
138     std::shared_ptr<EventInfo> eventInfo = std::make_shared<EventInfo>();
139     eventInfo->type = EventType::STOP;
140     eventInfo->msgId = MessageId::COORDINATION_MESSAGE;
141     eventInfo->pid = event.pid;
142     eventInfo->userData = event.userData;
143     calls_[EventType::STOP] = eventInfo;
144 }
145 
StopCooperateFinish(const DSoftbusStopCooperateFinished & event)146 void EventManager::StopCooperateFinish(const DSoftbusStopCooperateFinished &event)
147 {
148         .msgId = eventInfo->msgId,
149         .userData = eventInfo->userData,
150         .networkId = eventInfo->networkId,
151         .msg = (event.normal ? CoordinationMessage::DEACTIVATE_SUCCESS : CoordinationMessage::DEACTIVATE_FAIL),
152         .errCode = event.errCode
153     };
154     NotifyCooperateMessage(notice);
155     calls_[EventType::STOP] = nullptr;
156 }
157 
RemoteStop(const DSoftbusStopCooperate & event)158 void EventManager::RemoteStop(const DSoftbusStopCooperate &event)
159 {
160     CALL_DEBUG_ENTER;
161 }
162 
RemoteStopFinish(const DSoftbusStopCooperateFinished & event)163 void EventManager::RemoteStopFinish(const DSoftbusStopCooperateFinished &event)
164 {
165     CALL_DEBUG_ENTER;
166 }
167 
OnProfileChanged(const DDPCooperateSwitchChanged & event)168 void EventManager::OnProfileChanged(const DDPCooperateSwitchChanged &event)
169 {
170     CALL_INFO_TRACE;
171     FI_HILOGI("Switch status of \'%{public}s\' has changed to %{public}d",
172         Utility::Anonymize(event.networkId).c_str(), event.normal);
173     CoordinationMessage msg = (event.normal ? CoordinationMessage::PREPARE : CoordinationMessage::UNPREPARE);
174     OnCooperateMessage(msg, event.networkId);
175 }
176 
OnSoftbusSessionClosed(const DSoftbusSessionClosed & event)177 void EventManager::OnSoftbusSessionClosed(const DSoftbusSessionClosed &event)
178 {
179     FI_HILOGI("Connection with \'%{public}s\' is closed", Utility::Anonymize(event.networkId).c_str());
180     OnCooperateMessage(CoordinationMessage::SESSION_CLOSED, event.networkId);
181 }
182 
GetCooperateState(const CooperateStateNotice & notice)183 void EventManager::GetCooperateState(const CooperateStateNotice &notice)
184 {
185     CALL_INFO_TRACE;
186     NotifyCooperateState(notice);
187 }
188 
OnCooperateMessage(CoordinationMessage msg,const std::string & networkId)189 void EventManager::OnCooperateMessage(CoordinationMessage msg, const std::string &networkId)
190 {
191     CALL_INFO_TRACE;
192     for (auto iter = listeners_.begin(); iter != listeners_.end(); ++iter) {
193         std::shared_ptr<EventInfo> listener = *iter;
194         CHKPC(listener);
195         FI_HILOGD("Notify cooperate listener (%{public}d, %{public}d)", listener->pid, listener->msgId);
196         CooperateNotice notice {
197             .pid = listener->pid,
198             .msgId = listener->msgId,
199             .userData = listener->userData,
200             .networkId = networkId,
201             .msg = msg
202         };
203         NotifyCooperateMessage(notice);
204     }
205 }
206 
OnClientDied(const ClientDiedEvent & event)207 void EventManager::OnClientDied(const ClientDiedEvent &event)
208 {
209     FI_HILOGI("Remove client died listener, pid: %{public}d", event.pid);
210     for (auto iter = listeners_.begin(); iter != listeners_.end();) {
211         std::shared_ptr<EventInfo> listener = *iter;
212         CHKPC(listener);
213         if (event.pid == listener->pid) {
214             iter = listeners_.erase(iter);
215             break;
216         } else {
217             ++iter;
218         }
219     }
220 }
221 
NotifyCooperateMessage(const CooperateNotice & notice)222 void EventManager::NotifyCooperateMessage(const CooperateNotice &notice)
223 {
224     auto session = env_->GetSocketSessionManager().FindSessionByPid(notice.pid);
225     CHKPV(session);
226     NetPacket pkt(notice.msgId);
227     pkt << notice.userData << notice.networkId << static_cast<int32_t>(notice.msg) << notice.errCode;
228     if (pkt.ChkRWError()) {
229         FI_HILOGE("Packet write data failed");
230         return;
231     }
232     if (!session->SendMsg(pkt)) {
233         FI_HILOGE("Sending failed");
234     }
235 }
236 
NotifyCooperateState(const CooperateStateNotice & notice)237 void EventManager::NotifyCooperateState(const CooperateStateNotice &notice)
238 {
239     CALL_INFO_TRACE;
240     CHKPV(env_);
241     auto session = env_->GetSocketSessionManager().FindSessionByPid(notice.pid);
242     CHKPV(session);
243     NetPacket pkt(notice.msgId);
244     pkt << notice.userData << notice.state << static_cast<int32_t>(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         return;
252     }
253 }
254 } // namespace Cooperate
255 } // namespace DeviceStatus
256 } // namespace Msdp
257 } // namespace OHOS
258