1686862fbSopenharmony_ci/*
2686862fbSopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3686862fbSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4686862fbSopenharmony_ci * you may not use this file except in compliance with the License.
5686862fbSopenharmony_ci * You may obtain a copy of the License at
6686862fbSopenharmony_ci *
7686862fbSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8686862fbSopenharmony_ci *
9686862fbSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10686862fbSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11686862fbSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12686862fbSopenharmony_ci * See the License for the specific language governing permissions and
13686862fbSopenharmony_ci * limitations under the License.
14686862fbSopenharmony_ci */
15686862fbSopenharmony_ci
16686862fbSopenharmony_ci#include "softbus_adapter/softbus_adapter.h"
17686862fbSopenharmony_ci
18686862fbSopenharmony_ci#include <sys/prctl.h>
19686862fbSopenharmony_ci
20686862fbSopenharmony_ci#include "broadcast.h"
21686862fbSopenharmony_ci#include "dfx/distributed_radar.h"
22686862fbSopenharmony_ci#include "dtbschedmgr_log.h"
23686862fbSopenharmony_ci#include "softbus_error_code.h"
24686862fbSopenharmony_ci
25686862fbSopenharmony_cinamespace OHOS {
26686862fbSopenharmony_cinamespace DistributedSchedule {
27686862fbSopenharmony_cinamespace {
28686862fbSopenharmony_ciconst std::string TAG = "SoftbusAdapter";
29686862fbSopenharmony_ciconst std::string SOFTBUS_ADAPTER = "softbus_adapter";
30686862fbSopenharmony_ciconst std::string RETRY_SENT_EVENT_TASK = "retry_on_sent_event_task";
31686862fbSopenharmony_ciconstexpr int32_t RETRY_SENT_EVENT_DELAY = 50;
32686862fbSopenharmony_ciconstexpr int32_t RETRY_SENT_EVENT_MAX_TIME = 3;
33686862fbSopenharmony_ci}
34686862fbSopenharmony_ci
35686862fbSopenharmony_ciIMPLEMENT_SINGLE_INSTANCE(SoftbusAdapter);
36686862fbSopenharmony_ci
37686862fbSopenharmony_civoid SoftbusAdapter::Init()
38686862fbSopenharmony_ci{
39686862fbSopenharmony_ci    if (eventHandler_ != nullptr) {
40686862fbSopenharmony_ci        HILOGI("Already inited, end.");
41686862fbSopenharmony_ci        return;
42686862fbSopenharmony_ci    }
43686862fbSopenharmony_ci    eventThread_ = std::thread(&SoftbusAdapter::StartEvent, this);
44686862fbSopenharmony_ci    std::unique_lock<std::mutex> lock(eventMutex_);
45686862fbSopenharmony_ci    eventCon_.wait(lock, [this] {
46686862fbSopenharmony_ci        return eventHandler_ != nullptr;
47686862fbSopenharmony_ci    });
48686862fbSopenharmony_ci}
49686862fbSopenharmony_ci
50686862fbSopenharmony_civoid SoftbusAdapter::StartEvent()
51686862fbSopenharmony_ci{
52686862fbSopenharmony_ci    HILOGI("StartEvent start");
53686862fbSopenharmony_ci    prctl(PR_SET_NAME, SOFTBUS_ADAPTER.c_str());
54686862fbSopenharmony_ci    auto runner = AppExecFwk::EventRunner::Create(false);
55686862fbSopenharmony_ci    {
56686862fbSopenharmony_ci        std::lock_guard<std::mutex> lock(eventMutex_);
57686862fbSopenharmony_ci        eventHandler_ = std::make_shared<OHOS::AppExecFwk::EventHandler>(runner);
58686862fbSopenharmony_ci    }
59686862fbSopenharmony_ci    eventCon_.notify_one();
60686862fbSopenharmony_ci    if (runner != nullptr) {
61686862fbSopenharmony_ci        runner->Run();
62686862fbSopenharmony_ci    } else {
63686862fbSopenharmony_ci        HILOGE("runner is null");
64686862fbSopenharmony_ci    }
65686862fbSopenharmony_ci    HILOGI("StartEvent end");
66686862fbSopenharmony_ci}
67686862fbSopenharmony_ci
68686862fbSopenharmony_civoid SoftbusAdapter::UnInit()
69686862fbSopenharmony_ci{
70686862fbSopenharmony_ci    HILOGI("UnInit start");
71686862fbSopenharmony_ci    if (eventHandler_ != nullptr && eventHandler_->GetEventRunner() != nullptr) {
72686862fbSopenharmony_ci        eventHandler_->GetEventRunner()->Stop();
73686862fbSopenharmony_ci        eventThread_.join();
74686862fbSopenharmony_ci        eventHandler_ = nullptr;
75686862fbSopenharmony_ci    } else {
76686862fbSopenharmony_ci        HILOGE("eventHandler_ or eventRunner is nullptr");
77686862fbSopenharmony_ci    }
78686862fbSopenharmony_ci    HILOGI("UnInit end");
79686862fbSopenharmony_ci}
80686862fbSopenharmony_ci
81686862fbSopenharmony_ciint32_t SoftbusAdapter::SendSoftbusEvent(std::shared_ptr<DSchedDataBuffer> buffer)
82686862fbSopenharmony_ci{
83686862fbSopenharmony_ci    HILOGI("SendSoftbusEvent pkgName: %{public}s.", pkgName_.c_str());
84686862fbSopenharmony_ci    auto feedfunc = [this, buffer]() {
85686862fbSopenharmony_ci        DealSendSoftbusEvent(buffer);
86686862fbSopenharmony_ci    };
87686862fbSopenharmony_ci    if (eventHandler_ != nullptr) {
88686862fbSopenharmony_ci        eventHandler_->PostTask(feedfunc);
89686862fbSopenharmony_ci    } else {
90686862fbSopenharmony_ci        HILOGE("eventHandler_ is nullptr");
91686862fbSopenharmony_ci    }
92686862fbSopenharmony_ci
93686862fbSopenharmony_ci    return SOFTBUS_OK;
94686862fbSopenharmony_ci}
95686862fbSopenharmony_ci
96686862fbSopenharmony_ciint32_t SoftbusAdapter::DealSendSoftbusEvent(std::shared_ptr<DSchedDataBuffer> buffer, const int32_t retry)
97686862fbSopenharmony_ci{
98686862fbSopenharmony_ci    if (eventHandler_ != nullptr) {
99686862fbSopenharmony_ci        eventHandler_->RemoveTask(RETRY_SENT_EVENT_TASK);
100686862fbSopenharmony_ci    } else {
101686862fbSopenharmony_ci        HILOGE("eventHandler_ is nullptr");
102686862fbSopenharmony_ci        return INVALID_PARAMETERS_ERR;
103686862fbSopenharmony_ci    }
104686862fbSopenharmony_ci
105686862fbSopenharmony_ci    if (buffer == nullptr) {
106686862fbSopenharmony_ci        HILOGE("buffer is nullptr");
107686862fbSopenharmony_ci        return INVALID_PARAMETERS_ERR;
108686862fbSopenharmony_ci    }
109686862fbSopenharmony_ci    EventData eventData;
110686862fbSopenharmony_ci    eventData.event = FOREGROUND_APP;
111686862fbSopenharmony_ci    eventData.freq = EVENT_HIGH_FREQ;
112686862fbSopenharmony_ci    eventData.data = buffer->Data();
113686862fbSopenharmony_ci    eventData.dataLen = buffer->Capacity();
114686862fbSopenharmony_ci    eventData.screenOff = true;
115686862fbSopenharmony_ci    int32_t ret = SendEvent(pkgName_.c_str(), BROADCAST_TARGET_AREA, &eventData);
116686862fbSopenharmony_ci    if (ret != SOFTBUS_OK) {
117686862fbSopenharmony_ci        HILOGW("SendEvent failed, ret:%{public}d.", ret);
118686862fbSopenharmony_ci        return RetrySendSoftbusEvent(buffer, retry);
119686862fbSopenharmony_ci    }
120686862fbSopenharmony_ci    return ret;
121686862fbSopenharmony_ci}
122686862fbSopenharmony_ci
123686862fbSopenharmony_ciint32_t SoftbusAdapter::RetrySendSoftbusEvent(std::shared_ptr<DSchedDataBuffer> buffer, const int32_t retry)
124686862fbSopenharmony_ci{
125686862fbSopenharmony_ci    HILOGI("Retry post broadcast, current retry times %{public}d", retry);
126686862fbSopenharmony_ci    if (retry == RETRY_SENT_EVENT_MAX_TIME) {
127686862fbSopenharmony_ci        HILOGE("meet max retry time!");
128686862fbSopenharmony_ci        return INVALID_PARAMETERS_ERR;
129686862fbSopenharmony_ci    }
130686862fbSopenharmony_ci    auto feedfunc = [this, buffer, retry]() mutable {
131686862fbSopenharmony_ci        DealSendSoftbusEvent(buffer, retry + 1);
132686862fbSopenharmony_ci    };
133686862fbSopenharmony_ci    if (eventHandler_ != nullptr) {
134686862fbSopenharmony_ci        eventHandler_->RemoveTask(RETRY_SENT_EVENT_TASK);
135686862fbSopenharmony_ci        eventHandler_->PostTask(feedfunc, RETRY_SENT_EVENT_TASK, RETRY_SENT_EVENT_DELAY);
136686862fbSopenharmony_ci    } else {
137686862fbSopenharmony_ci        HILOGE("eventHandler_ is nullptr");
138686862fbSopenharmony_ci        return INVALID_PARAMETERS_ERR;
139686862fbSopenharmony_ci    }
140686862fbSopenharmony_ci    return ERR_OK;
141686862fbSopenharmony_ci}
142686862fbSopenharmony_ci
143686862fbSopenharmony_ciint32_t SoftbusAdapter::StopSoftbusEvent()
144686862fbSopenharmony_ci{
145686862fbSopenharmony_ci    HILOGI("StopSoftbusEvent pkgName: %{public}s.", pkgName_.c_str());
146686862fbSopenharmony_ci    int32_t ret = StopEvent(pkgName_.c_str(), BROADCAST_TARGET_AREA, FOREGROUND_APP);
147686862fbSopenharmony_ci    if (ret != SOFTBUS_OK) {
148686862fbSopenharmony_ci        HILOGE("StopEvent failed, ret:%{public}d.", ret);
149686862fbSopenharmony_ci        return ret;
150686862fbSopenharmony_ci    }
151686862fbSopenharmony_ci    return SOFTBUS_OK;
152686862fbSopenharmony_ci}
153686862fbSopenharmony_ci
154686862fbSopenharmony_cistatic void EventListenerReceived(const EventNotify *eventNotify)
155686862fbSopenharmony_ci{
156686862fbSopenharmony_ci    HILOGD("called.");
157686862fbSopenharmony_ci    if (eventNotify == nullptr) {
158686862fbSopenharmony_ci        HILOGE("eventNotify is null");
159686862fbSopenharmony_ci        return;
160686862fbSopenharmony_ci    }
161686862fbSopenharmony_ci    std::string networkId(eventNotify->senderNetworkId);
162686862fbSopenharmony_ci    SoftbusAdapter::GetInstance().OnBroadCastRecv(networkId, eventNotify->data, eventNotify->dataLen);
163686862fbSopenharmony_ci}
164686862fbSopenharmony_ci
165686862fbSopenharmony_civoid SoftbusAdapter::OnBroadCastRecv(std::string& networkId, uint8_t* data, uint32_t dataLen)
166686862fbSopenharmony_ci{
167686862fbSopenharmony_ci    if (softbusAdapterListener_ != nullptr) {
168686862fbSopenharmony_ci        softbusAdapterListener_->OnDataRecv(networkId, data, dataLen);
169686862fbSopenharmony_ci    } else {
170686862fbSopenharmony_ci        HILOGE("softbusAdapterListener_ is nullptr");
171686862fbSopenharmony_ci    }
172686862fbSopenharmony_ci}
173686862fbSopenharmony_ci
174686862fbSopenharmony_ciint32_t SoftbusAdapter::RegisterSoftbusEventListener(const std::shared_ptr<SoftbusAdapterListener>& listener)
175686862fbSopenharmony_ci{
176686862fbSopenharmony_ci    if (listener == nullptr) {
177686862fbSopenharmony_ci        HILOGE("Registering listener failed");
178686862fbSopenharmony_ci        return SOFTBUS_INVALID_PARAM;
179686862fbSopenharmony_ci    }
180686862fbSopenharmony_ci    {
181686862fbSopenharmony_ci        std::lock_guard<std::mutex> lock(softbusAdapterListenerMutex_);
182686862fbSopenharmony_ci        softbusAdapterListener_ = listener;
183686862fbSopenharmony_ci    }
184686862fbSopenharmony_ci    EventListener eventListener;
185686862fbSopenharmony_ci    eventListener.event = FOREGROUND_APP;
186686862fbSopenharmony_ci    eventListener.freq = EVENT_MID_FREQ;
187686862fbSopenharmony_ci    eventListener.deduplicate = true;
188686862fbSopenharmony_ci    eventListener.OnEventReceived = EventListenerReceived;
189686862fbSopenharmony_ci    HILOGI("RegisterSoftbusEventListener pkgName: %s.", pkgName_.c_str());
190686862fbSopenharmony_ci    int32_t ret = RegisterEventListener(pkgName_.c_str(), &eventListener);
191686862fbSopenharmony_ci    DmsRadar::GetInstance().RegisterSoftbusCallbackRes("RegisterSoftbusEventListener", ret);
192686862fbSopenharmony_ci    if (ret != SOFTBUS_OK) {
193686862fbSopenharmony_ci        HILOGE("RegisterSoftbusEventListener failed, ret: %{public}d.", ret);
194686862fbSopenharmony_ci        return ret;
195686862fbSopenharmony_ci    }
196686862fbSopenharmony_ci    return SOFTBUS_OK;
197686862fbSopenharmony_ci}
198686862fbSopenharmony_ci
199686862fbSopenharmony_ciint32_t SoftbusAdapter::UnregisterSoftbusEventListener(const std::shared_ptr<SoftbusAdapterListener>& listener)
200686862fbSopenharmony_ci{
201686862fbSopenharmony_ci    if (listener == nullptr) {
202686862fbSopenharmony_ci        HILOGE("Unregistering listener failed");
203686862fbSopenharmony_ci        return SOFTBUS_INVALID_PARAM;
204686862fbSopenharmony_ci    }
205686862fbSopenharmony_ci    {
206686862fbSopenharmony_ci        std::lock_guard<std::mutex> lock(softbusAdapterListenerMutex_);
207686862fbSopenharmony_ci        softbusAdapterListener_ = listener;
208686862fbSopenharmony_ci    }
209686862fbSopenharmony_ci    EventListener eventListener;
210686862fbSopenharmony_ci    eventListener.event = FOREGROUND_APP;
211686862fbSopenharmony_ci    eventListener.freq = EVENT_MID_FREQ;
212686862fbSopenharmony_ci    eventListener.deduplicate = true;
213686862fbSopenharmony_ci    eventListener.OnEventReceived = EventListenerReceived;
214686862fbSopenharmony_ci    HILOGI("UnregisterSoftbusEventListener pkgName: %s.", pkgName_.c_str());
215686862fbSopenharmony_ci    int32_t ret = UnregisterEventListener(pkgName_.c_str(), &eventListener);
216686862fbSopenharmony_ci    if (ret != SOFTBUS_OK) {
217686862fbSopenharmony_ci        HILOGE("UnregisterSoftbusEventListener failed, ret: %{public}d.", ret);
218686862fbSopenharmony_ci        return ret;
219686862fbSopenharmony_ci    }
220686862fbSopenharmony_ci    return SOFTBUS_OK;
221686862fbSopenharmony_ci}
222686862fbSopenharmony_ci} // namespace DistributedSchedule
223686862fbSopenharmony_ci} // namespace OHOS
224