1 /*
2 * Copyright (c) 2024 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 "Udmf"
16 #include "udmf.h"
17 #include "udmf_err_code.h"
18 #include "data_provider_impl.h"
19 #include "udmf_client.h"
20 #include "securec.h"
21 #include "udmf_capi_common.h"
22 #include "int_wrapper.h"
23 #include "string_wrapper.h"
24 #include "unified_meta.h"
25 #include "udmf_meta.h"
26 #include "logger.h"
27 #include "plain_text.h"
28 #include "link.h"
29 #include "html.h"
30 #include "system_defined_appitem.h"
31 #include "application_defined_record.h"
32 #include "system_defined_pixelmap.h"
33 #include "file.h"
34 #include "audio.h"
35 #include "folder.h"
36 #include "image.h"
37 #include "video.h"
38
39 using namespace OHOS::UDMF;
40
41 static constexpr uint64_t MAX_RECORDS_COUNT = 4 * 1024 * 1024;
42 static constexpr uint64_t MAX_KEY_STRING_LEN = 1 * 1024 * 1024;
43 static const std::map<std::string, UDType> FILE_TYPES = {
44 { UDMF_META_GENERAL_FILE, UDType::FILE },
45 { UDMF_META_AUDIO, UDType::AUDIO },
46 { UDMF_META_FOLDER, UDType::FOLDER },
47 { UDMF_META_IMAGE, UDType::IMAGE },
48 { UDMF_META_VIDEO, UDType::VIDEO }
49 };
50
DestroyStringArray(char ** & bufArray,unsigned int & count)51 static void DestroyStringArray(char**& bufArray, unsigned int& count)
52 {
53 if (bufArray == nullptr) {
54 return;
55 }
56 for (unsigned int i = 0; i < count; i++) {
57 if (bufArray[i] != nullptr) {
58 delete[] bufArray[i];
59 bufArray[i] = nullptr;
60 }
61 }
62 delete[] bufArray;
63 bufArray = nullptr;
64 count = 0;
65 }
66
DestroyUnifiedRecordArray(OH_UdmfRecord ** & records,unsigned int & count)67 static void DestroyUnifiedRecordArray(OH_UdmfRecord**& records, unsigned int& count)
68 {
69 if (records == nullptr) {
70 return;
71 }
72 for (unsigned int i = 0; i < count; i++) {
73 if (records[i] != nullptr) {
74 delete records[i];
75 records[i] = nullptr;
76 }
77 }
78 delete[] records;
79 records = nullptr;
80 count = 0;
81 }
82
StrVectorToTypesArray(const std::vector<std::string> & strVector)83 static char** StrVectorToTypesArray(const std::vector<std::string>& strVector)
84 {
85 unsigned int vectorSize = strVector.size();
86 if (vectorSize > MAX_RECORDS_COUNT) {
87 return nullptr;
88 }
89 char** typesArray = new (std::nothrow) char* [vectorSize] {nullptr};
90 for (unsigned int i = 0; i < vectorSize; ++i) {
91 unsigned int strLen = strVector[i].length() + 1;
92 if (strLen > MAX_KEY_STRING_LEN) {
93 LOG_INFO(UDMF_CAPI, "string exceeds maximum length, length is %{public}d", strLen);
94 DestroyStringArray(typesArray, vectorSize);
95 return nullptr;
96 }
97 typesArray[i] = new (std::nothrow) char[strLen];
98 if (typesArray[i] == nullptr ||
99 (strcpy_s(typesArray[i], strLen, strVector[i].c_str())) != EOK) {
100 LOG_ERROR(UDMF_CAPI, "string copy failed");
101 DestroyStringArray(typesArray, vectorSize);
102 return nullptr;
103 }
104 }
105 return typesArray;
106 }
107
CreateUnifiedDataRecordsArray(OH_UdmfData * unifiedData,std::vector<std::shared_ptr<UnifiedRecord>> & records)108 static OH_UdmfRecord** CreateUnifiedDataRecordsArray(OH_UdmfData* unifiedData,
109 std::vector<std::shared_ptr<UnifiedRecord>>& records)
110 {
111 unsigned int size = static_cast<unsigned int>(records.size());
112 if (unifiedData == nullptr || size == 0 || size > MAX_RECORDS_COUNT) {
113 return nullptr;
114 }
115 OH_UdmfRecord** result = new (std::nothrow) OH_UdmfRecord* [size] { nullptr };
116 if (result == nullptr) {
117 return nullptr;
118 }
119 for (unsigned int i = 0; i < size; i++) {
120 result[i] = new (std::nothrow) OH_UdmfRecord;
121 if (result[i] == nullptr) {
122 DestroyUnifiedRecordArray(result, size);
123 return nullptr;
124 }
125 result[i]->record_ = records[i];
126 }
127 unifiedData->records = result;
128 unifiedData->recordsCount = size;
129 return unifiedData->records;
130 }
131
IsUnifiedDataValid(OH_UdmfData * data)132 static bool IsUnifiedDataValid(OH_UdmfData* data)
133 {
134 return data != nullptr && data->unifiedData_ != nullptr &&
135 data->cid == NdkStructId::UDMF_UNIFIED_DATA_STRUCT_ID;
136 }
137
IsUnifiedRecordValid(OH_UdmfRecord * record)138 static bool IsUnifiedRecordValid(OH_UdmfRecord* record)
139 {
140 return record != nullptr && record->record_ != nullptr &&
141 record->cid == NdkStructId::UDMF_UNIFIED_RECORD_STRUCT_ID;
142 }
143
IsUnifiedPropertiesValid(OH_UdmfProperty * properties)144 static bool IsUnifiedPropertiesValid(OH_UdmfProperty* properties)
145 {
146 return properties != nullptr && properties->properties_ != nullptr &&
147 properties->cid == NdkStructId::UDMF_UNIFIED_DATA_PROPERTIES_ID;
148 }
149
AddFileUriTypeIfContains(std::vector<std::string> & types)150 static void AddFileUriTypeIfContains(std::vector<std::string>& types)
151 {
152 for (auto type : types) {
153 if (FILE_TYPES.find(type) != FILE_TYPES.end()) {
154 types.push_back(UDMF_META_GENERAL_FILE_URI);
155 break;
156 }
157 }
158 return;
159 }
160
OH_UdmfData_Create()161 OH_UdmfData* OH_UdmfData_Create()
162 {
163 OH_UdmfData* data = new (std::nothrow) OH_UdmfData;
164 if (data == nullptr) {
165 return nullptr;
166 }
167 data->unifiedData_ = std::make_shared<UnifiedData>();
168 return data;
169 }
170
OH_UdmfData_Destroy(OH_UdmfData * data)171 void OH_UdmfData_Destroy(OH_UdmfData* data)
172 {
173 if (data == nullptr) {
174 return;
175 }
176 DestroyStringArray(data->typesArray, data->typesCount);
177 DestroyUnifiedRecordArray(data->records, data->recordsCount);
178 delete data;
179 }
180
OH_UdmfData_AddRecord(OH_UdmfData * unifiedData,OH_UdmfRecord * record)181 int OH_UdmfData_AddRecord(OH_UdmfData* unifiedData, OH_UdmfRecord* record)
182 {
183 if (!IsUnifiedDataValid(unifiedData) || !IsUnifiedRecordValid(record)) {
184 return UDMF_E_INVALID_PARAM;
185 }
186 unifiedData->unifiedData_->AddRecord(record->record_);
187 return UDMF_E_OK;
188 }
189
OH_UdmfData_HasType(OH_UdmfData * unifiedData,const char * type)190 bool OH_UdmfData_HasType(OH_UdmfData* unifiedData, const char* type)
191 {
192 return IsUnifiedDataValid(unifiedData) && type != nullptr && unifiedData->unifiedData_->HasTypeInEntries(type);
193 }
194
OH_UdmfData_GetTypes(OH_UdmfData * unifiedData,unsigned int * count)195 char** OH_UdmfData_GetTypes(OH_UdmfData* unifiedData, unsigned int* count)
196 {
197 if (!IsUnifiedDataValid(unifiedData) || count == nullptr) {
198 return nullptr;
199 }
200 std::lock_guard<std::mutex> lock(unifiedData->mutex);
201 if (unifiedData->typesArray != nullptr) {
202 LOG_DEBUG(UDMF_CAPI, "return cache value");
203 *count = unifiedData->typesCount;
204 return unifiedData->typesArray;
205 }
206 std::vector<std::string> typeLabels = unifiedData->unifiedData_->GetEntriesTypes();
207 AddFileUriTypeIfContains(typeLabels);
208 unifiedData->typesArray = StrVectorToTypesArray(typeLabels);
209 unifiedData->typesArray == nullptr ? unifiedData->typesCount = 0 : unifiedData->typesCount = typeLabels.size();
210 *count = unifiedData->typesCount;
211 return unifiedData->typesArray;
212 }
213
OH_UdmfRecord_GetTypes(OH_UdmfRecord * record,unsigned int * count)214 char** OH_UdmfRecord_GetTypes(OH_UdmfRecord* record, unsigned int* count)
215 {
216 if (!IsUnifiedRecordValid(record) || count == nullptr) {
217 return nullptr;
218 }
219 std::lock_guard<std::mutex> lock(record->mutex);
220 if (record->typesArray != nullptr) {
221 LOG_DEBUG(UDMF_CAPI, "return cache value");
222 *count = record->typesCount;
223 return record->typesArray;
224 }
225 auto types = record->record_->GetUtdIds();
226 std::vector<std::string> typeLabels {types.begin(), types.end()};
227 AddFileUriTypeIfContains(typeLabels);
228 record->typesArray = StrVectorToTypesArray(typeLabels);
229 record->typesArray == nullptr ? record->typesCount = 0 : record->typesCount = typeLabels.size();
230 *count = record->typesCount;
231 return record->typesArray;
232 }
233
OH_UdmfData_GetRecords(OH_UdmfData * unifiedData,unsigned int * count)234 OH_UdmfRecord** OH_UdmfData_GetRecords(OH_UdmfData* unifiedData, unsigned int* count)
235 {
236 if (!IsUnifiedDataValid(unifiedData) || count == nullptr) {
237 return nullptr;
238 }
239 std::lock_guard<std::mutex> lock(unifiedData->mutex);
240 if (unifiedData->records != nullptr) {
241 LOG_DEBUG(UDMF_CAPI, "return cache value");
242 *count = unifiedData->recordsCount;
243 return unifiedData->records;
244 }
245 std::vector<std::shared_ptr<UnifiedRecord>> records = unifiedData->unifiedData_->GetRecords();
246 CreateUnifiedDataRecordsArray(unifiedData, records);
247 *count = unifiedData->recordsCount;
248 return unifiedData->records;
249 }
250
GetFirstPlainText(OH_UdmfRecord ** records,unsigned int recordCount,OH_UdsPlainText * plainText)251 static int GetFirstPlainText(OH_UdmfRecord **records, unsigned int recordCount, OH_UdsPlainText* plainText)
252 {
253 int ret = UDMF_ERR;
254 if (records == nullptr || recordCount == 0) {
255 return ret;
256 }
257 for (unsigned int i = 0; i < recordCount; i++) {
258 const char *type = OH_UdsPlainText_GetType(plainText);
259 if (type == nullptr || !records[i]->record_->HasType(type)) {
260 continue;
261 }
262 ret = OH_UdmfRecord_GetPlainText(records[i], plainText);
263 if (ret == UDMF_E_OK) {
264 return ret;
265 }
266 }
267 return ret;
268 }
269
GetFirstHtml(OH_UdmfRecord ** records,unsigned int recordCount,OH_UdsHtml * html)270 static int GetFirstHtml(OH_UdmfRecord **records, unsigned int recordCount, OH_UdsHtml* html)
271 {
272 int ret = UDMF_ERR;
273 if (records == nullptr || recordCount == 0) {
274 return ret;
275 }
276 for (unsigned int i = 0; i < recordCount; i++) {
277 const char *type = OH_UdsHtml_GetType(html);
278 if (type == nullptr || !records[i]->record_->HasType(type)) {
279 continue;
280 }
281 ret = OH_UdmfRecord_GetHtml(records[i], html);
282 if (ret == UDMF_E_OK) {
283 return ret;
284 }
285 }
286 return ret;
287 }
288
OH_UdmfData_GetPrimaryPlainText(OH_UdmfData * data,OH_UdsPlainText * plainText)289 int OH_UdmfData_GetPrimaryPlainText(OH_UdmfData* data, OH_UdsPlainText* plainText)
290 {
291 if (!IsUnifiedDataValid(data) || IsInvalidUdsObjectPtr(plainText, UDS_PLAIN_TEXT_STRUCT_ID)) {
292 return UDMF_E_INVALID_PARAM;
293 }
294 std::lock_guard<std::mutex> lock(data->mutex);
295 if (data->records == nullptr) {
296 LOG_DEBUG(UDMF_CAPI, "no cache value");
297 std::vector<std::shared_ptr<UnifiedRecord>> records = data->unifiedData_->GetRecords();
298 CreateUnifiedDataRecordsArray(data, records);
299 }
300
301 return GetFirstPlainText(data->records, data->recordsCount, plainText);
302 }
303
OH_UdmfData_GetPrimaryHtml(OH_UdmfData * data,OH_UdsHtml * html)304 int OH_UdmfData_GetPrimaryHtml(OH_UdmfData* data, OH_UdsHtml* html)
305 {
306 if (!IsUnifiedDataValid(data) || IsInvalidUdsObjectPtr(html, UDS_HTML_STRUCT_ID)) {
307 return UDMF_E_INVALID_PARAM;
308 }
309 std::lock_guard<std::mutex> lock(data->mutex);
310 if (data->records == nullptr) {
311 LOG_DEBUG(UDMF_CAPI, "no cache value");
312 std::vector<std::shared_ptr<UnifiedRecord>> records = data->unifiedData_->GetRecords();
313 CreateUnifiedDataRecordsArray(data, records);
314 }
315
316 return GetFirstHtml(data->records, data->recordsCount, html);
317 }
318
OH_UdmfData_GetRecordCount(OH_UdmfData * data)319 int OH_UdmfData_GetRecordCount(OH_UdmfData *data)
320 {
321 if (!IsUnifiedDataValid(data)) {
322 return 0;
323 }
324 std::lock_guard<std::mutex> lock(data->mutex);
325 if (data->records == nullptr) {
326 LOG_DEBUG(UDMF_CAPI, "no cache value");
327 std::vector<std::shared_ptr<UnifiedRecord>> records = data->unifiedData_->GetRecords();
328 CreateUnifiedDataRecordsArray(data, records);
329 }
330 return static_cast<int>(data->recordsCount);
331 }
332
OH_UdmfData_GetRecord(OH_UdmfData * data,unsigned int index)333 OH_UdmfRecord* OH_UdmfData_GetRecord(OH_UdmfData* data, unsigned int index)
334 {
335 if (!IsUnifiedDataValid(data) || index < 0) {
336 return nullptr;
337 }
338 std::lock_guard<std::mutex> lock(data->mutex);
339 if (data->records == nullptr) {
340 LOG_DEBUG(UDMF_CAPI, "no cache value");
341 std::vector<std::shared_ptr<UnifiedRecord>> records = data->unifiedData_->GetRecords();
342 CreateUnifiedDataRecordsArray(data, records);
343 }
344 if (index >= data->recordsCount || data->records == nullptr) {
345 return nullptr;
346 }
347 return data->records[index];
348 }
349
OH_UdmfData_IsLocal(OH_UdmfData * data)350 bool OH_UdmfData_IsLocal(OH_UdmfData* data)
351 {
352 if (!IsUnifiedDataValid(data) || data->unifiedData_->GetProperties() == nullptr) {
353 return true;
354 }
355 bool isRemote = data->unifiedData_->GetProperties()->isRemote;
356 return !isRemote;
357 }
358
OH_Udmf_GetUnifiedData(const char * key,Udmf_Intention intention,OH_UdmfData * data)359 int OH_Udmf_GetUnifiedData(const char* key, Udmf_Intention intention, OH_UdmfData* data)
360 {
361 if (!IsUnifiedDataValid(data) || key == nullptr) {
362 return UDMF_E_INVALID_PARAM;
363 }
364 Intention queryOptIntent;
365 switch (intention) {
366 case UDMF_INTENTION_DRAG:
367 queryOptIntent = Intention::UD_INTENTION_DRAG;
368 break;
369 default:
370 return UDMF_E_INVALID_PARAM;
371 }
372 QueryOption query = {.key = std::string(key), .intention = queryOptIntent};
373 if (UdmfClient::GetInstance().GetData(query, *(data->unifiedData_)) != E_OK) {
374 LOG_ERROR(UDMF_CAPI, "get data error");
375 return UDMF_ERR;
376 }
377 return UDMF_E_OK;
378 }
379
OH_Udmf_SetUnifiedData(Udmf_Intention intention,OH_UdmfData * unifiedData,char * key,unsigned int keyLen)380 int OH_Udmf_SetUnifiedData(Udmf_Intention intention, OH_UdmfData* unifiedData, char* key, unsigned int keyLen)
381 {
382 if (!IsUnifiedDataValid(unifiedData) || key == nullptr || keyLen < UDMF_KEY_BUFFER_LEN) {
383 return UDMF_E_INVALID_PARAM;
384 }
385 enum Intention customOptIntent;
386 switch (intention) {
387 case UDMF_INTENTION_DRAG:
388 customOptIntent = Intention::UD_INTENTION_DRAG;
389 break;
390 default:
391 return UDMF_E_INVALID_PARAM;
392 }
393 CustomOption option = {.intention = customOptIntent};
394 std::string keyStr;
395 if ((UdmfClient::GetInstance().SetData(option, *(unifiedData->unifiedData_), keyStr)) != E_OK) {
396 LOG_ERROR(UDMF_CAPI, "set data error");
397 return UDMF_ERR;
398 }
399 if (strcpy_s(key, keyLen, keyStr.c_str()) != EOK) {
400 LOG_INFO(UDMF_CAPI, "string copy failed");
401 return UDMF_ERR;
402 }
403 return UDMF_E_OK;
404 }
405
OH_UdmfRecord_Create()406 OH_UdmfRecord* OH_UdmfRecord_Create()
407 {
408 OH_UdmfRecord* record = new (std::nothrow) OH_UdmfRecord;
409 if (record == nullptr) {
410 return nullptr;
411 }
412 record->record_ = std::make_shared<UnifiedRecord>();
413 return record;
414 }
415
OH_UdmfRecord_Destroy(OH_UdmfRecord * record)416 void OH_UdmfRecord_Destroy(OH_UdmfRecord* record)
417 {
418 if (record == nullptr) {
419 return;
420 }
421 if (record->recordData != nullptr) {
422 delete[] record->recordData;
423 record->recordData = nullptr;
424 }
425 delete record;
426 }
427
OH_UdmfRecord_AddGeneralEntry(OH_UdmfRecord * record,const char * typeId,const unsigned char * entry,unsigned int count)428 int OH_UdmfRecord_AddGeneralEntry(OH_UdmfRecord* record, const char* typeId,
429 const unsigned char* entry, unsigned int count)
430 {
431 if (!IsUnifiedRecordValid(record) || typeId == nullptr || entry == nullptr || count == 0 ||
432 count > MAX_GENERAL_ENTRY_SIZE || strlen(typeId) > MAX_KEY_STRING_LEN) {
433 return UDMF_E_INVALID_PARAM;
434 }
435 std::vector<uint8_t> recordValue(entry, entry + count);
436 if (record->record_->GetType() == UD_BUTT) {
437 record->record_ = std::make_shared<ApplicationDefinedRecord>(APPLICATION_DEFINED_RECORD, recordValue);
438 record->record_->SetUtdId(typeId);
439 } else {
440 record->record_->AddEntry(typeId, std::move(recordValue));
441 }
442 record->recordDataLen = count;
443 return UDMF_E_OK;
444 }
445
GetValueFromUdsArrayBuffer(OH_UdmfRecord * record,const char * typeId,ValueType value)446 static int GetValueFromUdsArrayBuffer(OH_UdmfRecord *record, const char *typeId, ValueType value)
447 {
448 if (!std::holds_alternative<std::shared_ptr<Object>>(value)) {
449 LOG_ERROR(UDMF_CAPI, "valueType is not object sptr!");
450 return UDMF_ERR;
451 }
452 OH_UdsArrayBuffer *buffer = OH_UdsArrayBuffer_Create();
453 buffer->obj = std::get<std::shared_ptr<Object>>(value);
454
455 int ret = OH_UdsArrayBuffer_GetData(buffer, &record->recordData, &record->recordDataLen);
456 if (ret != UDMF_E_OK) {
457 LOG_ERROR(UDMF_CAPI, "get data from buffer failed. ret: %{public}d", ret);
458 OH_UdsArrayBuffer_Destroy(buffer);
459 return ret;
460 }
461 record->lastType = const_cast<char*>(typeId);
462 return UDMF_E_OK;
463 }
464
GetValueFromUint8Array(OH_UdmfRecord * record,const char * typeId,ValueType value)465 static int GetValueFromUint8Array(OH_UdmfRecord *record, const char *typeId, ValueType value)
466 {
467 auto recordValue = std::get_if<std::vector<uint8_t>>(&value);
468 if (recordValue == nullptr) {
469 return UDMF_ERR;
470 }
471 record->recordDataLen = recordValue->size();
472 if (record->recordDataLen > MAX_GENERAL_ENTRY_SIZE) {
473 LOG_INFO(UDMF_CAPI, "data size exceeds maximum size");
474 return UDMF_ERR;
475 }
476 record->recordData = new (std::nothrow) unsigned char[record->recordDataLen];
477 if (record->recordData == nullptr) {
478 return UDMF_ERR;
479 }
480 auto err = memcpy_s(record->recordData, record->recordDataLen, recordValue->data(), record->recordDataLen);
481 if (err != EOK) {
482 LOG_ERROR(UDMF_CAPI, "memcpy error! type:%{public}s", typeId);
483 return UDMF_ERR;
484 }
485 record->lastType = const_cast<char*>(typeId);
486 return UDMF_E_OK;
487 }
488
OH_UdmfRecord_GetGeneralEntry(OH_UdmfRecord * record,const char * typeId,unsigned char ** entry,unsigned int * count)489 int OH_UdmfRecord_GetGeneralEntry(OH_UdmfRecord* record, const char* typeId, unsigned char** entry, unsigned int* count)
490 {
491 if (!IsUnifiedRecordValid(record) || typeId == nullptr || entry == nullptr || count == nullptr) {
492 return UDMF_E_INVALID_PARAM;
493 }
494
495 std::lock_guard<std::mutex> lock(record->mutex);
496 if (!record->record_->HasType(typeId)) {
497 LOG_ERROR(UDMF_CAPI, "no type:%{public}s", typeId);
498 return UDMF_E_INVALID_PARAM;
499 }
500 if (record->lastType == typeId && record->recordData != nullptr) {
501 LOG_DEBUG(UDMF_CAPI, "return cache value");
502 *entry = record->recordData;
503 *count = record->recordDataLen;
504 return UDMF_E_OK;
505 }
506
507 auto value = record->record_->GetEntry(typeId);
508
509 int result = UDMF_ERR;
510 if (std::holds_alternative<std::shared_ptr<Object>>(value)) {
511 result = GetValueFromUdsArrayBuffer(record, typeId, value);
512 } else if (std::holds_alternative<std::vector<uint8_t>>(value)) {
513 result = GetValueFromUint8Array(record, typeId, value);
514 } else {
515 LOG_ERROR(UDMF_CAPI, "Not contains right data type.");
516 }
517 if (result != UDMF_E_OK) {
518 LOG_ERROR(UDMF_CAPI, "Get value from valueType failed. typeId: %{public}s, result: %{public}d", typeId, result);
519 return result;
520 }
521 *count = record->recordDataLen;
522 *entry = record->recordData;
523 return UDMF_E_OK;
524 }
525
526 template<typename T>
AddUds(OH_UdmfRecord * record,UdsObject * udsObject,UDType type)527 void AddUds(OH_UdmfRecord* record, UdsObject* udsObject, UDType type)
528 {
529 if (record->record_->GetType() == UD_BUTT) {
530 record->record_ = std::make_shared<T>(type, udsObject->obj);
531 } else {
532 record->record_->AddEntry(UtdUtils::GetUtdIdFromUtdEnum(type), udsObject->obj);
533 }
534 }
535
OH_UdmfRecord_AddPlainText(OH_UdmfRecord * record,OH_UdsPlainText * plainText)536 int OH_UdmfRecord_AddPlainText(OH_UdmfRecord* record, OH_UdsPlainText* plainText)
537 {
538 if (!IsUnifiedRecordValid(record) || IsInvalidUdsObjectPtr(plainText, UDS_PLAIN_TEXT_STRUCT_ID)) {
539 return UDMF_E_INVALID_PARAM;
540 }
541 AddUds<PlainText>(record, plainText, PLAIN_TEXT);
542 return UDMF_E_OK;
543 }
544
OH_UdmfRecord_AddHyperlink(OH_UdmfRecord * record,OH_UdsHyperlink * hyperlink)545 int OH_UdmfRecord_AddHyperlink(OH_UdmfRecord* record, OH_UdsHyperlink* hyperlink)
546 {
547 if (!IsUnifiedRecordValid(record) || IsInvalidUdsObjectPtr(hyperlink, UDS_HYPERLINK_STRUCT_ID)) {
548 return UDMF_E_INVALID_PARAM;
549 }
550 AddUds<Link>(record, hyperlink, HYPERLINK);
551 return UDMF_E_OK;
552 }
553
OH_UdmfRecord_AddHtml(OH_UdmfRecord * record,OH_UdsHtml * html)554 int OH_UdmfRecord_AddHtml(OH_UdmfRecord* record, OH_UdsHtml* html)
555 {
556 if (!IsUnifiedRecordValid(record) || IsInvalidUdsObjectPtr(html, UDS_HTML_STRUCT_ID)) {
557 return UDMF_E_INVALID_PARAM;
558 }
559 AddUds<Html>(record, html, HTML);
560 return UDMF_E_OK;
561 }
562
OH_UdmfRecord_AddAppItem(OH_UdmfRecord * record,OH_UdsAppItem * appItem)563 int OH_UdmfRecord_AddAppItem(OH_UdmfRecord* record, OH_UdsAppItem* appItem)
564 {
565 if (!IsUnifiedRecordValid(record) || IsInvalidUdsObjectPtr(appItem, UDS_APP_ITEM_STRUCT_ID)) {
566 return UDMF_E_INVALID_PARAM;
567 }
568 AddUds<SystemDefinedAppItem>(record, appItem, SYSTEM_DEFINED_APP_ITEM);
569 return UDMF_E_OK;
570 }
571
OH_UdmfRecord_AddFileUri(OH_UdmfRecord * record,OH_UdsFileUri * fileUri)572 int OH_UdmfRecord_AddFileUri(OH_UdmfRecord* record, OH_UdsFileUri* fileUri)
573 {
574 if (!IsUnifiedRecordValid(record) || IsInvalidUdsObjectPtr(fileUri, UDS_FILE_URI_STRUCT_ID)) {
575 return UDMF_E_INVALID_PARAM;
576 }
577 std::string* fileType = std::get_if<std::string>(&(fileUri->obj->value_[FILE_TYPE]));
578 if (fileType == nullptr) {
579 return UDMF_ERR;
580 }
581 int32_t utdId = UtdUtils::GetUtdEnumFromUtdId(*fileType);
582 switch (utdId) {
583 case UDType::FILE:
584 AddUds<File>(record, fileUri, UDType::FILE);
585 break;
586 case UDType::AUDIO:
587 AddUds<Audio>(record, fileUri, UDType::AUDIO);
588 break;
589 case UDType::FOLDER:
590 AddUds<Folder>(record, fileUri, UDType::FOLDER);
591 break;
592 case UDType::IMAGE:
593 AddUds<Image>(record, fileUri, UDType::IMAGE);
594 break;
595 case UDType::VIDEO:
596 AddUds<Video>(record, fileUri, UDType::VIDEO);
597 break;
598 default:
599 AddUds<UnifiedRecord>(record, fileUri, UDType::FILE_URI);
600 }
601 return UDMF_E_OK;
602 }
603
OH_UdmfRecord_AddPixelMap(OH_UdmfRecord * record,OH_UdsPixelMap * pixelMap)604 int OH_UdmfRecord_AddPixelMap(OH_UdmfRecord* record, OH_UdsPixelMap* pixelMap)
605 {
606 if (!IsUnifiedRecordValid(record) || IsInvalidUdsObjectPtr(pixelMap, UDS_PIXEL_MAP_STRUCT_ID)) {
607 return UDMF_E_INVALID_PARAM;
608 }
609 AddUds<SystemDefinedPixelMap>(record, pixelMap, UDType::SYSTEM_DEFINED_PIXEL_MAP);
610 return UDMF_E_OK;
611 }
612
GetUds(OH_UdmfRecord * record,UdsObject * udsObject,UDType type)613 int GetUds(OH_UdmfRecord* record, UdsObject* udsObject, UDType type)
614 {
615 record->record_->InitObject();
616 auto value = record->record_->GetEntry(UtdUtils::GetUtdIdFromUtdEnum(type));
617 if (!std::holds_alternative<std::shared_ptr<Object>>(value)) {
618 return UDMF_ERR;
619 }
620 udsObject->obj = std::get<std::shared_ptr<Object>>(value);
621 return UDMF_E_OK;
622 }
623
OH_UdmfRecord_AddArrayBuffer(OH_UdmfRecord * record,const char * type,OH_UdsArrayBuffer * buffer)624 int OH_UdmfRecord_AddArrayBuffer(OH_UdmfRecord* record, const char* type, OH_UdsArrayBuffer* buffer)
625 {
626 if (!IsUnifiedRecordValid(record) || type == nullptr || strlen(type) > MAX_KEY_STRING_LEN ||
627 IsInvalidUdsObjectPtr(buffer, UDS_ARRAY_BUFFER_STRUCT_ID)) {
628 return UDMF_E_INVALID_PARAM;
629 }
630 unsigned char *entry;
631 unsigned int size;
632 int ret = OH_UdsArrayBuffer_GetData(buffer, &entry, &size);
633 if (ret != UDMF_E_OK) {
634 return UDMF_E_INVALID_PARAM;
635 }
636 buffer->obj->value_[UNIFORM_DATA_TYPE] = type;
637 return OH_UdmfRecord_AddGeneralEntry(record, type, entry, size);
638 }
639
OH_UdmfRecord_GetPlainText(OH_UdmfRecord * record,OH_UdsPlainText * plainText)640 int OH_UdmfRecord_GetPlainText(OH_UdmfRecord* record, OH_UdsPlainText* plainText)
641 {
642 if (!IsUnifiedRecordValid(record) || IsInvalidUdsObjectPtr(plainText, UDS_PLAIN_TEXT_STRUCT_ID)) {
643 return UDMF_E_INVALID_PARAM;
644 }
645 return GetUds(record, plainText, PLAIN_TEXT);
646 }
647
OH_UdmfRecord_GetHyperlink(OH_UdmfRecord * record,OH_UdsHyperlink * hyperlink)648 int OH_UdmfRecord_GetHyperlink(OH_UdmfRecord* record, OH_UdsHyperlink* hyperlink)
649 {
650 if (!IsUnifiedRecordValid(record) || IsInvalidUdsObjectPtr(hyperlink, UDS_HYPERLINK_STRUCT_ID)) {
651 return UDMF_E_INVALID_PARAM;
652 }
653 return GetUds(record, hyperlink, HYPERLINK);
654 }
655
OH_UdmfRecord_GetHtml(OH_UdmfRecord * record,OH_UdsHtml * html)656 int OH_UdmfRecord_GetHtml(OH_UdmfRecord* record, OH_UdsHtml* html)
657 {
658 if (!IsUnifiedRecordValid(record) || IsInvalidUdsObjectPtr(html, UDS_HTML_STRUCT_ID)) {
659 return UDMF_E_INVALID_PARAM;
660 }
661 return GetUds(record, html, HTML);
662 }
663
OH_UdmfRecord_GetAppItem(OH_UdmfRecord * record,OH_UdsAppItem * appItem)664 int OH_UdmfRecord_GetAppItem(OH_UdmfRecord* record, OH_UdsAppItem* appItem)
665 {
666 if (!IsUnifiedRecordValid(record) || IsInvalidUdsObjectPtr(appItem, UDS_APP_ITEM_STRUCT_ID)) {
667 return UDMF_E_INVALID_PARAM;
668 }
669 return GetUds(record, appItem, SYSTEM_DEFINED_APP_ITEM);
670 }
671
OH_UdmfRecord_GetFileUri(OH_UdmfRecord * record,OH_UdsFileUri * fileUri)672 int OH_UdmfRecord_GetFileUri(OH_UdmfRecord* record, OH_UdsFileUri* fileUri)
673 {
674 if (!IsUnifiedRecordValid(record) || IsInvalidUdsObjectPtr(fileUri, UDS_FILE_URI_STRUCT_ID)) {
675 return UDMF_E_INVALID_PARAM;
676 }
677 if (GetUds(record, fileUri, UDType::FILE_URI) == UDMF_E_OK) {
678 return UDMF_E_OK;
679 }
680 for (auto fileType : FILE_TYPES) {
681 int ret = GetUds(record, fileUri, fileType.second);
682 if (ret == UDMF_E_OK) {
683 fileUri->obj->value_[UNIFORM_DATA_TYPE] = UDMF_META_GENERAL_FILE_URI;
684 fileUri->obj->value_[FILE_TYPE] = UtdUtils::GetUtdIdFromUtdEnum(fileType.second);
685 return UDMF_E_OK;
686 }
687 }
688 LOG_ERROR(UDMF_CAPI, "could't find file uri");
689 return UDMF_E_INVALID_PARAM;
690 }
691
OH_UdmfRecord_GetPixelMap(OH_UdmfRecord * record,OH_UdsPixelMap * pixelMap)692 int OH_UdmfRecord_GetPixelMap(OH_UdmfRecord* record, OH_UdsPixelMap* pixelMap)
693 {
694 if (!IsUnifiedRecordValid(record) || IsInvalidUdsObjectPtr(pixelMap, UDS_PIXEL_MAP_STRUCT_ID)) {
695 return UDMF_E_INVALID_PARAM;
696 }
697 return GetUds(record, pixelMap, UDType::SYSTEM_DEFINED_PIXEL_MAP);
698 }
699
OH_UdmfRecord_GetArrayBuffer(OH_UdmfRecord * record,const char * type,OH_UdsArrayBuffer * buffer)700 int OH_UdmfRecord_GetArrayBuffer(OH_UdmfRecord* record, const char* type, OH_UdsArrayBuffer* buffer)
701 {
702 unsigned int size = 0;
703 unsigned char *entry;
704 int ret = OH_UdmfRecord_GetGeneralEntry(record, type, &entry, &size);
705 if (ret != UDMF_E_OK) {
706 LOG_ERROR(UDMF_CAPI, "OH_UdmfRecord_GetGeneralEntry ret: %{public}d.", ret);
707 return ret;
708 }
709 return OH_UdsArrayBuffer_SetData(buffer, entry, size);
710 }
711
OH_UdmfProperty_Create(OH_UdmfData * data)712 OH_UdmfProperty* OH_UdmfProperty_Create(OH_UdmfData* data)
713 {
714 if (!IsUnifiedDataValid(data)) {
715 return nullptr;
716 }
717 OH_UdmfProperty* properties = new (std::nothrow) OH_UdmfProperty;
718 if (properties == nullptr) {
719 return nullptr;
720 }
721 properties->properties_ = data->unifiedData_->GetProperties();
722 return properties;
723 }
724
OH_UdmfProperty_Destroy(OH_UdmfProperty * properties)725 void OH_UdmfProperty_Destroy(OH_UdmfProperty* properties)
726 {
727 if (properties != nullptr) {
728 delete properties;
729 }
730 }
731
OH_UdmfProperty_GetTag(OH_UdmfProperty * properties)732 const char* OH_UdmfProperty_GetTag(OH_UdmfProperty* properties)
733 {
734 if (!IsUnifiedPropertiesValid(properties)) {
735 return nullptr;
736 }
737 return properties->properties_->tag.c_str();
738 }
739
OH_UdmfProperty_GetTimestamp(OH_UdmfProperty * properties)740 int64_t OH_UdmfProperty_GetTimestamp(OH_UdmfProperty* properties)
741 {
742 if (!IsUnifiedPropertiesValid(properties)) {
743 return -1;
744 }
745 return properties->properties_->timestamp;
746 }
747
OH_UdmfProperty_GetShareOption(OH_UdmfProperty * properties)748 Udmf_ShareOption OH_UdmfProperty_GetShareOption(OH_UdmfProperty* properties)
749 {
750 if (!IsUnifiedPropertiesValid(properties)) {
751 return Udmf_ShareOption::SHARE_OPTIONS_INVALID;
752 }
753 switch (properties->properties_->shareOptions) {
754 case ShareOptions::IN_APP:
755 return Udmf_ShareOption::SHARE_OPTIONS_IN_APP;
756 case ShareOptions::CROSS_APP:
757 case ShareOptions::CROSS_DEVICE:
758 return Udmf_ShareOption::SHARE_OPTIONS_CROSS_APP;
759 default:
760 return Udmf_ShareOption::SHARE_OPTIONS_INVALID;
761 }
762 }
763
OH_UdmfProperty_GetExtrasIntParam(OH_UdmfProperty * properties,const char * key,const int defaultValue)764 int OH_UdmfProperty_GetExtrasIntParam(OH_UdmfProperty* properties, const char* key, const int defaultValue)
765 {
766 return (IsUnifiedPropertiesValid(properties) && key != nullptr) ?
767 properties->properties_->extras.GetIntParam(key, defaultValue) : defaultValue;
768 }
769
OH_UdmfProperty_GetExtrasStringParam(OH_UdmfProperty * properties,const char * key)770 const char* OH_UdmfProperty_GetExtrasStringParam(OH_UdmfProperty* properties, const char* key)
771 {
772 if (!IsUnifiedPropertiesValid(properties) || key == nullptr) {
773 return nullptr;
774 }
775 properties->extraStr = properties->properties_->extras.GetStringParam(key);
776 return properties->extraStr.c_str();
777 }
778
OH_UdmfProperty_SetTag(OH_UdmfProperty * properties,const char * tag)779 int OH_UdmfProperty_SetTag(OH_UdmfProperty* properties, const char* tag)
780 {
781 if (!IsUnifiedPropertiesValid(properties) || tag == nullptr) {
782 return UDMF_E_INVALID_PARAM;
783 }
784 properties->properties_->tag = tag;
785 return UDMF_E_OK;
786 }
787
OH_UdmfProperty_SetShareOption(OH_UdmfProperty * properties,Udmf_ShareOption option)788 int OH_UdmfProperty_SetShareOption(OH_UdmfProperty* properties, Udmf_ShareOption option)
789 {
790 if (!IsUnifiedPropertiesValid(properties)) {
791 return UDMF_E_INVALID_PARAM;
792 }
793 std::lock_guard<std::mutex> lock(properties->mutex);
794 switch (option) {
795 case Udmf_ShareOption::SHARE_OPTIONS_IN_APP:
796 properties->properties_->shareOptions = ShareOptions::IN_APP;
797 break;
798 case Udmf_ShareOption::SHARE_OPTIONS_CROSS_APP:
799 properties->properties_->shareOptions = ShareOptions::CROSS_APP;
800 break;
801 default:
802 return UDMF_E_INVALID_PARAM;
803 }
804 return UDMF_E_OK;
805 }
806
OH_UdmfProperty_SetExtrasIntParam(OH_UdmfProperty * properties,const char * key,int param)807 int OH_UdmfProperty_SetExtrasIntParam(OH_UdmfProperty* properties, const char* key, int param)
808 {
809 if (!IsUnifiedPropertiesValid(properties) || key == nullptr) {
810 return UDMF_E_INVALID_PARAM;
811 }
812 std::lock_guard<std::mutex> lock(properties->mutex);
813 properties->properties_->extras.SetParam(key, OHOS::AAFwk::Integer::Box(param));
814 return UDMF_E_OK;
815 }
816
OH_UdmfProperty_SetExtrasStringParam(OH_UdmfProperty * properties,const char * key,const char * param)817 int OH_UdmfProperty_SetExtrasStringParam(OH_UdmfProperty* properties, const char* key, const char* param)
818 {
819 if (!IsUnifiedPropertiesValid(properties) || key == nullptr || param == nullptr) {
820 return UDMF_E_INVALID_PARAM;
821 }
822 std::lock_guard<std::mutex> lock(properties->mutex);
823 properties->properties_->extras.SetParam(key, OHOS::AAFwk::String::Box(param));
824 return UDMF_E_OK;
825 }
826
OH_UdmfRecordProvider_Create()827 OH_UdmfRecordProvider* OH_UdmfRecordProvider_Create()
828 {
829 OH_UdmfRecordProvider* provider = new (std::nothrow) OH_UdmfRecordProvider();
830 if (provider == nullptr) {
831 LOG_ERROR(UDMF_CAPI, "allocate OH_UdmfRecordProvider memory fail");
832 }
833 return provider;
834 }
835
OH_UdmfRecordProvider_Destroy(OH_UdmfRecordProvider * provider)836 int OH_UdmfRecordProvider_Destroy(OH_UdmfRecordProvider* provider)
837 {
838 if (provider == nullptr) {
839 return UDMF_E_INVALID_PARAM;
840 }
841 if (provider->context != nullptr && provider->finalize != nullptr) {
842 (provider->finalize)(provider->context);
843 LOG_INFO(UDMF_CAPI, "free context finished");
844 }
845 delete provider;
846 return UDMF_E_OK;
847 }
848
OH_UdmfRecordProvider_SetData(OH_UdmfRecordProvider * provider,void * context,const OH_UdmfRecordProvider_GetData callback,const UdmfData_Finalize finalize)849 int OH_UdmfRecordProvider_SetData(OH_UdmfRecordProvider* provider, void* context,
850 const OH_UdmfRecordProvider_GetData callback, const UdmfData_Finalize finalize)
851 {
852 if (provider == nullptr || callback == nullptr) {
853 return UDMF_E_INVALID_PARAM;
854 }
855 provider->callback = callback;
856 if (context != nullptr && finalize == nullptr) {
857 LOG_ERROR(UDMF_CAPI, "finalize function is null when context not null");
858 return UDMF_E_INVALID_PARAM;
859 }
860 provider->context = context;
861 provider->finalize = finalize;
862 return UDMF_E_OK;
863 }
864
OH_UdmfRecord_SetProvider(OH_UdmfRecord * record,const char * const * types,unsigned int count,OH_UdmfRecordProvider * provider)865 int OH_UdmfRecord_SetProvider(OH_UdmfRecord* record, const char* const* types, unsigned int count,
866 OH_UdmfRecordProvider* provider)
867 {
868 if (!IsUnifiedRecordValid(record) || types == nullptr || count == 0 || provider == nullptr) {
869 return UDMF_E_INVALID_PARAM;
870 }
871 std::shared_ptr<DataProviderImpl> providerBox = std::make_shared<DataProviderImpl>();
872 providerBox->SetInnerProvider(provider);
873 std::vector<std::string> udTypes;
874 std::set<std::string> udTypeSet;
875 for (unsigned int i = 0; i < count; ++i) {
876 if (types[i] == nullptr) {
877 LOG_ERROR(UDMF_CAPI, "The type with index %{public}d is empty", i);
878 continue;
879 }
880 if (udTypeSet.count(types[i]) == 0) {
881 udTypeSet.emplace(types[i]);
882 udTypes.emplace_back(types[i]);
883 }
884 }
885 record->record_->SetEntryGetter(udTypes, providerBox);
886 return UDMF_E_OK;
887 }
888