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