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