1 /*
2 * Copyright (c) 2022 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 "remote_session_source_impl.h"
17 #include "json_utils.h"
18 #include "avsession_trace.h"
19 #include "avsession_sysevent.h"
20
21 namespace OHOS::AVSession {
RemoteSessionSourceImpl()22 RemoteSessionSourceImpl::RemoteSessionSourceImpl()
23 {
24 }
25
CreateRemoteSessionSourceImpl()26 extern "C" RemoteSessionSourceImpl* CreateRemoteSessionSourceImpl()
27 {
28 return new(std::nothrow) RemoteSessionSourceImpl();
29 }
30
DestroyRemoteSessionSourceImpl(RemoteSessionSourceImpl * impl)31 extern "C" void DestroyRemoteSessionSourceImpl(RemoteSessionSourceImpl* impl)
32 {
33 delete(impl);
34 }
35
36 // LCOV_EXCL_START
CastSessionToRemote(const sptr<AVSessionItem> & session,const std::string & sourceDevice,const std::string & sinkDevice,const std::string & sinkCapability)37 int32_t RemoteSessionSourceImpl::CastSessionToRemote(const sptr <AVSessionItem>& session,
38 const std::string& sourceDevice,
39 const std::string& sinkDevice,
40 const std::string& sinkCapability)
41 {
42 session_ = session;
43 auto syncer = std::make_shared<RemoteSessionSyncerImpl>(session->GetSessionId(), sourceDevice, sinkDevice);
44 CHECK_AND_RETURN_RET_LOG(syncer != nullptr, AVSESSION_ERROR, "syncer is nullptr");
45 int32_t ret = syncer->Init();
46 CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, ret, "syncer init failed");
47 syncers_[sinkDevice] = syncer;
48 SLOGI("sinkDevice is %{public}s", sinkDevice.c_str());
49
50 RemoteSessionCapabilitySet::GetInstance().AddRemoteCapability(session->GetSessionId(), sinkDevice, sinkCapability);
51
52 CHECK_AND_RETURN_RET_LOG(!syncers_.empty(), AVSESSION_ERROR, "syncers size is empty");
53
54 for (auto iter = syncers_.rbegin(); iter != syncers_.rend(); iter++) {
55 auto sessionSyncer = iter->second;
56 ret = sessionSyncer->RegisterDisconnectNotifier([this] (const std::string& deviceId) {
57 CHECK_AND_RETURN_RET_LOG(!syncers_.empty() && syncers_[deviceId] != nullptr, AVSESSION_ERROR,
58 "syncer is not exist");
59 SLOGE("device %{public}s is disconnected", deviceId.c_str());
60 if (session_ != nullptr) {
61 HISYSEVENT_FAULT("REMOTE_CONTROL_FAILED",
62 "BUNDLE_NAME", session_->GetDescriptor().elementName_.GetBundleName(),
63 "SESSION_TYPE", session_->GetDescriptor().sessionType_,
64 "AUDIO_STATUS", HISYSEVENT_GET_AUDIO_STATUS(session_->GetUid()),
65 "ERROR_TYPE", "REMOTE_DISCONNECTED",
66 "ERROR_INFO", "remote disconnected");
67 }
68 return AVSESSION_SUCCESS;
69 });
70 CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, ret, "AddDisconnectNotifier failed");
71
72 ret = sessionSyncer->RegisterDataNotifier([this] (const SessionDataCategory category,
73 const std::string& deviceId) {
74 AVSESSION_TRACE_SYNC_START("RemoteSessionSourceImpl::DataNotifier");
75 SLOGI("device %{public}s category %{public}d changed", deviceId.c_str(), category);
76 CHECK_AND_RETURN_RET_LOG(session_ != nullptr, AVSESSION_ERROR, "session_ is nullptr");
77 CHECK_AND_RETURN_RET_LOG(!syncers_.empty() && syncers_[deviceId] != nullptr, AVSESSION_ERROR,
78 "syncer is not exist");
79 return HandleSourceSessionDataCategory(category, deviceId);
80 });
81 CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, ret, "AddDataNotifier failed");
82 }
83 return AVSESSION_SUCCESS;
84 }
85 // LCOV_EXCL_STOP
86
87 // LCOV_EXCL_START
HandleSourceSessionDataCategory(const SessionDataCategory category,const std::string & deviceId)88 int32_t RemoteSessionSourceImpl::HandleSourceSessionDataCategory(const SessionDataCategory category,
89 const std::string& deviceId)
90 {
91 if (category == SESSION_DATA_CONTROL_COMMAND) {
92 AVMetaData metaData;
93 AVSESSION_TRACE_SYNC_START("RemoteSessionSourceImpl::SendControlCommand");
94 AVControlCommand command;
95 CHECK_AND_RETURN_RET_LOG(syncers_[deviceId]->GetControlCommand(command) == AVSESSION_SUCCESS,
96 AVSESSION_ERROR, "GetControlCommand failed");
97 session_->ExecuteControllerCommand(command);
98 } else if (category == SESSION_DATA_COMMON_COMMAND) {
99 std::string commonCommand;
100 AAFwk::WantParams commandArgs;
101 AVSESSION_TRACE_SYNC_START("RemoteSessionSourceImpl::SendCommonCommand");
102 CHECK_AND_RETURN_RET_LOG(syncers_[deviceId]->GetCommonCommand(commonCommand, commandArgs) == AVSESSION_SUCCESS,
103 AVSESSION_ERROR, "GetCommonCommand failed");
104 session_->ExecueCommonCommand(commonCommand, commandArgs);
105 } else {
106 SLOGE("Category is illegal");
107 return AVSESSION_ERROR;
108 }
109
110 return AVSESSION_SUCCESS;
111 }
112 // LCOV_EXCL_STOP
113
114 // LCOV_EXCL_START
CancelCastAudio(const std::string & sinkDevice)115 int32_t RemoteSessionSourceImpl::CancelCastAudio(const std::string& sinkDevice)
116 {
117 SLOGI("start");
118 RemoteSessionCapabilitySet::GetInstance().RemoveRemoteCapability(session_->GetSessionId(), sinkDevice);
119 CHECK_AND_RETURN_RET_LOG(!syncers_.empty(), AVSESSION_SUCCESS, "syncer is empty");
120 auto iter = syncers_.begin();
121 while (iter != syncers_.end()) {
122 if (iter->first == sinkDevice) {
123 SLOGI("cancel sinkDevice %{public}s cast audio", sinkDevice.c_str());
124 iter->second->Destroy();
125 iter->second = nullptr;
126 iter = syncers_.erase(iter);
127 }
128 }
129 SLOGI("success");
130 return AVSESSION_SUCCESS;
131 }
132 // LCOV_EXCL_STOP
133
134 // LCOV_EXCL_START
SetAVMetaData(const AVMetaData & metaData)135 int32_t RemoteSessionSourceImpl::SetAVMetaData(const AVMetaData& metaData)
136 {
137 SLOGI("start");
138 CHECK_AND_RETURN_RET_LOG(!syncers_.empty() && session_ != nullptr, AVSESSION_ERROR, "syncers size is zero");
139 for (auto iter = syncers_.rbegin(); iter != syncers_.rend(); iter++) {
140 SLOGI("iter %{public}s", iter->first.c_str());
141 AVMetaData sinkMetaData;
142 auto mask = GetSinkMetaMaskType(iter->first);
143 if (!metaData.CopyToByMask(mask, sinkMetaData)) {
144 continue;
145 }
146 auto ret = iter->second->PutAVMetaData(sinkMetaData);
147 if (ret != AVSESSION_SUCCESS) {
148 HISYSEVENT_FAULT("REMOTE_CONTROL_FAILED",
149 "BUNDLE_NAME", session_->GetDescriptor().elementName_.GetBundleName(),
150 "SESSION_TYPE", session_->GetDescriptor().sessionType_,
151 "AUDIO_STATUS", HISYSEVENT_GET_AUDIO_STATUS(session_->GetUid()),
152 "ERROR_TYPE", "TIME_OUT",
153 "ERROR_INFO", "SetAVMetaData time out");
154 }
155 }
156 SLOGI("success");
157 return AVSESSION_SUCCESS;
158 }
159 // LCOV_EXCL_STOP
160
161 // LCOV_EXCL_START
SetAVPlaybackState(const AVPlaybackState & state)162 int32_t RemoteSessionSourceImpl::SetAVPlaybackState(const AVPlaybackState& state)
163 {
164 SLOGI("start");
165 CHECK_AND_RETURN_RET_LOG(!syncers_.empty() && session_ != nullptr, AVSESSION_ERROR, "syncers size is zero");
166 for (auto iter = syncers_.rbegin(); iter != syncers_.rend(); iter++) {
167 SLOGI("syncer %{public}s", iter->first.c_str());
168 AVPlaybackState sinkState;
169 auto mask = GetSinkPlaybackStateMaskType(iter->first);
170 if (!state.CopyToByMask(mask, sinkState)) {
171 continue;
172 }
173 auto ret = iter->second->PutAVPlaybackState(sinkState);
174 if (ret != AVSESSION_SUCCESS) {
175 HISYSEVENT_FAULT("REMOTE_CONTROL_FAILED",
176 "BUNDLE_NAME", session_->GetDescriptor().elementName_.GetBundleName(),
177 "SESSION_TYPE", session_->GetDescriptor().sessionType_,
178 "AUDIO_STATUS", HISYSEVENT_GET_AUDIO_STATUS(session_->GetUid()),
179 "ERROR_TYPE", "TIME_OUT",
180 "ERROR_INFO", "SetAVPlaybackState time out");
181 }
182 }
183 SLOGI("success");
184 return AVSESSION_SUCCESS;
185 }
186 // LCOV_EXCL_STOP
187
188 // LCOV_EXCL_START
SetSessionEventRemote(const std::string & event,const AAFwk::WantParams & args)189 int32_t RemoteSessionSourceImpl::SetSessionEventRemote(const std::string& event, const AAFwk::WantParams& args)
190 {
191 SLOGI("start");
192 CHECK_AND_RETURN_RET_LOG(!syncers_.empty() && session_ != nullptr, AVSESSION_ERROR, "syncers size is zero");
193 for (auto iter = syncers_.rbegin(); iter != syncers_.rend(); iter++) {
194 SLOGI("iter %{public}s", iter->first.c_str());
195 std::string sinkEvent = event;
196 AAFwk::WantParams sinkArgs = args;
197
198 auto ret = iter->second->PutSessionEvent(sinkEvent, sinkArgs);
199 if (ret != AVSESSION_SUCCESS) {
200 HISYSEVENT_FAULT("REMOTE_CONTROL_FAILED",
201 "BUNDLE_NAME", session_->GetDescriptor().elementName_.GetBundleName(),
202 "SESSION_TYPE", session_->GetDescriptor().sessionType_,
203 "AUDIO_STATUS", HISYSEVENT_GET_AUDIO_STATUS(session_->GetUid()),
204 "ERROR_TYPE", "TIME_OUT",
205 "ERROR_INFO", "SetSessionEventRemote time out");
206 }
207 }
208 SLOGI("success");
209 return AVSESSION_SUCCESS;
210 }
211 // LCOV_EXCL_STOP
212
213 // LCOV_EXCL_START
SetAVQueueItems(const std::vector<AVQueueItem> & items)214 int32_t RemoteSessionSourceImpl::SetAVQueueItems(const std::vector<AVQueueItem>& items)
215 {
216 SLOGI("start");
217 CHECK_AND_RETURN_RET_LOG(!syncers_.empty() && session_ != nullptr, AVSESSION_ERROR, "syncers size is zero");
218 for (auto iter = syncers_.rbegin(); iter != syncers_.rend(); iter++) {
219 SLOGI("iter %{public}s", iter->first.c_str());
220 std::vector<AVQueueItem> sinkItems = items;
221
222 auto ret = iter->second->PutAVQueueItems(sinkItems);
223 if (ret != AVSESSION_SUCCESS) {
224 HISYSEVENT_FAULT("REMOTE_CONTROL_FAILED",
225 "BUNDLE_NAME", session_->GetDescriptor().elementName_.GetBundleName(),
226 "SESSION_TYPE", session_->GetDescriptor().sessionType_,
227 "AUDIO_STATUS", HISYSEVENT_GET_AUDIO_STATUS(session_->GetUid()),
228 "ERROR_TYPE", "TIME_OUT",
229 "ERROR_INFO", "SetAVQueueItems time out");
230 }
231 }
232 SLOGI("success");
233 return AVSESSION_SUCCESS;
234 }
235 // LCOV_EXCL_STOP
236
237 // LCOV_EXCL_START
SetAVQueueTitle(const std::string & title)238 int32_t RemoteSessionSourceImpl::SetAVQueueTitle(const std::string& title)
239 {
240 SLOGI("start");
241 CHECK_AND_RETURN_RET_LOG(!syncers_.empty() && session_ != nullptr, AVSESSION_ERROR, "syncers size is zero");
242 for (auto iter = syncers_.rbegin(); iter != syncers_.rend(); iter++) {
243 SLOGI("iter %{public}s", iter->first.c_str());
244 std::string sinkTitle = title;
245
246 auto ret = iter->second->PutAVQueueTitle(sinkTitle);
247 if (ret != AVSESSION_SUCCESS) {
248 HISYSEVENT_FAULT("REMOTE_CONTROL_FAILED",
249 "BUNDLE_NAME", session_->GetDescriptor().elementName_.GetBundleName(),
250 "SESSION_TYPE", session_->GetDescriptor().sessionType_,
251 "AUDIO_STATUS", HISYSEVENT_GET_AUDIO_STATUS(session_->GetUid()),
252 "ERROR_TYPE", "TIME_OUT",
253 "ERROR_INFO", "SetAVQueueTitle time out");
254 }
255 }
256 SLOGI("success");
257 return AVSESSION_SUCCESS;
258 }
259 // LCOV_EXCL_STOP
260
261 // LCOV_EXCL_START
SetExtrasRemote(const AAFwk::WantParams & extras)262 int32_t RemoteSessionSourceImpl::SetExtrasRemote(const AAFwk::WantParams& extras)
263 {
264 SLOGI("start");
265 CHECK_AND_RETURN_RET_LOG(!syncers_.empty() && session_ != nullptr, AVSESSION_ERROR, "syncers size is zero");
266 for (auto iter = syncers_.rbegin(); iter != syncers_.rend(); iter++) {
267 SLOGI("iter %{public}s", iter->first.c_str());
268 AAFwk::WantParams sinkExtras = extras;
269
270 auto ret = iter->second->PutExtras(sinkExtras);
271 if (ret != AVSESSION_SUCCESS) {
272 HISYSEVENT_FAULT("REMOTE_CONTROL_FAILED",
273 "BUNDLE_NAME", session_->GetDescriptor().elementName_.GetBundleName(),
274 "SESSION_TYPE", session_->GetDescriptor().sessionType_,
275 "AUDIO_STATUS", HISYSEVENT_GET_AUDIO_STATUS(session_->GetUid()),
276 "ERROR_TYPE", "TIME_OUT",
277 "ERROR_INFO", "SetExtrasRemote time out");
278 }
279 }
280 SLOGI("success");
281 return AVSESSION_SUCCESS;
282 }
283 // LCOV_EXCL_STOP
284
285 // LCOV_EXCL_START
GetSinkMetaMaskType(const std::string & sinkDevice)286 AVMetaData::MetaMaskType RemoteSessionSourceImpl::GetSinkMetaMaskType(const std::string& sinkDevice)
287 {
288 std::vector<int32_t> capability = AVMetaData::localCapability;
289 AVMetaData::MetaMaskType mask;
290 for (const auto& key : capability) {
291 bool hasCapability = RemoteSessionCapabilitySet::GetInstance().HasCapability(session_->GetSessionId(),
292 sinkDevice,
293 SESSION_DATA_META, key);
294 if (hasCapability) {
295 mask.set(key);
296 }
297 }
298 return mask;
299 }
300 // LCOV_EXCL_STOP
301
302 // LCOV_EXCL_START
GetSinkPlaybackStateMaskType(const std::string & sinkDevice)303 AVPlaybackState::PlaybackStateMaskType RemoteSessionSourceImpl::GetSinkPlaybackStateMaskType(
304 const std::string& sinkDevice)
305 {
306 std::vector<int32_t> capability = AVPlaybackState::localCapability;
307 AVPlaybackState::PlaybackStateMaskType mask;
308 for (const auto& key : capability) {
309 bool hasCapability = RemoteSessionCapabilitySet::GetInstance().HasCapability(session_->GetSessionId(),
310 sinkDevice,
311 SESSION_DATA_PLAYBACK_STATE, key);
312 if (hasCapability) {
313 mask.set(key);
314 }
315 }
316 return mask;
317 }
318 // LCOV_EXCL_STOP
319 } // namespace OHOS::AVSession