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_session.h"
17 #include <thread>
18 #include "avsession_log.h"
19 #include "avsession_errors.h"
20 #include "av_router.h"
21
22 using namespace OHOS::CastEngine;
23
24 namespace OHOS::AVSession {
~HwCastProviderSession()25 HwCastProviderSession::~HwCastProviderSession()
26 {
27 SLOGI("destruct the HwCastProviderSession");
28 Release();
29 }
30
Init()31 int32_t HwCastProviderSession::Init()
32 {
33 SLOGI("Init the HwCastProviderSession");
34 if (castSession_) {
35 return castSession_->RegisterListener(shared_from_this());
36 }
37 return AVSESSION_ERROR;
38 }
39
SetProtocolType(CastEngine::ProtocolType protocolType)40 void HwCastProviderSession::SetProtocolType(CastEngine::ProtocolType protocolType)
41 {
42 SLOGI("SetProtocolType %{public}d", static_cast<int>(protocolType));
43 protocolType_ = protocolType;
44 }
45
Release()46 void HwCastProviderSession::Release()
47 {
48 SLOGI("release the HwCastProviderSession");
49 if (!castSession_) {
50 SLOGE("castSession_ is not exist");
51 return;
52 }
53 castSession_->Release();
54 castSession_ = nullptr;
55 }
56
AddDevice(const std::string deviceId,uint32_t spid)57 bool HwCastProviderSession::AddDevice(const std::string deviceId, uint32_t spid)
58 {
59 SLOGI("AddDevice in HwCastProviderSession");
60 if (!castSession_) {
61 SLOGE("castSession_ is not exist");
62 return false;
63 }
64 CastRemoteDevice castRemoteDevice = {};
65 castRemoteDevice.deviceId = deviceId;
66 castRemoteDevice.spid = spid;
67
68 int32_t ret = castSession_->AddDevice(castRemoteDevice);
69 avToastDeviceState_ = ConnectionState::STATE_CONNECTING;
70 SLOGI("AddDevice in HwCastProviderSession with ret %{public}d", static_cast<int32_t>(ret));
71 return (ret == 0) ? true : false;
72 }
73
RemoveDevice(std::string deviceId,bool continuePlay)74 bool HwCastProviderSession::RemoveDevice(std::string deviceId, bool continuePlay)
75 {
76 SLOGI("RemoveDevice in HwCastProviderSession, continuePlay=%{public}d", static_cast<int32_t>(continuePlay));
77 if (!castSession_) {
78 SLOGE("castSession_ is not exist");
79 return false;
80 }
81
82 avToastDeviceState_ = ConnectionState::STATE_DISCONNECTED;
83 if (continuePlay) {
84 return castSession_->RemoveDevice(deviceId, CastEngine::DeviceRemoveAction::ACTION_CONTINUE_PLAY);
85 }
86 return castSession_->RemoveDevice(deviceId);
87 }
88
CreateStreamPlayer()89 std::shared_ptr<CastEngine::IStreamPlayer> HwCastProviderSession::CreateStreamPlayer()
90 {
91 SLOGI("CreateStreamPlayer in HwCastProviderSession");
92 if (!castSession_) {
93 SLOGE("castSession_ is not exist");
94 return nullptr;
95 }
96
97 std::shared_ptr<CastEngine::IStreamPlayer> streamPlayerPtr = nullptr;
98 castSession_->CreateStreamPlayer(streamPlayerPtr);
99 return streamPlayerPtr;
100 }
101
GetRemoteDrmCapabilities(std::string deviceId,std::vector<std::string> & drmCapabilities)102 bool HwCastProviderSession::GetRemoteDrmCapabilities(std::string deviceId, std::vector<std::string> &drmCapabilities)
103 {
104 SLOGI("enter GetRemoteDrmCapabilities");
105 if (!castSession_) {
106 SLOGE("castSession_ is not exist");
107 return false;
108 }
109 CastRemoteDevice castRemoteDevice = {};
110 castSession_->GetRemoteDeviceInfo(deviceId, castRemoteDevice);
111 drmCapabilities = castRemoteDevice.drmCapabilities;
112 return true;
113 }
114
GetRemoteNetWorkId(std::string deviceId,std::string & networkId)115 bool HwCastProviderSession::GetRemoteNetWorkId(std::string deviceId, std::string &networkId)
116 {
117 SLOGI("enter GetRemoteNetWorkId");
118 if (!castSession_) {
119 SLOGE("castSession_ is not exist");
120 return false;
121 }
122 CastRemoteDevice castRemoteDevice = {};
123 castSession_->GetRemoteDeviceInfo(deviceId, castRemoteDevice);
124 networkId = castRemoteDevice.networkId;
125 return true;
126 }
127
SetStreamState(DeviceInfo deviceInfo)128 bool HwCastProviderSession::SetStreamState(DeviceInfo deviceInfo)
129 {
130 std::lock_guard lockGuard(mutex_);
131 for (auto listener : castSessionStateListenerList_) {
132 if (listener != nullptr) {
133 SLOGI("trigger the OnCastStateChange for registered listeners");
134 listener->OnCastStateChange(deviceStateConnection, deviceInfo);
135 }
136 }
137 stashDeviceState_ = deviceStateConnection;
138 stashDeviceId_ = deviceInfo.deviceId_;
139 return true;
140 }
141
RegisterCastSessionStateListener(std::shared_ptr<IAVCastSessionStateListener> listener)142 bool HwCastProviderSession::RegisterCastSessionStateListener(std::shared_ptr<IAVCastSessionStateListener> listener)
143 {
144 SLOGI("RegisterCastSessionStateListener");
145 if (listener == nullptr) {
146 SLOGE("RegisterCastSessionStateListener failed for the listener is nullptr");
147 return false;
148 }
149 {
150 std::lock_guard lockGuard(mutex_);
151 if (find(castSessionStateListenerList_.begin(), castSessionStateListenerList_.end(), listener)
152 != castSessionStateListenerList_.end()) {
153 SLOGE("listener is already in castSessionStateListenerList_");
154 return false;
155 }
156 castSessionStateListenerList_.emplace_back(listener);
157 SLOGI("register listener finished with size %{public}d and check stash state %{public}d",
158 static_cast<int>(castSessionStateListenerList_.size()), static_cast<int32_t>(stashDeviceState_));
159 }
160 if (stashDeviceState_ > 0) {
161 DeviceInfo deviceInfo;
162 deviceInfo.deviceId_ = stashDeviceId_;
163 deviceInfo.deviceName_ = "RemoteCast";
164 deviceInfo.castCategory_ = AVCastCategory::CATEGORY_LOCAL;
165 if (listener != nullptr) {
166 SLOGI("retry trigger the OnCastStateChange for registered listeners");
167 listener->OnCastStateChange(static_cast<int>(stashDeviceState_), deviceInfo);
168 }
169 }
170 return true;
171 }
172
UnRegisterCastSessionStateListener(std::shared_ptr<IAVCastSessionStateListener> listener)173 bool HwCastProviderSession::UnRegisterCastSessionStateListener(std::shared_ptr<IAVCastSessionStateListener> listener)
174 {
175 if (listener == nullptr) {
176 SLOGE("UnRegisterCastSessionStateListener failed for the listener is nullptr");
177 return false;
178 }
179 std::lock_guard lockGuard(mutex_);
180 for (auto iter = castSessionStateListenerList_.begin(); iter != castSessionStateListenerList_.end();) {
181 if (*iter == listener) {
182 castSessionStateListenerList_.erase(iter);
183 SLOGI("unRegister finished with size %{public}d", static_cast<int>(castSessionStateListenerList_.size()));
184 return true;
185 } else {
186 ++iter;
187 }
188 }
189
190 return false;
191 }
192
OnDeviceState(const CastEngine::DeviceStateInfo & stateInfo)193 void HwCastProviderSession::OnDeviceState(const CastEngine::DeviceStateInfo &stateInfo)
194 {
195 int32_t deviceState = static_cast<int32_t>(stateInfo.deviceState);
196 std::vector<std::shared_ptr<IAVCastSessionStateListener>> tempListenerList;
197 SLOGI("OnDeviceState from cast %{public}d", static_cast<int>(deviceState));
198 if (stashDeviceState_ == deviceState) {
199 SLOGI("duplicate devicestate");
200 return;
201 }
202
203 computeToastOnDeviceState(stateInfo.deviceState);
204 {
205 std::lock_guard lockGuard(mutex_);
206 if (castSessionStateListenerList_.size() == 0) {
207 SLOGI("current has not registered listener, stash state: %{public}d", deviceState);
208 stashDeviceState_ = deviceState;
209 stashDeviceId_ = stateInfo.deviceId;
210 return;
211 }
212 stashDeviceState_ = -1;
213 tempListenerList = castSessionStateListenerList_;
214 }
215
216 std::vector<AudioStreamInfo> streamInfos;
217 if (protocolType_ == CastEngine::ProtocolType::CAST_PLUS_AUDIO) {
218 SLOGI("OnDeviceState CAST_PLUS_AUDIO GetRemoteDeviceInfo");
219 CastRemoteDevice castRemoteDevice = {};
220 castSession_->GetRemoteDeviceInfo(stateInfo.deviceId, castRemoteDevice);
221 AudioStreamInfo audioStreamInfo;
222 audioStreamInfo.samplingRate = static_cast<AudioSamplingRate>(castRemoteDevice.audioCapability.samplingRate);
223 audioStreamInfo.encoding = static_cast<AudioEncodingType>(castRemoteDevice.audioCapability.encoding);
224 audioStreamInfo.format = static_cast<AudioSampleFormat>(castRemoteDevice.audioCapability.format);
225 audioStreamInfo.channels = static_cast<AudioChannel>(castRemoteDevice.audioCapability.channels);
226 audioStreamInfo.channelLayout = static_cast<AudioChannelLayout>(castRemoteDevice.audioCapability.channelLayout);
227 streamInfos.push_back(audioStreamInfo);
228 }
229
230 for (auto listener : tempListenerList) {
231 DeviceInfo deviceInfo;
232 deviceInfo.deviceId_ = stateInfo.deviceId;
233 deviceInfo.deviceName_ = "RemoteCast";
234 deviceInfo.castCategory_ = AVCastCategory::CATEGORY_LOCAL;
235 deviceInfo.audioCapabilities_.streamInfos_ = streamInfos;
236 if (listener != nullptr) {
237 SLOGI("trigger the OnCastStateChange for ListSize %{public}d", static_cast<int>(tempListenerList.size()));
238 listener->OnCastStateChange(static_cast<int>(deviceState), deviceInfo);
239 OnDeviceStateChange(stateInfo);
240 }
241 }
242 }
243
computeToastOnDeviceState(CastEngine::DeviceState state)244 void HwCastProviderSession::computeToastOnDeviceState(CastEngine::DeviceState state)
245 {
246 // device connected
247 if (state == CastEngine::DeviceState::STREAM) {
248 avToastDeviceState_ = ConnectionState::STATE_CONNECTED;
249 return;
250 }
251 // stream to mirror scene, session is not hold by avsession
252 if (state == CastEngine::DeviceState::STREAM_TO_MIRROR) {
253 avToastDeviceState_ = ConnectionState::STATE_DISCONNECTED;
254 return;
255 }
256 if (state != CastEngine::DeviceState::DISCONNECTED) {
257 return;
258 }
259 // device disconnected after successful connection
260 if (avToastDeviceState_ == ConnectionState::STATE_CONNECTED) {
261 AVSessionUtils::PublishCommonEvent(MEDIA_CAST_DISCONNECT);
262 return;
263 }
264 // device disconnected during connecting
265 if (avToastDeviceState_ == ConnectionState::STATE_CONNECTING) {
266 AVSessionUtils::PublishCommonEvent(MEDIA_CAST_ERROR);
267 return;
268 }
269 }
270
OnDeviceStateChange(const CastEngine::DeviceStateInfo & stateInfo)271 void HwCastProviderSession::OnDeviceStateChange(const CastEngine::DeviceStateInfo &stateInfo)
272 {
273 SLOGI("OnDeviceStateChange from cast with deviceId %{public}s, state %{public}d, reasonCode %{public}d",
274 stateInfo.deviceId.c_str(), static_cast<int32_t>(stateInfo.deviceState),
275 static_cast<int32_t>(stateInfo.reasonCode));
276
277 DeviceState deviceState;
278 deviceState.deviceId = stateInfo.deviceId;
279 deviceState.deviceState = static_cast<int32_t>(stateInfo.deviceState);
280 deviceState.reasonCode = static_cast<int32_t>(stateInfo.reasonCode);
281
282 AVRouter::GetInstance().OnDeviceStateChange(deviceState);
283 }
284
OnEvent(const CastEngine::EventId & eventId,const std::string & jsonParam)285 void HwCastProviderSession::OnEvent(const CastEngine::EventId &eventId, const std::string &jsonParam)
286 {
287 SLOGI("OnEvent from cast with eventId %{public}d, %{public}s", eventId, jsonParam.c_str());
288 std::string jsonStr = jsonParam;
289 std::lock_guard lockGuard(mutex_);
290 int32_t castEventId = static_cast<int>(eventId);
291 if (castEventId >= eventIdStart && castEventId <= eventIdEnd) {
292 SLOGI("trigger the OnCastEventRecv");
293 }
294 }
295 }
296