1 /*
2 * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development 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 "common/common_macro.h"
17 #include "common/const_def.h"
18 #include "common/sharing_log.h"
19 #include "wfd_sink_impl.h"
20 #include "wifi_diaplay.h"
21
22 namespace OHOS {
23 namespace Sharing {
24
GetInstance(WfdMode mode)25 std::shared_ptr<WifiDisplay> MiracastFactory::GetInstance(WfdMode mode)
26 {
27 SHARING_LOGD("trace.");
28 auto wifiDisplay = std::make_shared<WifiDisplay>(mode);
29 wifiDisplay->Init();
30 return wifiDisplay;
31 }
32
WifiDisplay(WfdMode mode)33 WifiDisplay::WifiDisplay(WfdMode mode)
34 {
35 SHARING_LOGD("trace.");
36 if (mode == SINK) {
37 SHARING_LOGD("trace.");
38 wfdSinkImpl_ = WfdSinkFactory::CreateSink(0, "WFD_SINK");
39 } else {
40 SHARING_LOGD("create wfd source.");
41 }
42 }
43
~WifiDisplay()44 WifiDisplay::~WifiDisplay()
45 {
46 SHARING_LOGD("trace.");
47 if (wfdSinkImpl_) {
48 wfdSinkImpl_->Stop();
49 wfdSinkImpl_ = nullptr;
50 }
51 }
52
Init()53 void WifiDisplay::Init()
54 {
55 if (wfdSinkImpl_)
56 wfdSinkImpl_->SetListener(shared_from_this());
57 }
58
Stop()59 int32_t WifiDisplay::Stop()
60 {
61 SHARING_LOGD("trace.");
62 if (wfdSinkImpl_ && mode_ == SINK) {
63 auto ret = wfdSinkImpl_->Stop();
64 if (ret != 0) {
65 SHARING_LOGE("stop wifi display failed");
66 }
67
68 return ret;
69 }
70
71 return ERR_GENERAL_ERROR;
72 }
73
Start()74 int32_t WifiDisplay::Start()
75 {
76 SHARING_LOGD("trace.");
77 if (wfdSinkImpl_ && mode_ == SINK) {
78 auto ret = wfdSinkImpl_->Start();
79 if (ret != 0) {
80 SHARING_LOGE("start wifi display failed");
81 }
82
83 return ret;
84 }
85
86 return ERR_GENERAL_ERROR;
87 }
88
AppendSurface(std::string devId,uint64_t surfaceId)89 int32_t WifiDisplay::AppendSurface(std::string devId, uint64_t surfaceId)
90 {
91 SHARING_LOGD("trace.");
92 if (wfdSinkImpl_ && mode_ == SINK) {
93 auto ret = wfdSinkImpl_->AppendSurface(devId, surfaceId);
94 if (ret != 0) {
95 SHARING_LOGE("failed");
96 }
97
98 return ret;
99 }
100
101 return ERR_GENERAL_ERROR;
102 }
103
SetMediaFormat(std::string deviceId,CastCodecAttr videoAttr,CastCodecAttr audioAttr)104 int32_t WifiDisplay::SetMediaFormat(std::string deviceId, CastCodecAttr videoAttr, CastCodecAttr audioAttr)
105 {
106 SHARING_LOGD("trace.");
107 if (IsVideoCodecAttr(videoAttr) && IsAudioCodecAttr(audioAttr) && mode_ == SINK) {
108 CodecAttr videoCodecAttr;
109 videoCodecAttr.formatId = videoAttr.format;
110 videoCodecAttr.codecType = (int32_t)videoAttr.codecType;
111
112 CodecAttr audioCodecAttr;
113 audioCodecAttr.formatId = audioAttr.format;
114 audioCodecAttr.codecType = (int32_t)audioAttr.codecType;
115
116 if (wfdSinkImpl_) {
117 return wfdSinkImpl_->SetMediaFormat(deviceId, videoCodecAttr, audioCodecAttr);
118 }
119 }
120
121 return ERR_GENERAL_ERROR;
122 }
123
Play(std::string devId)124 int32_t WifiDisplay::Play(std::string devId)
125 {
126 SHARING_LOGD("trace.");
127 if (wfdSinkImpl_ && mode_ == SINK) {
128 auto ret = wfdSinkImpl_->Play(devId);
129 if (ret != 0) {
130 SHARING_LOGE("start protocol interaction failed");
131 }
132
133 return ret;
134 }
135
136 return ERR_GENERAL_ERROR;
137 }
138
Pause(std::string devId)139 int32_t WifiDisplay::Pause(std::string devId)
140 {
141 SHARING_LOGD("trace.");
142 if (wfdSinkImpl_ && mode_ == SINK) {
143 auto ret = wfdSinkImpl_->Pause(devId);
144 if (ret != 0) {
145 SHARING_LOGE("pause the playback failed");
146 }
147
148 return ret;
149 }
150
151 return ERR_GENERAL_ERROR;
152 }
153
Close(std::string devId)154 int32_t WifiDisplay::Close(std::string devId)
155 {
156 SHARING_LOGD("trace.");
157 if (wfdSinkImpl_ && mode_ == SINK) {
158 auto ret = wfdSinkImpl_->Close(devId);
159 if (ret != 0) {
160 SHARING_LOGE("close the source failed");
161 }
162
163 return ret;
164 }
165
166 return ERR_GENERAL_ERROR;
167 }
168
StartDiscover()169 int32_t WifiDisplay::StartDiscover()
170 {
171 SHARING_LOGD("trace.");
172 return ERR_OK;
173 }
174
StopDiscover()175 int32_t WifiDisplay::StopDiscover()
176 {
177 SHARING_LOGD("trace.");
178 return ERR_OK;
179 }
180
AddDevice(const CastDeviceInfo & deviceInfo)181 int32_t WifiDisplay::AddDevice(const CastDeviceInfo &deviceInfo)
182 {
183 SHARING_LOGD("trace.");
184 return ERR_OK;
185 }
186
RemoveDevice(std::string deviceId)187 int32_t WifiDisplay::RemoveDevice(std::string deviceId)
188 {
189 SHARING_LOGD("trace.");
190 return ERR_OK;
191 }
192
SetListener(const std::shared_ptr<IWfdListener> & listener)193 int32_t WifiDisplay::SetListener(const std::shared_ptr<IWfdListener> &listener)
194 {
195 SHARING_LOGD("trace.");
196 RETURN_INVALID_IF_NULL(listener);
197
198 listener_ = listener;
199 return ERR_OK;
200 }
201
OnInfo(std::shared_ptr<BaseMsg> & info)202 void WifiDisplay::OnInfo(std::shared_ptr<BaseMsg> &info)
203 {
204 SHARING_LOGD("trace.");
205 CHECK_AND_RETURN_LOG(info != nullptr, "info is nullptr.");
206
207 SHARING_LOGI("msg: %{public}d.", info->GetMsgId());
208 switch (info->GetMsgId()) {
209 case WfdErrorMsg::MSG_ID: {
210 auto data = std::static_pointer_cast<WfdErrorMsg>(info);
211 CastErrorInfo errInfo;
212 errInfo.deviceId = data->mac;
213 errInfo.errorCode = data->errorCode;
214
215 auto listener = listener_.lock();
216 if (listener) {
217 listener->OnError(errInfo);
218 }
219
220 break;
221 }
222 case WfdConnectionChangedMsg::MSG_ID: {
223 auto data = std::static_pointer_cast<WfdConnectionChangedMsg>(info);
224 CastDeviceInfo deviceInfo;
225 deviceInfo.ipAddr = data->ip;
226 deviceInfo.deviceId = data->mac;
227 deviceInfo.state = static_cast<CastDeviceState>(data->state);
228 deviceInfo.deviceName = data->deviceName;
229 deviceInfo.primaryDeviceType = data->primaryDeviceType;
230 deviceInfo.secondaryDeviceType = data->secondaryDeviceType;
231
232 auto callback = listener_.lock();
233 if (callback) {
234 callback->OnDeviceState(deviceInfo);
235 }
236
237 break;
238 }
239 case WfdSurfaceFailureMsg::MSG_ID: {
240 auto data = std::static_pointer_cast<WfdSurfaceFailureMsg>(info);
241 CastErrorInfo errInfo;
242 errInfo.errorCode = ERR_SURFACE_FAILURE;
243
244 auto listener = listener_.lock();
245 if (listener) {
246 listener->OnError(errInfo);
247 }
248
249 break;
250 }
251 default:
252 SHARING_LOGI("none process case.");
253 break;
254 }
255 }
256
IsVideoCodecAttr(CastCodecAttr videoAttr)257 bool WifiDisplay::IsVideoCodecAttr(CastCodecAttr videoAttr)
258 {
259 SHARING_LOGD("trace.");
260 switch (videoAttr.codecType) {
261 case CodecType::CODEC_H264:
262 break;
263 case CodecType::CODEC_H265:
264 break;
265 default:
266 SHARING_LOGE("none process case.");
267 return false;
268 }
269
270 switch (videoAttr.format) {
271 case VideoFormat::VIDEO_640X480_60:
272 break;
273 case VideoFormat::VIDEO_1280X720_25:
274 break;
275 case VideoFormat::VIDEO_1280X720_30:
276 break;
277 case VideoFormat::VIDEO_1920X1080_25:
278 break;
279 case VideoFormat::VIDEO_1920X1080_30:
280 break;
281 default:
282 SHARING_LOGE("none process case.");
283 return false;
284 }
285
286 return true;
287 }
288
IsAudioCodecAttr(CastCodecAttr audioAttr)289 bool WifiDisplay::IsAudioCodecAttr(CastCodecAttr audioAttr)
290 {
291 SHARING_LOGD("trace.");
292 switch (audioAttr.codecType) {
293 case CodecType::CODEC_AAC:
294 break;
295 default:
296 SHARING_LOGI("none process case.");
297 return false;
298 }
299
300 switch (audioAttr.format) {
301 case AudioFormat::AUDIO_44100_8_1:
302 break;
303 case AudioFormat::AUDIO_44100_8_2:
304 break;
305 case AudioFormat::AUDIO_44100_16_1:
306 break;
307 case AudioFormat::AUDIO_44100_16_2:
308 break;
309 case AudioFormat::AUDIO_48000_8_1:
310 break;
311 case AudioFormat::AUDIO_48000_8_2:
312 break;
313 case AudioFormat::AUDIO_48000_16_1:
314 break;
315 case AudioFormat::AUDIO_48000_16_2:
316 break;
317 default:
318 SHARING_LOGI("none process case.");
319 return false;
320 }
321
322 return true;
323 }
324
325 } // namespace Sharing
326 } // namespace OHOS