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