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