1 /*
2 * Copyright (c) 2023 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 #define LOG_TAG "UnifiedData"
16 #include "logger.h"
17 #include "unified_data.h"
18 #include "utd_client.h"
19
20 namespace OHOS {
21 namespace UDMF {
22 static const std::set<std::string> FILE_TYPES = {
23 "general.file", "general.image", "general.video", "general.audio", "general.folder", "general.file-uri" };
24 static constexpr const char *RECORDS_TANSFER_TAG = "records_to_entries_data_format";
UnifiedData()25 UnifiedData::UnifiedData()
26 {
27 properties_ = std::make_shared<UnifiedDataProperties>();
28 auto duration = std::chrono::system_clock::now().time_since_epoch();
29 properties_->timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
30 }
31
UnifiedData(std::shared_ptr<UnifiedDataProperties> properties)32 UnifiedData::UnifiedData(std::shared_ptr<UnifiedDataProperties> properties)
33 {
34 if (properties == nullptr) {
35 LOG_ERROR(UDMF_FRAMEWORK, "Invalid properties!");
36 return;
37 }
38 properties_ = properties;
39 auto duration = std::chrono::system_clock::now().time_since_epoch();
40 properties_->timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
41 }
42
GetSize()43 int64_t UnifiedData::GetSize()
44 {
45 int64_t totalSize = 0;
46 for (const auto &record : this->records_) {
47 totalSize += record->GetSize();
48 }
49 return totalSize;
50 }
51
GetGroupId() const52 std::string UnifiedData::GetGroupId() const
53 {
54 return this->runtime_->key.groupId;
55 }
56
GetRuntime() const57 std::shared_ptr<Runtime> UnifiedData::GetRuntime() const
58 {
59 return this->runtime_;
60 }
61
SetRuntime(Runtime & runtime)62 void UnifiedData::SetRuntime(Runtime &runtime)
63 {
64 this->runtime_ = std::make_shared<Runtime>(runtime);
65 this->SetSdkVersion(runtime.sdkVersion);
66 }
67
AddRecord(const std::shared_ptr<UnifiedRecord> & record)68 void UnifiedData::AddRecord(const std::shared_ptr<UnifiedRecord> &record)
69 {
70 if (record == nullptr) {
71 return;
72 }
73 record->SetRecordId(++recordId_);
74 this->records_.push_back(record);
75 }
76
AddRecords(const std::vector<std::shared_ptr<UnifiedRecord>> & records)77 void UnifiedData::AddRecords(const std::vector<std::shared_ptr<UnifiedRecord>> &records)
78 {
79 for (auto &record :records) {
80 if (record == nullptr) {
81 LOG_ERROR(UDMF_FRAMEWORK, "Invalid record, skip!");
82 continue;
83 }
84 record->SetRecordId(++recordId_);
85 this->records_.push_back(record);
86 }
87 }
88
GetRecordAt(std::size_t index) const89 std::shared_ptr<UnifiedRecord> UnifiedData::GetRecordAt(std::size_t index) const
90 {
91 if (records_.size() > index) {
92 return records_[index];
93 }
94 return nullptr;
95 }
96
SetRecords(std::vector<std::shared_ptr<UnifiedRecord>> records)97 void UnifiedData::SetRecords(std::vector<std::shared_ptr<UnifiedRecord>> records)
98 {
99 this->records_ = std::move(records);
100 }
101
GetRecords() const102 std::vector<std::shared_ptr<UnifiedRecord>> UnifiedData::GetRecords() const
103 {
104 return this->records_;
105 }
106
GetTypesLabels() const107 std::vector<std::string> UnifiedData::GetTypesLabels() const
108 {
109 std::vector<std::string> types;
110 for (const std::shared_ptr<UnifiedRecord> &record : records_) {
111 types.push_back(UtdUtils::GetUtdIdFromUtdEnum(record->GetType()));
112 }
113 return types;
114 }
115
HasType(const std::string & type) const116 bool UnifiedData::HasType(const std::string &type) const
117 {
118 for (const std::shared_ptr<UnifiedRecord> &record : records_) {
119 std::vector<std::string> recordTypes = record->GetTypes();
120 if (std::find(recordTypes.begin(), recordTypes.end(), type) != recordTypes.end()) {
121 return true;
122 }
123 }
124 return false;
125 }
126
HasHigherFileType(const std::string & type) const127 bool UnifiedData::HasHigherFileType(const std::string &type) const
128 {
129 std::set<std::string> types = GetTypIds();
130 if (types.find(type) != types.end()) {
131 return true;
132 }
133 if (!UnifiedDataUtils::IsFilterFileType(type)) {
134 return false;
135 }
136 for (auto it = types.begin(); it != types.end(); ++it) {
137 std::shared_ptr<TypeDescriptor> descriptor;
138 UtdClient::GetInstance().GetTypeDescriptor(*it, descriptor);
139 if (descriptor == nullptr) {
140 continue;
141 }
142 bool isFileType = false;
143 descriptor->BelongsTo(type, isFileType);
144 if (isFileType) {
145 return true;
146 }
147 }
148 return false;
149 }
150
GetEntriesTypes() const151 std::vector<std::string> UnifiedData::GetEntriesTypes() const
152 {
153 std::set<std::string> labels;
154 for (const auto &record : records_) {
155 auto types = record->GetUtdIds();
156 labels.insert(types.begin(), types.end());
157 }
158 return std::vector<std::string>(labels.begin(), labels.end());
159 }
160
HasTypeInEntries(const std::string & type) const161 bool UnifiedData::HasTypeInEntries(const std::string &type) const
162 {
163 for (const auto &record : records_) {
164 if (record == nullptr) {
165 LOG_ERROR(UDMF_FRAMEWORK, "Invalid record, skip!");
166 continue;
167 }
168 auto types = record->GetUtdIds();
169 if (types.find(type) != types.end()) {
170 return true;
171 }
172 }
173 return false;
174 }
175
IsEmpty() const176 bool UnifiedData::IsEmpty() const
177 {
178 return records_.empty();
179 }
180
IsValid()181 bool UnifiedData::IsValid()
182 {
183 if (this->IsEmpty()) {
184 LOG_ERROR(UDMF_FRAMEWORK, "Empty data without any record!");
185 return false;
186 }
187 if (this->GetSize() > MAX_DATA_SIZE) {
188 LOG_ERROR(UDMF_FRAMEWORK, "Exceeded data limit, UnifiedData size: %{public}" PRId64 " !", this->GetSize());
189 return false;
190 }
191 return true;
192 }
193
IsComplete()194 bool UnifiedData::IsComplete()
195 {
196 std::shared_ptr<Runtime> runtime = this->GetRuntime();
197 if (runtime == nullptr) {
198 return false;
199 }
200 if (static_cast<uint32_t>(this->GetRecords().size()) != runtime->recordTotalNum) {
201 LOG_ERROR(UDMF_FRAMEWORK,
202 "The records of unifiedData is incomplete, expected recordsNum is %{public}u, not %{public}zu.",
203 runtime->recordTotalNum, this->GetRecords().size());
204 return false;
205 }
206 return true;
207 }
208
HasFileType() const209 bool UnifiedData::HasFileType() const
210 {
211 auto types = GetTypIds();
212 std::set<std::string> intersection;
213 std::set_intersection(FILE_TYPES.begin(), FILE_TYPES.end(), types.begin(), types.end(),
214 std::inserter(intersection, intersection.begin()));
215 return !intersection.empty();
216 }
217
HasUriInfo() const218 bool UnifiedData::HasUriInfo() const
219 {
220 for (auto record : records_) {
221 if (!record->GetUris().empty()) {
222 return true;
223 }
224 }
225 return false;
226 }
227
ClearUriInfo() const228 void UnifiedData::ClearUriInfo() const
229 {
230 for (auto record : records_) {
231 record->ClearUris();
232 }
233 }
234
SetProperties(std::shared_ptr<UnifiedDataProperties> properties)235 void UnifiedData::SetProperties(std::shared_ptr<UnifiedDataProperties> properties)
236 {
237 if (!properties) {
238 LOG_ERROR(UDMF_FRAMEWORK, "properties is null!");
239 return;
240 }
241 if (properties_ == nullptr) {
242 LOG_ERROR(UDMF_FRAMEWORK, "properties_ is nullptr!");
243 return;
244 }
245 properties->timestamp = properties_->timestamp;
246 properties_ = properties;
247 }
248
GetProperties() const249 std::shared_ptr<UnifiedDataProperties> UnifiedData::GetProperties() const
250 {
251 return properties_;
252 }
253
SetDataId(uint32_t dataId)254 void UnifiedData::SetDataId(uint32_t dataId)
255 {
256 dataId_ = dataId;
257 }
258
GetDataId() const259 uint32_t UnifiedData::GetDataId() const
260 {
261 return dataId_;
262 }
263
SetChannelName(const std::string & name)264 void UnifiedData::SetChannelName(const std::string &name)
265 {
266 channelName_ = std::move(name);
267 }
268
GetTypIds() const269 std::set<std::string> UnifiedData::GetTypIds() const
270 {
271 std::set<std::string> types;
272 for (const auto &record : records_) {
273 std::set<std::string> recordTypes = record->GetUtdIdsWithAddFileType(true);
274 types.insert(recordTypes.begin(), recordTypes.end());
275 }
276 return types;
277 }
278
GetFileUris() const279 std::vector<std::string> UnifiedData::GetFileUris() const
280 {
281 std::vector<std::string> uris;
282 for (auto record : records_) {
283 std::string oriUri;
284 if (record == nullptr || !record->HasFileType(oriUri)) {
285 continue;
286 }
287 uris.push_back(oriUri);
288 }
289 return uris;
290 }
291
IsNeedTransferToEntries() const292 bool UnifiedData::IsNeedTransferToEntries() const
293 {
294 if (records_.size() <= 1) {
295 return false;
296 }
297 if (properties_ == nullptr) {
298 return false;
299 }
300 return properties_->tag == RECORDS_TANSFER_TAG;
301 }
302
ConvertRecordsToEntries()303 void UnifiedData::ConvertRecordsToEntries()
304 {
305 if (!IsNeedTransferToEntries()) {
306 return;
307 }
308 std::shared_ptr<UnifiedRecord> recordFirst = records_[0];
309 if (recordFirst == nullptr) {
310 LOG_ERROR(UDMF_FRAMEWORK, "First record is null");
311 return;
312 }
313 for (size_t i = 1; i < records_.size(); i++) {
314 auto record = records_[i];
315 if (record == nullptr) {
316 continue;
317 }
318 if (record->GetUtdId2() == recordFirst->GetUtdId2()) {
319 continue;
320 }
321 record->InitObject();
322 recordFirst->AddEntry(record->GetUtdId2(), record->GetValue());
323 }
324 records_.erase(records_.begin() + 1, records_.end());
325 LOG_INFO(UDMF_FRAMEWORK, "Convert records to entries finished");
326 }
327
GetSdkVersion() const328 std::string UnifiedData::GetSdkVersion() const
329 {
330 return sdkVersion_;
331 }
332
SetSdkVersion(const std::string & version)333 void UnifiedData::SetSdkVersion(const std::string &version)
334 {
335 sdkVersion_ = version;
336 }
337 } // namespace UDMF
338 } // namespace OHOS