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