• 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 
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