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 "hw_cast_provider.h"
17 #include <thread>
18 #include "cast_session_manager.h"
19 #include "hw_cast_stream_player.h"
20 #include "avsession_log.h"
21 #include "avsession_errors.h"
22 #include "avsession_radar.h"
23
24 using namespace OHOS::CastEngine::CastEngineClient;
25 using namespace OHOS::CastEngine;
26
27 namespace OHOS::AVSession {
28 const uint32_t UNTRUSTED_DEVICE = 0;
29 const uint32_t TRUSTED_DEVICE = 1;
30
HwCastProvider()31 HwCastProvider::HwCastProvider()
32 {
33 SLOGD("pre construct the HwCastProvider");
34 std::lock_guard lockGuard(mutexLock_);
35 SLOGI("destruct the HwCastProvider");
36 }
37
~HwCastProvider()38 HwCastProvider::~HwCastProvider()
39 {
40 SLOGD("pre destruct the HwCastProvider");
41 std::lock_guard lockGuard(mutexLock_);
42 SLOGI("destruct the HwCastProvider");
43 }
44
Init()45 int32_t HwCastProvider::Init()
46 {
47 SLOGD("pre init the HwCastProvider");
48 std::lock_guard lockGuard(mutexLock_);
49 int32_t ret = CastSessionManager::GetInstance().RegisterListener(shared_from_this());
50 SLOGI("Init the HwCastProvider %{public}d", ret);
51 return ret;
52 }
53
StartDeviceLogging(int32_t fd,uint32_t maxSize)54 int32_t HwCastProvider::StartDeviceLogging(int32_t fd, uint32_t maxSize)
55 {
56 SLOGI("start StartDeviceLogging, fd is %{public}d and maxSize is %{public}d", fd, maxSize);
57 return CastSessionManager::GetInstance().StartDeviceLogging(fd, maxSize);
58 }
59
StopDeviceLogging()60 int32_t HwCastProvider::StopDeviceLogging()
61 {
62 SLOGI("StopDeviceLogging");
63 return CastSessionManager::GetInstance().StartDeviceLogging(-1, 0);
64 }
65
StartDiscovery(int castCapability,std::vector<std::string> drmSchemes)66 bool HwCastProvider::StartDiscovery(int castCapability, std::vector<std::string> drmSchemes)
67 {
68 SLOGI("start discovery and the castCapability is %{public}d", castCapability);
69 AVSessionRadarInfo info("HwCastProvider::StartDiscovery");
70 AVSessionRadar::GetInstance().StartCastDiscoveryBegin(info);
71 auto ret = CastSessionManager::GetInstance().StartDiscovery(castCapability, drmSchemes);
72 if (ret != 0) {
73 info.errorCode_ = ret;
74 AVSessionRadar::GetInstance().FailToStartCastDiscovery(info);
75 } else {
76 AVSessionRadar::GetInstance().StartCastDiscoveryEnd(info);
77 }
78 return ret;
79 }
80
StopDiscovery()81 void HwCastProvider::StopDiscovery()
82 {
83 SLOGI("stop discovery");
84 AVSessionRadarInfo info("HwCastProvider::StopDiscovery");
85 AVSessionRadar::GetInstance().StopCastDiscoveryBegin(info);
86 auto ret = CastSessionManager::GetInstance().StopDiscovery();
87 if (ret != 0) {
88 info.errorCode_ = ret;
89 AVSessionRadar::GetInstance().FailToStopCastDiscovery(info);
90 } else {
91 AVSessionRadar::GetInstance().StopCastDiscoveryEnd(info);
92 }
93 }
94
SetDiscoverable(const bool enable)95 int32_t HwCastProvider::SetDiscoverable(const bool enable)
96 {
97 SLOGI("SetDiscoverable in %{public}d", static_cast<int32_t>(enable));
98 return AVSESSION_SUCCESS;
99 }
100
Release()101 void HwCastProvider::Release()
102 {
103 SLOGI("Release the HwCastProvider");
104 {
105 std::lock_guard lockGuard(mutexLock_);
106 hwCastProviderSessionMap_.clear();
107 avCastControllerMap_.clear();
108 castStateListenerList_.clear();
109 castFlag_.clear();
110 }
111 if (!isRelease_) {
112 SLOGI("release in with check pass");
113 isRelease_ = true;
114 } else {
115 SLOGW("already in release, check return");
116 return;
117 }
118 CastSessionManager::GetInstance().UnregisterListener();
119 CastSessionManager::GetInstance().Release();
120 SLOGD("Release done");
121 }
122
StartCastSession()123 int HwCastProvider::StartCastSession()
124 {
125 SLOGI("StartCastSession begin");
126 CastSessionProperty property = {CastEngine::ProtocolType::CAST_PLUS_STREAM, CastEngine::EndType::CAST_SOURCE};
127 std::shared_ptr<ICastSession> castSession = nullptr;
128 int ret = CastSessionManager::GetInstance().CreateCastSession(property, castSession);
129 if (ret != AVSESSION_SUCCESS) {
130 AVSessionRadarInfo info("HwCastProvider::StartCastSession");
131 info.errorCode_ = ret;
132 AVSessionRadar::GetInstance().FailToStartCast(info);
133 SLOGI("StartCastSession failed and return the ret is %{public}d", ret);
134 return AVSESSION_ERROR;
135 }
136 int castId;
137 {
138 SLOGI("StartCastSession pre check lock");
139 std::lock_guard lockGuard(mutexLock_);
140 SLOGI("StartCastSession check lock");
141 std::vector<bool>::iterator iter = find(castFlag_.begin(), castFlag_.end(), false);
142 if (iter == castFlag_.end()) {
143 SLOGE("StartCastSession failed");
144 return AVSESSION_ERROR;
145 }
146 *iter = true;
147 castId = iter - castFlag_.begin();
148 auto hwCastProviderSession = std::make_shared<HwCastProviderSession>(castSession);
149 if (hwCastProviderSession) {
150 if (hwCastProviderSession->Init() != AVSESSION_ERROR) {
151 SLOGI("CastSession init successed");
152 } else {
153 hwCastProviderSession->Release();
154 return AVSESSION_ERROR;
155 }
156 }
157 hwCastProviderSessionMap_[castId] = hwCastProviderSession;
158 }
159 SLOGI("StartCastSession successed and return the castId is %{public}d", castId);
160
161 return castId;
162 }
163
StopCastSession(int castId)164 void HwCastProvider::StopCastSession(int castId)
165 {
166 SLOGI("StopCastSession begin with %{public}d", castId);
167 std::lock_guard lockGuard(mutexLock_);
168 SLOGI("StopCastSession check lock");
169 auto hwCastStreamPlayer = avCastControllerMap_[castId];
170 if (hwCastStreamPlayer) {
171 hwCastStreamPlayer->Release();
172 }
173 avCastControllerMap_.erase(castId);
174 int32_t mirrorCastId = static_cast<int32_t>((static_cast<uint64_t>(mirrorCastHandle) << 32) >> 32);
175 if (castId == mirrorCastId) {
176 return;
177 }
178 if (hwCastProviderSessionMap_.find(castId) == hwCastProviderSessionMap_.end()) {
179 SLOGE("no need to release castSession for castId %{public}d is not exit in hwCastProviderSessionMap_", castId);
180 return;
181 }
182 auto hwCastProviderSession = hwCastProviderSessionMap_[castId];
183 if (hwCastProviderSession) {
184 hwCastProviderSession->Release();
185 }
186 hwCastProviderSessionMap_.erase(castId);
187 castFlag_[castId] = false;
188 }
189
AddCastDevice(int castId,DeviceInfo deviceInfo)190 bool HwCastProvider::AddCastDevice(int castId, DeviceInfo deviceInfo)
191 {
192 SLOGI("AddCastDevice with config castSession and corresonding castId is %{public}d", castId);
193 std::lock_guard lockGuard(mutexLock_);
194 SLOGI("add device check lock done");
195
196 if (hwCastProviderSessionMap_.find(castId) == hwCastProviderSessionMap_.end()) {
197 SLOGE("the castId corresonding to castSession is not exist");
198 return false;
199 }
200 auto hwCastProviderSession = hwCastProviderSessionMap_[castId];
201 if (!hwCastProviderSession) {
202 SLOGE("the castId corresonding to castSession is nullptr");
203 return false;
204 }
205
206 return hwCastProviderSession->AddDevice(deviceInfo.deviceId_);
207 }
208
RemoveCastDevice(int castId,DeviceInfo deviceInfo,bool continuePlay)209 bool HwCastProvider::RemoveCastDevice(int castId, DeviceInfo deviceInfo, bool continuePlay)
210 {
211 SLOGI("RemoveCastDevice with config castSession and corresonding castId is %{public}d", castId);
212 std::lock_guard lockGuard(mutexLock_);
213 SLOGI("remove device check lock");
214 if (hwCastProviderSessionMap_.find(castId) == hwCastProviderSessionMap_.end()) {
215 SLOGE("the castId corresonding to castSession is not exist");
216 return false;
217 }
218 auto hwCastProviderSession = hwCastProviderSessionMap_[castId];
219 if (!hwCastProviderSession) {
220 SLOGE("the castId corresonding to castSession is nullptr");
221 return false;
222 }
223
224 return hwCastProviderSession->RemoveDevice(deviceInfo.deviceId_, continuePlay);
225 }
226
RegisterCastStateListener(std::shared_ptr<IAVCastStateListener> listener)227 bool HwCastProvider::RegisterCastStateListener(std::shared_ptr<IAVCastStateListener> listener)
228 {
229 SLOGI("RegisterCastStateListener in");
230 std::lock_guard lockGuard(mutexLock_);
231 SLOGI("RegisterCastStateListener in pass lock");
232 if (listener == nullptr) {
233 SLOGE("RegisterCastStateListener the listener is nullptr");
234 return false;
235 }
236 if (find(castStateListenerList_.begin(), castStateListenerList_.end(), listener) != castStateListenerList_.end()) {
237 SLOGE("RegisterCastStateListener the listener is already be registered");
238 return false;
239 }
240 SLOGI("RegisterCastStateListener successed, and save it in the castStateListenerList_");
241 castStateListenerList_.emplace_back(listener);
242
243 return true;
244 }
245
UnRegisterCastStateListener(std::shared_ptr<IAVCastStateListener> listener)246 bool HwCastProvider::UnRegisterCastStateListener(std::shared_ptr<IAVCastStateListener> listener)
247 {
248 SLOGI("UnRegisterCastStateListener in");
249 std::lock_guard lockGuard(mutexLock_);
250 SLOGI("UnRegisterCastStateListener in pass lock");
251 if (listener == nullptr) {
252 SLOGE("UnRegisterCastStateListener the listener is nullptr");
253 return false;
254 }
255 for (auto iter = castStateListenerList_.begin(); iter != castStateListenerList_.end();) {
256 if (*iter == listener) {
257 castStateListenerList_.erase(iter);
258 SLOGI("UnRegisterCastStateListener successed, and erase it from castStateListenerList_");
259 return true;
260 } else {
261 ++iter;
262 }
263 }
264 SLOGE("listener is not found in castStateListenerList_, so UnRegisterCastStateListener failed");
265
266 return false;
267 }
268
GetRemoteController(int castId)269 std::shared_ptr<IAVCastControllerProxy> HwCastProvider::GetRemoteController(int castId)
270 {
271 SLOGI("get remote controller with castId %{public}d", static_cast<int32_t>(castId));
272 std::lock_guard lockGuard(mutexLock_);
273 SLOGI("get remote controller check lock with castId %{public}d", static_cast<int32_t>(castId));
274 if (avCastControllerMap_.find(castId) != avCastControllerMap_.end()) {
275 SLOGI("the castId corresonding to streamPlayer is already exist");
276 return avCastControllerMap_[castId];
277 }
278 if (hwCastProviderSessionMap_.find(castId) == hwCastProviderSessionMap_.end()) {
279 SLOGE("No castSession corresonding to castId exists");
280 return nullptr;
281 }
282 auto hwCastProviderSession = hwCastProviderSessionMap_[castId];
283 if (hwCastProviderSession == nullptr) {
284 SLOGE("castSession corresonding to castId is nullptr");
285 return nullptr;
286 }
287 std::shared_ptr<IStreamPlayer> streamPlayer = hwCastProviderSession->CreateStreamPlayer();
288 std::shared_ptr<HwCastStreamPlayer> hwCastStreamPlayer = std::make_shared<HwCastStreamPlayer>(streamPlayer);
289 if (!hwCastStreamPlayer) {
290 SLOGE("the created hwCastStreamPlayer is nullptr");
291 return nullptr;
292 }
293 if (hwCastStreamPlayer->Init() == AVSESSION_ERROR) {
294 SLOGE("hwCastStreamPlayer init failed");
295 return nullptr;
296 }
297 avCastControllerMap_[castId] = hwCastStreamPlayer;
298 SLOGI("Create streamPlayer finished");
299 return hwCastStreamPlayer;
300 }
301
SetStreamState(int64_t castHandle,DeviceInfo deviceInfo)302 bool HwCastProvider::SetStreamState(int64_t castHandle, DeviceInfo deviceInfo)
303 {
304 int32_t castId = static_cast<int32_t>((static_cast<uint64_t>(castHandle) << 32) >> 32);
305 mirrorCastHandle = castHandle;
306 SLOGI("mirrorCastHandle is %{public}lld", static_cast<long long>(mirrorCastHandle));
307 if (hwCastProviderSessionMap_.find(castId) == hwCastProviderSessionMap_.end()) {
308 SLOGE("SetStreamState failed for the castSession corresponding to castId is not exit");
309 return false;
310 }
311 auto hwCastProviderSession = hwCastProviderSessionMap_[castId];
312 if (hwCastProviderSession == nullptr) {
313 SLOGE("SetStreamState failed for the hwCastProviderSession is nullptr");
314 return false;
315 }
316 return hwCastProviderSession->SetStreamState(deviceInfo);
317 }
318
GetRemoteNetWorkId(int32_t castId,std::string deviceId,std::string & networkId)319 bool HwCastProvider::GetRemoteNetWorkId(int32_t castId, std::string deviceId, std::string &networkId)
320 {
321 SLOGI("enter GetRemoteNetWorkId");
322 if (hwCastProviderSessionMap_.find(castId) == hwCastProviderSessionMap_.end()) {
323 SLOGE("GetRemoteNetWorkId failed for the castSession corresponding to castId is not exit");
324 return false;
325 }
326 auto hwCastProviderSession = hwCastProviderSessionMap_[castId];
327 if (hwCastProviderSession == nullptr) {
328 SLOGE("GetRemoteNetWorkId failed for the hwCastProviderSession is nullptr");
329 return false;
330 }
331 return hwCastProviderSession->GetRemoteNetWorkId(deviceId, networkId);
332 }
333
GetMirrorCastHandle()334 int64_t HwCastProvider::GetMirrorCastHandle()
335 {
336 return mirrorCastHandle;
337 }
338
RegisterCastSessionStateListener(int castId,std::shared_ptr<IAVCastSessionStateListener> listener)339 bool HwCastProvider::RegisterCastSessionStateListener(int castId,
340 std::shared_ptr<IAVCastSessionStateListener> listener)
341 {
342 SLOGD("RegisterCastSessionStateListener for castId %{public}d", castId);
343 if (listener == nullptr) {
344 SLOGE("RegisterCastSessionStateListener failed for the listener is nullptr");
345 return false;
346 }
347 std::lock_guard lockGuard(mutexLock_);
348 SLOGI("register castsession state listener check lock with castId %{public}d", static_cast<int32_t>(castId));
349 if (hwCastProviderSessionMap_.find(castId) == hwCastProviderSessionMap_.end()) {
350 SLOGE("RegisterCastSessionStateListener failed for the castSession corresponding to castId is not exit");
351 return false;
352 }
353 auto hwCastProviderSession = hwCastProviderSessionMap_[castId];
354 if (hwCastProviderSession == nullptr) {
355 SLOGE("RegisterCastSessionStateListener failed for the hwCastProviderSession is nullptr");
356 return false;
357 }
358
359 return hwCastProviderSession->RegisterCastSessionStateListener(listener);
360 }
361
UnRegisterCastSessionStateListener(int castId,std::shared_ptr<IAVCastSessionStateListener> listener)362 bool HwCastProvider::UnRegisterCastSessionStateListener(int castId,
363 std::shared_ptr<IAVCastSessionStateListener> listener)
364 {
365 if (listener == nullptr) {
366 SLOGE("UnRegisterCastSessionStateListener failed for the listener is nullptr");
367 return false;
368 }
369 std::lock_guard lockGuard(mutexLock_);
370 SLOGI("unregister castsession state listener check lock with castId %{public}d", static_cast<int32_t>(castId));
371 if (hwCastProviderSessionMap_.find(castId) == hwCastProviderSessionMap_.end()) {
372 SLOGE("UnRegisterCastSessionStateListener failed for the castSession corresponding to castId is not exit");
373 return false;
374 }
375 auto hwCastProviderSession = hwCastProviderSessionMap_[castId];
376 if (hwCastProviderSession == nullptr) {
377 SLOGE("UnRegisterCastSessionStateListener failed for the hwCastProviderSession is nullptr");
378 return false;
379 }
380
381 return hwCastProviderSession->UnRegisterCastSessionStateListener(listener);
382 }
383
384
OnDeviceFound(const std::vector<CastRemoteDevice> & deviceList)385 void HwCastProvider::OnDeviceFound(const std::vector<CastRemoteDevice> &deviceList)
386 {
387 std::vector<DeviceInfo> deviceInfoList;
388 if (deviceList.empty()) {
389 SLOGW("recv empty deviceList, return");
390 return;
391 }
392 SLOGI("get deviceList size %{public}zu", deviceList.size());
393 for (CastRemoteDevice castRemoteDevice : deviceList) {
394 SLOGI("get devices with deviceName %{public}s", castRemoteDevice.deviceName.c_str());
395 DeviceInfo deviceInfo;
396 deviceInfo.castCategory_ = AVCastCategory::CATEGORY_REMOTE;
397 deviceInfo.deviceId_ = castRemoteDevice.deviceId;
398 deviceInfo.deviceName_ = castRemoteDevice.deviceName;
399 deviceInfo.deviceType_ = static_cast<int>(castRemoteDevice.deviceType);
400 deviceInfo.ipAddress_ = castRemoteDevice.ipAddress;
401 deviceInfo.networkId_ = castRemoteDevice.networkId;
402 deviceInfo.manufacturer_ = castRemoteDevice.manufacturerName;
403 deviceInfo.modelName_ = castRemoteDevice.modelName;
404 deviceInfo.supportedProtocols_ = GetProtocolType(castRemoteDevice.protocolCapabilities);
405 // should be castRemoteDevice.isTrusted ? TRUSTED_DEVICE : UNTRUSTED_DEVICE;
406 deviceInfo.authenticationStatus_ = castRemoteDevice.isLeagacy ? TRUSTED_DEVICE : UNTRUSTED_DEVICE;
407 deviceInfo.supportedDrmCapabilities_ = castRemoteDevice.drmCapabilities;
408 deviceInfo.isLegacy_ = castRemoteDevice.isLeagacy;
409 deviceInfo.mediumTypes_ = static_cast<int32_t>(castRemoteDevice.mediumTypes);
410 deviceInfoList.emplace_back(deviceInfo);
411 }
412 for (auto listener : castStateListenerList_) {
413 if (listener != nullptr) {
414 SLOGI("trigger the OnDeviceAvailable for registered listeners");
415 listener->OnDeviceAvailable(deviceInfoList);
416 }
417 }
418 }
419
OnLogEvent(const int32_t eventId,const int64_t param)420 void HwCastProvider::OnLogEvent(const int32_t eventId, const int64_t param)
421 {
422 SLOGI("eventId is %{public}d, param is %{public}" PRId64, eventId, param);
423 std::lock_guard lockGuard(mutexLock_);
424 for (auto listener : castStateListenerList_) {
425 if (listener != nullptr) {
426 SLOGI("trigger the OnDeviceLogEvent for registered listeners");
427 if (eventId == DeviceLogEventCode::DEVICE_LOG_FULL) {
428 listener->OnDeviceLogEvent(DeviceLogEventCode::DEVICE_LOG_FULL, param);
429 } else {
430 listener->OnDeviceLogEvent(DeviceLogEventCode::DEVICE_LOG_EXCEPTION, param);
431 }
432 }
433 }
434 }
435
OnDeviceOffline(const std::string & deviceId)436 void HwCastProvider::OnDeviceOffline(const std::string& deviceId)
437 {
438 SLOGI("Received on device offline event");
439 for (auto listener : castStateListenerList_) {
440 if (listener != nullptr) {
441 SLOGI("trigger the OnDeviceOffline for registered listeners");
442 listener->OnDeviceOffline(deviceId);
443 }
444 }
445 }
446
OnSessionCreated(const std::shared_ptr<CastEngine::ICastSession> & castSession)447 void HwCastProvider::OnSessionCreated(const std::shared_ptr<CastEngine::ICastSession> &castSession)
448 {
449 SLOGI("Cast provider received session create event");
450 std::thread([this, castSession]() {
451 SLOGI("Cast pvd received session create event and create task thread");
452 for (auto listener : castStateListenerList_) {
453 listener->OnSessionNeedDestroy();
454 SLOGI("Cast pvd received session create event and session destroy check done");
455 }
456 int32_t castId;
457 {
458 std::lock_guard lockGuard(mutexLock_);
459 std::vector<bool>::iterator iter = find(castFlag_.begin(), castFlag_.end(), false);
460 if (iter == castFlag_.end()) {
461 SLOGE("Do not trigger callback due to the castFlag_ used up.");
462 return;
463 }
464 *iter = true;
465 castId = iter - castFlag_.begin();
466 SLOGI("Cast task thread to find flag");
467 }
468 auto hwCastProviderSession = std::make_shared<HwCastProviderSession>(castSession);
469 hwCastProviderSession->Init();
470 {
471 std::lock_guard lockGuard(mutexLock_);
472 hwCastProviderSessionMap_[castId] = hwCastProviderSession;
473 SLOGI("Cast task thread to create player");
474 std::shared_ptr<IStreamPlayer> streamPlayer = hwCastProviderSession->CreateStreamPlayer();
475 std::shared_ptr<HwCastStreamPlayer> hwCastStreamPlayer = std::make_shared<HwCastStreamPlayer>(streamPlayer);
476 hwCastStreamPlayer->Init();
477 avCastControllerMap_[castId] = hwCastStreamPlayer;
478 }
479 SLOGI("Create streamPlayer finished %{public}d", castId);
480 for (auto listener : castStateListenerList_) {
481 listener->OnSessionCreated(castId);
482 }
483 SLOGI("do session create notify finished %{public}d", castId);
484 }).detach();
485 }
486
OnServiceDied()487 void HwCastProvider::OnServiceDied()
488 {
489 for (auto listener : castStateListenerList_) {
490 if (listener != nullptr) {
491 SLOGI("trigger the OnServiceDied for registered listeners");
492 listener->OnCastServerDied();
493 }
494 }
495 }
496
GetProtocolType(uint32_t castProtocolType)497 int32_t HwCastProvider::GetProtocolType(uint32_t castProtocolType)
498 {
499 int32_t protocolType = (castProtocolType & ProtocolType::TYPE_CAST_PLUS_STREAM) |
500 (castProtocolType & ProtocolType::TYPE_DLNA);
501 return protocolType;
502 }
503 } // namespace OHOS::AVSession
504