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 "softbus_adapter/softbus_adapter.h"
17
18 #include <sys/prctl.h>
19
20 #include "broadcast.h"
21 #include "dfx/distributed_radar.h"
22 #include "dtbschedmgr_log.h"
23 #include "softbus_error_code.h"
24
25 namespace OHOS {
26 namespace DistributedSchedule {
27 namespace {
28 const std::string TAG = "SoftbusAdapter";
29 const std::string SOFTBUS_ADAPTER = "softbus_adapter";
30 const std::string RETRY_SENT_EVENT_TASK = "retry_on_sent_event_task";
31 constexpr int32_t RETRY_SENT_EVENT_DELAY = 50;
32 constexpr int32_t RETRY_SENT_EVENT_MAX_TIME = 3;
33 }
34
35 IMPLEMENT_SINGLE_INSTANCE(SoftbusAdapter);
36
Init()37 void SoftbusAdapter::Init()
38 {
39 if (eventHandler_ != nullptr) {
40 HILOGI("Already inited, end.");
41 return;
42 }
43 eventThread_ = std::thread(&SoftbusAdapter::StartEvent, this);
44 std::unique_lock<std::mutex> lock(eventMutex_);
45 eventCon_.wait(lock, [this] {
46 return eventHandler_ != nullptr;
47 });
48 }
49
StartEvent()50 void SoftbusAdapter::StartEvent()
51 {
52 HILOGI("StartEvent start");
53 prctl(PR_SET_NAME, SOFTBUS_ADAPTER.c_str());
54 auto runner = AppExecFwk::EventRunner::Create(false);
55 {
56 std::lock_guard<std::mutex> lock(eventMutex_);
57 eventHandler_ = std::make_shared<OHOS::AppExecFwk::EventHandler>(runner);
58 }
59 eventCon_.notify_one();
60 if (runner != nullptr) {
61 runner->Run();
62 } else {
63 HILOGE("runner is null");
64 }
65 HILOGI("StartEvent end");
66 }
67
UnInit()68 void SoftbusAdapter::UnInit()
69 {
70 HILOGI("UnInit start");
71 if (eventHandler_ != nullptr && eventHandler_->GetEventRunner() != nullptr) {
72 eventHandler_->GetEventRunner()->Stop();
73 eventThread_.join();
74 eventHandler_ = nullptr;
75 } else {
76 HILOGE("eventHandler_ or eventRunner is nullptr");
77 }
78 HILOGI("UnInit end");
79 }
80
SendSoftbusEvent(std::shared_ptr<DSchedDataBuffer> buffer)81 int32_t SoftbusAdapter::SendSoftbusEvent(std::shared_ptr<DSchedDataBuffer> buffer)
82 {
83 HILOGI("SendSoftbusEvent pkgName: %{public}s.", pkgName_.c_str());
84 auto feedfunc = [this, buffer]() {
85 DealSendSoftbusEvent(buffer);
86 };
87 if (eventHandler_ != nullptr) {
88 eventHandler_->PostTask(feedfunc);
89 } else {
90 HILOGE("eventHandler_ is nullptr");
91 }
92
93 return SOFTBUS_OK;
94 }
95
DealSendSoftbusEvent(std::shared_ptr<DSchedDataBuffer> buffer,const int32_t retry)96 int32_t SoftbusAdapter::DealSendSoftbusEvent(std::shared_ptr<DSchedDataBuffer> buffer, const int32_t retry)
97 {
98 if (eventHandler_ != nullptr) {
99 eventHandler_->RemoveTask(RETRY_SENT_EVENT_TASK);
100 } else {
101 HILOGE("eventHandler_ is nullptr");
102 return INVALID_PARAMETERS_ERR;
103 }
104
105 if (buffer == nullptr) {
106 HILOGE("buffer is nullptr");
107 return INVALID_PARAMETERS_ERR;
108 }
109 EventData eventData;
110 eventData.event = FOREGROUND_APP;
111 eventData.freq = EVENT_HIGH_FREQ;
112 eventData.data = buffer->Data();
113 eventData.dataLen = buffer->Capacity();
114 eventData.screenOff = true;
115 int32_t ret = SendEvent(pkgName_.c_str(), BROADCAST_TARGET_AREA, &eventData);
116 if (ret != SOFTBUS_OK) {
117 HILOGW("SendEvent failed, ret:%{public}d.", ret);
118 return RetrySendSoftbusEvent(buffer, retry);
119 }
120 return ret;
121 }
122
RetrySendSoftbusEvent(std::shared_ptr<DSchedDataBuffer> buffer,const int32_t retry)123 int32_t SoftbusAdapter::RetrySendSoftbusEvent(std::shared_ptr<DSchedDataBuffer> buffer, const int32_t retry)
124 {
125 HILOGI("Retry post broadcast, current retry times %{public}d", retry);
126 if (retry == RETRY_SENT_EVENT_MAX_TIME) {
127 HILOGE("meet max retry time!");
128 return INVALID_PARAMETERS_ERR;
129 }
130 auto feedfunc = [this, buffer, retry]() mutable {
131 DealSendSoftbusEvent(buffer, retry + 1);
132 };
133 if (eventHandler_ != nullptr) {
134 eventHandler_->RemoveTask(RETRY_SENT_EVENT_TASK);
135 eventHandler_->PostTask(feedfunc, RETRY_SENT_EVENT_TASK, RETRY_SENT_EVENT_DELAY);
136 } else {
137 HILOGE("eventHandler_ is nullptr");
138 return INVALID_PARAMETERS_ERR;
139 }
140 return ERR_OK;
141 }
142
StopSoftbusEvent()143 int32_t SoftbusAdapter::StopSoftbusEvent()
144 {
145 HILOGI("StopSoftbusEvent pkgName: %{public}s.", pkgName_.c_str());
146 int32_t ret = StopEvent(pkgName_.c_str(), BROADCAST_TARGET_AREA, FOREGROUND_APP);
147 if (ret != SOFTBUS_OK) {
148 HILOGE("StopEvent failed, ret:%{public}d.", ret);
149 return ret;
150 }
151 return SOFTBUS_OK;
152 }
153
EventListenerReceived(const EventNotify * eventNotify)154 static void EventListenerReceived(const EventNotify *eventNotify)
155 {
156 HILOGD("called.");
157 if (eventNotify == nullptr) {
158 HILOGE("eventNotify is null");
159 return;
160 }
161 std::string networkId(eventNotify->senderNetworkId);
162 SoftbusAdapter::GetInstance().OnBroadCastRecv(networkId, eventNotify->data, eventNotify->dataLen);
163 }
164
OnBroadCastRecv(std::string & networkId,uint8_t * data,uint32_t dataLen)165 void SoftbusAdapter::OnBroadCastRecv(std::string& networkId, uint8_t* data, uint32_t dataLen)
166 {
167 if (softbusAdapterListener_ != nullptr) {
168 softbusAdapterListener_->OnDataRecv(networkId, data, dataLen);
169 } else {
170 HILOGE("softbusAdapterListener_ is nullptr");
171 }
172 }
173
RegisterSoftbusEventListener(const std::shared_ptr<SoftbusAdapterListener> & listener)174 int32_t SoftbusAdapter::RegisterSoftbusEventListener(const std::shared_ptr<SoftbusAdapterListener>& listener)
175 {
176 if (listener == nullptr) {
177 HILOGE("Registering listener failed");
178 return SOFTBUS_INVALID_PARAM;
179 }
180 {
181 std::lock_guard<std::mutex> lock(softbusAdapterListenerMutex_);
182 softbusAdapterListener_ = listener;
183 }
184 EventListener eventListener;
185 eventListener.event = FOREGROUND_APP;
186 eventListener.freq = EVENT_MID_FREQ;
187 eventListener.deduplicate = true;
188 eventListener.OnEventReceived = EventListenerReceived;
189 HILOGI("RegisterSoftbusEventListener pkgName: %s.", pkgName_.c_str());
190 int32_t ret = RegisterEventListener(pkgName_.c_str(), &eventListener);
191 DmsRadar::GetInstance().RegisterSoftbusCallbackRes("RegisterSoftbusEventListener", ret);
192 if (ret != SOFTBUS_OK) {
193 HILOGE("RegisterSoftbusEventListener failed, ret: %{public}d.", ret);
194 return ret;
195 }
196 return SOFTBUS_OK;
197 }
198
UnregisterSoftbusEventListener(const std::shared_ptr<SoftbusAdapterListener> & listener)199 int32_t SoftbusAdapter::UnregisterSoftbusEventListener(const std::shared_ptr<SoftbusAdapterListener>& listener)
200 {
201 if (listener == nullptr) {
202 HILOGE("Unregistering listener failed");
203 return SOFTBUS_INVALID_PARAM;
204 }
205 {
206 std::lock_guard<std::mutex> lock(softbusAdapterListenerMutex_);
207 softbusAdapterListener_ = listener;
208 }
209 EventListener eventListener;
210 eventListener.event = FOREGROUND_APP;
211 eventListener.freq = EVENT_MID_FREQ;
212 eventListener.deduplicate = true;
213 eventListener.OnEventReceived = EventListenerReceived;
214 HILOGI("UnregisterSoftbusEventListener pkgName: %s.", pkgName_.c_str());
215 int32_t ret = UnregisterEventListener(pkgName_.c_str(), &eventListener);
216 if (ret != SOFTBUS_OK) {
217 HILOGE("UnregisterSoftbusEventListener failed, ret: %{public}d.", ret);
218 return ret;
219 }
220 return SOFTBUS_OK;
221 }
222 } // namespace DistributedSchedule
223 } // namespace OHOS
224