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