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