• 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 <iomanip>
17 #include <sstream>
18 #include "avsession_trace.h"
19 #include "hash_calculator.h"
20 #include "parcel.h"
21 #include "remote_session_syncer_impl.h"
22 
23 namespace OHOS::AVSession {
RemoteSessionSyncerImpl(const std::string & sourceSessionId,const std::string & sourceDevice,const std::string & sinkDevice)24 RemoteSessionSyncerImpl::RemoteSessionSyncerImpl(const std::string& sourceSessionId, const std::string& sourceDevice,
25                                                  const std::string& sinkDevice)
26     : sourceSessionId_(sourceSessionId), sourceDevice_(sourceDevice), sinkDevice_(sinkDevice)
27 {
28     SLOGE("construct");
29 }
30 
OnChanged(const std::string & sessionId,const std::vector<std::string> & keys)31 void RemoteSessionSyncerImpl::OnChanged(const std::string &sessionId, const std::vector<std::string>& keys)
32 {
33     SLOGI("sessionId is %{public}s key is %{public}s", sessionId.c_str(), keys[0].c_str());
34     CHECK_AND_RETURN_LOG(objectDataNotifier_ != nullptr, "objectDataNotifier_ is nullptr");
35     for (const auto& key : keys) {
36         CHECK_AND_RETURN_LOG(categoryMap.count(key) > 0, "key is not exist");
37         objectDataNotifier_(categoryMap.at(key), sinkDevice_);
38     }
39 }
40 
OnChanged(const std::string & name,const std::string & networkId,const std::string & onlineStatus)41 void RemoteSessionSyncerImpl::OnChanged(const std::string &name, const std::string &networkId,
42                                         const std::string &onlineStatus)
43 {
44     SLOGI("%{public}.6s %{public}s", networkId.c_str(), onlineStatus.c_str());
45     CHECK_AND_RETURN_LOG(onlineStatus == "offline", "state is online");
46     CHECK_AND_RETURN_LOG(objectDisconnectNotifier_ != nullptr, "objectDataNotifier_ is nullptr");
47     objectDisconnectNotifier_(networkId);
48 }
49 
Init()50 int32_t RemoteSessionSyncerImpl::Init()
51 {
52     SLOGE("start");
53     objectStore_ = DistributedObjectStore::GetInstance("av_session");
54     CHECK_AND_RETURN_RET_LOG(objectStore_ != nullptr, AVSESSION_ERROR, "objectStore_ is nullptr");
55 
56     std::string object = sourceSessionId_ + sourceDevice_ + sinkDevice_;
57     HashCalculator hashCalculator;
58     CHECK_AND_RETURN_RET_LOG(hashCalculator.Init() == AVSESSION_SUCCESS, AVSESSION_ERROR, "hash init failed");
59     CHECK_AND_RETURN_RET_LOG(hashCalculator.Update(std::vector<uint8_t>(object.begin(), object.end())) ==
60                              AVSESSION_SUCCESS, AVSESSION_ERROR, "hash update failed");
61     std::vector<uint8_t> hash;
62     CHECK_AND_RETURN_RET_LOG(hashCalculator.GetResult(hash) == AVSESSION_SUCCESS, AVSESSION_ERROR,
63                              "hash get result failed");
64     std::stringstream stream;
65     int32_t width = 2;
66     for (const auto& byte : hash) {
67         stream << std::uppercase << std::hex << std::setfill('0') << std::setw(width) << static_cast<int>(byte);
68     }
69     objectName_ = stream.str();
70     SLOGI("sourceSessionId is %{public}s, sourceDevice is %{public}s, sinkDevice is %{public}s, object is %{public}s",
71           sourceSessionId_.c_str(), sourceDevice_.c_str(), sinkDevice_.c_str(), objectName_.c_str());
72     object_ = objectStore_->CreateObject(objectName_);
73     CHECK_AND_RETURN_RET_LOG(object_ != nullptr, AVSESSION_ERROR, "object_ is nullptr");
74     SLOGE("init object success");
75     return AVSESSION_SUCCESS;
76 }
77 
PutData(const std::string & key,std::vector<uint8_t> & data)78 int32_t RemoteSessionSyncerImpl::PutData(const std::string &key, std::vector<uint8_t> &data)
79 {
80     CHECK_AND_RETURN_RET_LOG(object_ != nullptr, AVSESSION_ERROR, "object is nullptr");
81     return object_->PutComplex(key, data) == ObjectStore::SUCCESS ? AVSESSION_SUCCESS : AVSESSION_ERROR;
82 }
83 
GetData(const std::string & key,std::vector<uint8_t> & data)84 int32_t RemoteSessionSyncerImpl::GetData(const std::string &key, std::vector<uint8_t> &data)
85 {
86     CHECK_AND_RETURN_RET_LOG(object_ != nullptr, AVSESSION_ERROR, "object is nullptr");
87     return object_->GetComplex(key, data) == ObjectStore::SUCCESS ? AVSESSION_SUCCESS : AVSESSION_ERROR;
88 }
89 
PutAVMetaData(const AVMetaData & metaData)90 int32_t RemoteSessionSyncerImpl::PutAVMetaData(const AVMetaData& metaData)
91 {
92     AVSESSION_TRACE_SYNC_START("RemoteSessionSyncerImpl::PutAVMetaData");
93     Parcel data;
94     CHECK_AND_RETURN_RET_LOG(metaData.Marshalling(data), AVSESSION_ERROR, "metaData Marshalling error");
95     uint8_t *parcelData = reinterpret_cast<uint8_t*>(data.GetData());
96     std::vector<uint8_t> dataVector(data.GetDataSize());
97     std::copy(parcelData, parcelData + data.GetDataSize(), dataVector.begin());
98 
99     CHECK_AND_RETURN_RET_LOG(PutData(METADATA_KEY, dataVector) == AVSESSION_SUCCESS, AVSESSION_ERROR, "put data error");
100     return AVSESSION_SUCCESS;
101 }
102 
GetAVMetaData(AVMetaData & metaData)103 int32_t RemoteSessionSyncerImpl::GetAVMetaData(AVMetaData& metaData)
104 {
105     std::vector<uint8_t> dataVector;
106     CHECK_AND_RETURN_RET_LOG(GetData(METADATA_KEY, dataVector) == AVSESSION_SUCCESS, AVSESSION_ERROR, "get data error");
107     CHECK_AND_RETURN_RET_LOG(dataVector.size() <= RECEIVE_DATA_SIZE_MAX, AVSESSION_ERROR, "get data size over range");
108     DefaultAllocator allocator;
109     uint8_t *allocateData = reinterpret_cast<uint8_t*>(allocator.Alloc(dataVector.size()));
110     CHECK_AND_RETURN_RET_LOG(allocateData != nullptr, AVSESSION_ERROR, "alloc data fail");
111     std::copy(dataVector.begin(), dataVector.end(), allocateData);
112     Parcel parcelData;
113     CHECK_AND_RETURN_RET_LOG(parcelData.ParseFrom(reinterpret_cast<uintptr_t>(allocateData), dataVector.size()),
114                              AVSESSION_ERROR, "parse parcel error");
115     AVMetaData *data = AVMetaData::Unmarshalling(parcelData);
116     CHECK_AND_RETURN_RET_LOG(data != nullptr, AVSESSION_ERROR, "Unmarshalling error");
117     metaData = *data;
118     delete data;
119     return AVSESSION_SUCCESS;
120 }
121 
PutAVPlaybackState(const AVPlaybackState & state)122 int32_t RemoteSessionSyncerImpl::PutAVPlaybackState(const AVPlaybackState& state)
123 {
124     AVSESSION_TRACE_SYNC_START("RemoteSessionSyncerImpl::PutAVPlaybackState");
125     Parcel data;
126     CHECK_AND_RETURN_RET_LOG(state.Marshalling(data), AVSESSION_ERROR, "state Marshalling error");
127     uint8_t *parcelData = reinterpret_cast<uint8_t*>(data.GetData());
128     std::vector<uint8_t> dataVector(data.GetDataSize());
129     std::copy(parcelData, parcelData + data.GetDataSize(), dataVector.begin());
130 
131     CHECK_AND_RETURN_RET_LOG(PutData(PLAYBACK_STATE_KEY, dataVector) == AVSESSION_SUCCESS, AVSESSION_ERROR,
132                              "put data error");
133     return AVSESSION_SUCCESS;
134 }
135 
GetAVPlaybackState(AVPlaybackState & state)136 int32_t RemoteSessionSyncerImpl::GetAVPlaybackState(AVPlaybackState& state)
137 {
138     std::vector<uint8_t> dataVector;
139     CHECK_AND_RETURN_RET_LOG(GetData(PLAYBACK_STATE_KEY, dataVector) == AVSESSION_SUCCESS, AVSESSION_ERROR,
140                              "get data error");
141     CHECK_AND_RETURN_RET_LOG(dataVector.size() <= RECEIVE_DATA_SIZE_MAX, AVSESSION_ERROR, "get data size over range");
142     DefaultAllocator allocator;
143     uint8_t *allocateData = reinterpret_cast<uint8_t*>(allocator.Alloc(dataVector.size()));
144     CHECK_AND_RETURN_RET_LOG(allocateData != nullptr, AVSESSION_ERROR, "alloc data fail");
145     std::copy(dataVector.begin(), dataVector.end(), allocateData);
146     Parcel parcelData;
147     CHECK_AND_RETURN_RET_LOG(parcelData.ParseFrom(reinterpret_cast<uintptr_t>(allocateData), dataVector.size()),
148                              AVSESSION_ERROR, "parse parcel error");
149     AVPlaybackState *data = AVPlaybackState::Unmarshalling(parcelData);
150     CHECK_AND_RETURN_RET_LOG(data != nullptr, AVSESSION_ERROR, "Unmarshalling error");
151     state = *data;
152     delete data;
153     return AVSESSION_SUCCESS;
154 }
155 
PutControlCommand(const AVControlCommand & command)156 int32_t RemoteSessionSyncerImpl::PutControlCommand(const AVControlCommand& command)
157 {
158     AVSESSION_TRACE_SYNC_START("RemoteSessionSyncerImpl::PutControlCommand");
159     Parcel data;
160     CHECK_AND_RETURN_RET_LOG(command.Marshalling(data), AVSESSION_ERROR, "command Marshalling error");
161     uint8_t *parcelData = reinterpret_cast<uint8_t*>(data.GetData());
162     std::vector<uint8_t> dataVector(data.GetDataSize());
163     std::copy(parcelData, parcelData + data.GetDataSize(), dataVector.begin());
164 
165     CHECK_AND_RETURN_RET_LOG(PutData(CONTROL_COMMAND_KEY, dataVector) == AVSESSION_SUCCESS, AVSESSION_ERROR,
166                              "put data error");
167     return AVSESSION_SUCCESS;
168 }
169 
GetControlCommand(AVControlCommand & command)170 int32_t RemoteSessionSyncerImpl::GetControlCommand(AVControlCommand& command)
171 {
172     std::vector<uint8_t> dataVector;
173     CHECK_AND_RETURN_RET_LOG(GetData(CONTROL_COMMAND_KEY, dataVector) == AVSESSION_SUCCESS, AVSESSION_ERROR,
174                              "get data error");
175     CHECK_AND_RETURN_RET_LOG(dataVector.size() <= RECEIVE_DATA_SIZE_MAX, AVSESSION_ERROR, "get data size over range");
176     DefaultAllocator allocator;
177     uint8_t *allocateData = reinterpret_cast<uint8_t*>(allocator.Alloc(dataVector.size()));
178     CHECK_AND_RETURN_RET_LOG(allocateData != nullptr, AVSESSION_ERROR, "alloc data fail");
179     std::copy(dataVector.begin(), dataVector.end(), allocateData);
180     Parcel parcelData;
181     CHECK_AND_RETURN_RET_LOG(parcelData.ParseFrom(reinterpret_cast<uintptr_t>(allocateData), dataVector.size()),
182                              AVSESSION_ERROR, "parse parcel error");
183     AVControlCommand *data = AVControlCommand::Unmarshalling(parcelData);
184     CHECK_AND_RETURN_RET_LOG(data != nullptr, AVSESSION_ERROR, "Unmarshalling error");
185     command = *data;
186     delete data;
187     return AVSESSION_SUCCESS;
188 }
189 
RegisterDataNotifier(const ObjectDataNotifier & notifier)190 int32_t RemoteSessionSyncerImpl::RegisterDataNotifier(const ObjectDataNotifier& notifier)
191 {
192     CHECK_AND_RETURN_RET_LOG(objectStore_ != nullptr && object_ != nullptr, AVSESSION_ERROR,
193                              "objectStore_ or object_ is nullptr");
194     objectDataNotifier_ = notifier;
195     objectStore_->Watch(object_, shared_from_this());
196     return AVSESSION_SUCCESS;
197 }
198 
RegisterDisconnectNotifier(const ObjectDisconnectNotifier & notifier)199 int32_t RemoteSessionSyncerImpl::RegisterDisconnectNotifier(const ObjectDisconnectNotifier& notifier)
200 {
201     CHECK_AND_RETURN_RET_LOG(objectStore_ != nullptr, AVSESSION_ERROR, "objectStore_ is nullptr");
202     objectDisconnectNotifier_ = notifier;
203     objectStore_->SetStatusNotifier(shared_from_this());
204     return AVSESSION_SUCCESS;
205 }
206 
Destroy()207 void RemoteSessionSyncerImpl::Destroy()
208 {
209     auto ret = objectStore_->UnWatch(object_);
210     CHECK_AND_RETURN_LOG(ret == ObjectStore::SUCCESS, "UnWatch error");
211     ret = objectStore_->DeleteObject(objectName_);
212     CHECK_AND_RETURN_LOG(ret == ObjectStore::SUCCESS, "DeleteObject error");
213     SLOGI("Destroy");
214 }
215 
~RemoteSessionSyncerImpl()216 RemoteSessionSyncerImpl::~RemoteSessionSyncerImpl()
217 {
218     SLOGI("RemoteSessionSyncerImpl");
219 }
220 } // namespace OHOS::AVSession