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