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