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 CHECK_AND_RETURN_RET_LOG(category == SESSION_DATA_CONTROL_COMMAND, AVSESSION_ERROR, "category is error");
79 AVControlCommand command;
80 CHECK_AND_RETURN_RET_LOG(syncers_[deviceId]->GetControlCommand(command) == AVSESSION_SUCCESS,
81 AVSESSION_ERROR, "GetControlCommand failed");
82 session_->ExecuteControllerCommand(command);
83 return AVSESSION_SUCCESS;
84 });
85 CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, ret, "AddDataNotifier failed");
86 }
87 return AVSESSION_SUCCESS;
88 }
89
CancelCastAudio(const std::string & sinkDevice)90 int32_t RemoteSessionSourceImpl::CancelCastAudio(const std::string& sinkDevice)
91 {
92 SLOGI("start");
93 RemoteSessionCapabilitySet::GetInstance().RemoveRemoteCapability(session_->GetSessionId(), sinkDevice);
94 CHECK_AND_RETURN_RET_LOG(!syncers_.empty(), AVSESSION_SUCCESS, "syncer is empty");
95 auto iter = syncers_.begin();
96 while (iter != syncers_.end()) {
97 if (iter->first == sinkDevice) {
98 SLOGI("cancel sinkDevice %{public}s cast audio", sinkDevice.c_str());
99 iter->second->Destroy();
100 iter->second = nullptr;
101 iter = syncers_.erase(iter);
102 }
103 }
104 SLOGI("success");
105 return AVSESSION_SUCCESS;
106 }
107
SetAVMetaData(const AVMetaData & metaData)108 int32_t RemoteSessionSourceImpl::SetAVMetaData(const AVMetaData& metaData)
109 {
110 SLOGI("start");
111 CHECK_AND_RETURN_RET_LOG(!syncers_.empty() && session_ != nullptr, AVSESSION_ERROR, "syncers size is zero");
112 for (auto iter = syncers_.rbegin(); iter != syncers_.rend(); iter++) {
113 SLOGI("iter %{public}s", iter->first.c_str());
114 AVMetaData sinkMetaData;
115 auto mask = GetSinkMetaMaskType(iter->first);
116 if (!metaData.CopyToByMask(mask, sinkMetaData)) {
117 continue;
118 }
119 auto ret = iter->second->PutAVMetaData(sinkMetaData);
120 if (ret != AVSESSION_SUCCESS) {
121 HISYSEVENT_FAULT("REMOTE_CONTROL_FAILED",
122 "BUNDLE_NAME", session_->GetDescriptor().elementName_.GetBundleName(),
123 "SESSION_TYPE", session_->GetDescriptor().sessionType_,
124 "AUDIO_STATUS", HISYSEVENT_GET_AUDIO_STATUS(session_->GetUid()),
125 "ERROR_TYPE", "TIME_OUT",
126 "ERROR_INFO", "SetAVMetaData time out");
127 }
128 }
129 SLOGI("success");
130 return AVSESSION_SUCCESS;
131 }
132
SetAVPlaybackState(const AVPlaybackState & state)133 int32_t RemoteSessionSourceImpl::SetAVPlaybackState(const AVPlaybackState& state)
134 {
135 SLOGI("start");
136 CHECK_AND_RETURN_RET_LOG(!syncers_.empty() && session_ != nullptr, AVSESSION_ERROR, "syncers size is zero");
137 for (auto iter = syncers_.rbegin(); iter != syncers_.rend(); iter++) {
138 SLOGI("syncer %{public}s", iter->first.c_str());
139 AVPlaybackState sinkState;
140 auto mask = GetSinkPlaybackStateMaskType(iter->first);
141 if (!state.CopyToByMask(mask, sinkState)) {
142 continue;
143 }
144 auto ret = iter->second->PutAVPlaybackState(sinkState);
145 if (ret != AVSESSION_SUCCESS) {
146 HISYSEVENT_FAULT("REMOTE_CONTROL_FAILED",
147 "BUNDLE_NAME", session_->GetDescriptor().elementName_.GetBundleName(),
148 "SESSION_TYPE", session_->GetDescriptor().sessionType_,
149 "AUDIO_STATUS", HISYSEVENT_GET_AUDIO_STATUS(session_->GetUid()),
150 "ERROR_TYPE", "TIME_OUT",
151 "ERROR_INFO", "SetAVPlaybackState time out");
152 }
153 }
154 SLOGI("success");
155 return AVSESSION_SUCCESS;
156 }
157
GetSinkMetaMaskType(const std::string & sinkDevice)158 AVMetaData::MetaMaskType RemoteSessionSourceImpl::GetSinkMetaMaskType(const std::string& sinkDevice)
159 {
160 std::vector<int32_t> capability = AVMetaData::localCapability;
161 AVMetaData::MetaMaskType mask;
162 for (const auto& key : capability) {
163 bool hasCapability = RemoteSessionCapabilitySet::GetInstance().HasCapability(session_->GetSessionId(),
164 sinkDevice,
165 SESSION_DATA_META, key);
166 if (hasCapability) {
167 mask.set(key);
168 }
169 }
170 return mask;
171 }
172
GetSinkPlaybackStateMaskType(const std::string & sinkDevice)173 AVPlaybackState::PlaybackStateMaskType RemoteSessionSourceImpl::GetSinkPlaybackStateMaskType(
174 const std::string& sinkDevice)
175 {
176 std::vector<int32_t> capability = AVPlaybackState::localCapability;
177 AVPlaybackState::PlaybackStateMaskType mask;
178 for (const auto& key : capability) {
179 bool hasCapability = RemoteSessionCapabilitySet::GetInstance().HasCapability(session_->GetSessionId(),
180 sinkDevice,
181 SESSION_DATA_PLAYBACK_STATE, key);
182 if (hasCapability) {
183 mask.set(key);
184 }
185 }
186 return mask;
187 }
188 } // namespace OHOS::AVSession