• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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