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 #include "pasteboard_utils.h"
16 
17 #include <unordered_set>
18 
19 #include "application_defined_record.h"
20 #include "audio.h"
21 #include "folder.h"
22 #include "html.h"
23 #include "image.h"
24 #include "link.h"
25 #include "paste_data_record.h"
26 #include "pixel_map.h"
27 #include "plain_text.h"
28 #include "system_defined_appitem.h"
29 #include "system_defined_form.h"
30 #include "unified_record.h"
31 #include "video.h"
32 #include "system_defined_pixelmap.h"
33 
34 namespace OHOS {
35 namespace MiscServices {
36 using UnifiedRecord = UDMF::UnifiedRecord;
37 using UnifiedData = UDMF::UnifiedData;
38 using UnifiedDataProperties = UDMF::UnifiedDataProperties;
39 using UDType = UDMF::UDType;
40 using ShareOptions = UDMF::ShareOptions;
41 
InitDecodeMap()42 void PasteboardUtils::InitDecodeMap()
43 {
44     convert2URecordMap_ = {
45         { UDMF::TEXT, PasteRecord2Text },
46         { UDMF::PLAIN_TEXT, PasteRecord2PlaintText },
47         { UDMF::OPENHARMONY_WANT, PasteRecord2Want },
48         { UDMF::HTML, PasteRecord2Html },
49         { UDMF::HYPERLINK, PasteRecord2Link },
50         { UDMF::FILE, PasteRecord2File },
51         { UDMF::IMAGE, PasteRecord2Image },
52         { UDMF::VIDEO, PasteRecord2Video },
53         { UDMF::AUDIO, PasteRecord2Audio },
54         { UDMF::FOLDER, PasteRecord2Folder },
55         { UDMF::SYSTEM_DEFINED_PIXEL_MAP, PasteRecord2PixelMap },
56         { UDMF::SYSTEM_DEFINED_RECORD, PasteRecord2SystemDefined },
57         { UDMF::SYSTEM_DEFINED_FORM, PasteRecord2Form },
58         { UDMF::SYSTEM_DEFINED_APP_ITEM, PasteRecord2AppItem },
59     };
60 
61     convert2PRecordMap_ = {
62         { UDMF::TEXT, Text2PasteRecord },
63         { UDMF::PLAIN_TEXT, PlainText2PasteRecord },
64         { UDMF::OPENHARMONY_WANT, Want2PasteRecord },
65         { UDMF::HTML, Html2PasteRecord },
66         { UDMF::HYPERLINK, Link2PasteRecord },
67         { UDMF::FILE, File2PasteRecord },
68         { UDMF::IMAGE, Image2PasteRecord },
69         { UDMF::VIDEO, Video2PasteRecord },
70         { UDMF::AUDIO, Audio2PasteRecord },
71         { UDMF::FOLDER, Folder2PasteRecord },
72         { UDMF::SYSTEM_DEFINED_PIXEL_MAP, PixelMap2PasteRecord },
73         { UDMF::SYSTEM_DEFINED_RECORD, SystemDefined2PasteRecord },
74         { UDMF::SYSTEM_DEFINED_FORM, Form2PasteRecord },
75         { UDMF::SYSTEM_DEFINED_APP_ITEM, AppItem2PasteRecord },
76         { UDMF::APPLICATION_DEFINED_RECORD, AppDefined2PasteRecord },
77     };
78 }
79 
Convert(const UnifiedData & unifiedData)80 std::shared_ptr<PasteData> PasteboardUtils::Convert(const UnifiedData& unifiedData)
81 {
82     auto unifiedRecords = unifiedData.GetRecords();
83     auto pasteData = std::make_shared<PasteData>(Convert(unifiedRecords));
84     auto unifiedDataProperties = unifiedData.GetProperties();
85     auto properties = Convert(*unifiedDataProperties);
86     auto recordTypes = unifiedData.GetTypesLabels();
87     properties.mimeTypes = Convert(recordTypes);
88     pasteData->SetProperty(properties);
89     return pasteData;
90 }
91 
Convert(const PasteData & pasteData)92 std::shared_ptr<UnifiedData> PasteboardUtils::Convert(const PasteData& pasteData)
93 {
94     auto unifiedData = std::make_shared<UnifiedData>();
95     for (std::size_t i = 0; i < pasteData.GetRecordCount(); ++i) {
96         auto pasteboardRecord = pasteData.GetRecordAt(i);
97         if (pasteboardRecord == nullptr) {
98             continue;
99         }
100         auto type = Convert(pasteboardRecord->GetUDType(), pasteboardRecord->GetMimeType());
101         auto it = convert2URecordMap_.find(type);
102         if (it == convert2URecordMap_.end()) {
103             PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "not find type, go to customData");
104             unifiedData->AddRecords(Custom2AppDefined(pasteboardRecord));
105         } else {
106             unifiedData->AddRecord(it->second(pasteboardRecord));
107         }
108     }
109     auto pastedProp = pasteData.GetProperty();
110     auto unifiedProp = Convert(pastedProp);
111     unifiedData->SetProperties(unifiedProp);
112     return unifiedData;
113 }
114 
Convert(const std::vector<std::shared_ptr<UnifiedRecord>> & records)115 std::vector<std::shared_ptr<PasteDataRecord>> PasteboardUtils::Convert(
116     const std::vector<std::shared_ptr<UnifiedRecord>>& records)
117 {
118     std::vector<std::shared_ptr<PasteDataRecord>> pasteboardRecords;
119     for (auto const& record : records) {
120         if (record == nullptr) {
121             continue;
122         }
123         auto type = record->GetType();
124         auto it = convert2PRecordMap_.find(type);
125         if (it == convert2PRecordMap_.end()) {
126             PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "not find type, convert to AppDefinedRecord");
127             pasteboardRecords.push_back(AppDefined2PasteRecord(record));
128         } else {
129             PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "find type, convert to pasteRecord, type:%{public}d", type);
130             pasteboardRecords.push_back(it->second(record));
131         }
132     }
133     return pasteboardRecords;
134 }
135 
UdmfOptions2PbOption(ShareOptions udmfOptions)136 ShareOption PasteboardUtils::UdmfOptions2PbOption(ShareOptions udmfOptions)
137 {
138     ShareOption pbOption = CrossDevice;
139     switch (udmfOptions) {
140         case UDMF::IN_APP:
141             pbOption = InApp;
142             break;
143         case UDMF::CROSS_APP:
144             pbOption = LocalDevice;
145             break;
146         case UDMF::CROSS_DEVICE:
147             pbOption = CrossDevice;
148             break;
149         default:
150             break;
151     }
152     return pbOption;
153 }
154 
PbOption2UdmfOptions(ShareOption pbOption)155 ShareOptions PasteboardUtils::PbOption2UdmfOptions(ShareOption pbOption)
156 {
157     ShareOptions udmfOptions = UDMF::CROSS_DEVICE;
158     switch (pbOption) {
159         case InApp:
160             udmfOptions = UDMF::IN_APP;
161             break;
162         case LocalDevice:
163             udmfOptions = UDMF::CROSS_APP;
164             break;
165         case CrossDevice:
166             udmfOptions = UDMF::CROSS_DEVICE;
167             break;
168         default:
169             break;
170     }
171     return udmfOptions;
172 }
173 
Convert(const UnifiedDataProperties & properties)174 PasteDataProperty PasteboardUtils::Convert(const UnifiedDataProperties& properties)
175 {
176     PasteDataProperty pasteDataProperty;
177     pasteDataProperty.shareOption = UdmfOptions2PbOption(properties.shareOptions);
178     pasteDataProperty.additions = properties.extras;
179     pasteDataProperty.timestamp = properties.timestamp;
180     pasteDataProperty.tag = properties.tag;
181     pasteDataProperty.isRemote = properties.isRemote;
182     return PasteDataProperty(pasteDataProperty);
183 }
184 
Convert(const PasteDataProperty & properties)185 std::shared_ptr<UnifiedDataProperties> PasteboardUtils::Convert(const PasteDataProperty& properties)
186 {
187     auto unifiedDataProperties = std::make_shared<UnifiedDataProperties>();
188     unifiedDataProperties->shareOptions = PbOption2UdmfOptions(properties.shareOption);
189     unifiedDataProperties->extras = properties.additions;
190     unifiedDataProperties->timestamp = properties.timestamp;
191     unifiedDataProperties->tag = properties.tag;
192     unifiedDataProperties->isRemote = properties.isRemote;
193     return unifiedDataProperties;
194 }
195 
Convert(const std::vector<std::string> & utdIds)196 std::vector<std::string> PasteboardUtils::Convert(const std::vector<std::string>& utdIds)
197 {
198     std::vector<std::string> types;
199     for (const auto& utdId : utdIds) {
200         types.push_back(CommonUtils::Convert2MimeType(utdId));
201     }
202     return types;
203 }
204 
Convert(UDType uDType)205 std::string PasteboardUtils::Convert(UDType uDType)
206 {
207     switch (uDType) {
208         case UDType::PLAIN_TEXT:
209             return MIMETYPE_TEXT_PLAIN;
210         case UDType::HTML:
211             return MIMETYPE_TEXT_HTML;
212         case UDType::FILE:
213         case UDType::IMAGE:
214         case UDType::VIDEO:
215         case UDType::AUDIO:
216         case UDType::FOLDER:
217         case UDType::FILE_URI:
218             return MIMETYPE_TEXT_URI;
219         case UDType::SYSTEM_DEFINED_PIXEL_MAP:
220             return MIMETYPE_PIXELMAP;
221         case UDType::OPENHARMONY_WANT:
222             return MIMETYPE_TEXT_WANT;
223         default:
224             return UDMF::UtdUtils::GetUtdIdFromUtdEnum(uDType);
225     }
226 }
227 
Convert(int32_t uDType,const std::string & mimeType)228 UDType PasteboardUtils::Convert(int32_t uDType, const std::string& mimeType)
229 {
230     if (uDType != UDMF::UD_BUTT) {
231         return static_cast<UDType>(uDType);
232     }
233     if (mimeType == MIMETYPE_TEXT_URI) {
234         return UDMF::FILE;
235     }
236     if (mimeType == MIMETYPE_TEXT_PLAIN) {
237         return UDMF::PLAIN_TEXT;
238     }
239     if (mimeType == MIMETYPE_TEXT_HTML) {
240         return UDMF::HTML;
241     }
242     if (mimeType == MIMETYPE_TEXT_WANT) {
243         return UDMF::OPENHARMONY_WANT;
244     }
245     if (mimeType == MIMETYPE_PIXELMAP) {
246         return UDMF::SYSTEM_DEFINED_PIXEL_MAP;
247     }
248     auto type = UDMF::UtdUtils::GetUtdEnumFromUtdId(mimeType);
249     if (type != UDMF::UD_BUTT) {
250         return static_cast<UDType>(type);
251     }
252     return UDMF::UD_BUTT;
253 }
254 
PlainText2PasteRecord(const std::shared_ptr<UnifiedRecord> record)255 std::shared_ptr<PasteDataRecord> PasteboardUtils::PlainText2PasteRecord(const std::shared_ptr<UnifiedRecord> record)
256 {
257     auto plainText = static_cast<UDMF::PlainText*>(record.get());
258     if (plainText == nullptr) {
259         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "get PLAIN_TEXT record failed.");
260         return nullptr;
261     }
262     auto pbRecord = std::make_shared<PasteDataRecord>();
263     auto utdId = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDType::PLAIN_TEXT);
264     auto value = record->GetOriginValue();
265     if (std::holds_alternative<std::shared_ptr<Object>>(value)) {
266         pbRecord->AddEntry(utdId, std::make_shared<PasteDataEntry>(utdId, value));
267         return pbRecord;
268     }
269     auto object = std::make_shared<Object>();
270     object->value_[UDMF::UNIFORM_DATA_TYPE] = utdId;
271     object->value_[UDMF::CONTENT] = plainText->GetContent();
272     object->value_[UDMF::ABSTRACT] = plainText->GetAbstract();
273     pbRecord->AddEntry(utdId, std::make_shared<PasteDataEntry>(utdId, object));
274     pbRecord->SetDetails(plainText->GetDetails());
275     return pbRecord;
276 }
277 
PasteRecord2PlaintText(const std::shared_ptr<PasteDataRecord> record)278 std::shared_ptr<UnifiedRecord> PasteboardUtils::PasteRecord2PlaintText(const std::shared_ptr<PasteDataRecord> record)
279 {
280     if (record == nullptr) {
281         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "to plain, record is null.");
282         return nullptr;
283     }
284     auto udmfValue = record->GetUDMFValue();
285     if (!udmfValue) {
286         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "udmfvalue is null");
287         return nullptr;
288     }
289     auto plainText = std::make_shared<UDMF::PlainText>(UDMF::PLAIN_TEXT, *udmfValue);
290     if (record->GetDetails()) {
291         plainText->SetDetails(*record->GetDetails());
292     }
293     return plainText;
294 }
295 
Want2PasteRecord(const std::shared_ptr<UnifiedRecord> record)296 std::shared_ptr<PasteDataRecord> PasteboardUtils::Want2PasteRecord(const std::shared_ptr<UnifiedRecord> record)
297 {
298     auto want = static_cast<UDMF::UnifiedRecord*>(record.get());
299     if (want == nullptr) {
300         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "get want record failed.");
301         return nullptr;
302     }
303     auto recordValue = want->GetValue();
304     auto wantValue = std::get_if<std::shared_ptr<OHOS::AAFwk::Want>>(&recordValue);
305     if (wantValue == nullptr) {
306         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "get want from unified record failed.");
307         return nullptr;
308     }
309     auto wantRecord = PasteDataRecord::NewWantRecord(*(wantValue));
310     wantRecord->SetUDType(UDMF::OPENHARMONY_WANT);
311     return wantRecord;
312 }
313 
PasteRecord2Want(const std::shared_ptr<PasteDataRecord> record)314 std::shared_ptr<UnifiedRecord> PasteboardUtils::PasteRecord2Want(const std::shared_ptr<PasteDataRecord> record)
315 {
316     if (record == nullptr) {
317         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "to want, record is null.");
318         return nullptr;
319     }
320     auto wantRecord = record->GetWant();
321     if (wantRecord == nullptr) {
322         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "get want from paste record failed.");
323         return nullptr;
324     }
325     return std::make_shared<UDMF::UnifiedRecord>(UDMF::OPENHARMONY_WANT, wantRecord);
326 }
327 
Html2PasteRecord(const std::shared_ptr<UnifiedRecord> record)328 std::shared_ptr<PasteDataRecord> PasteboardUtils::Html2PasteRecord(const std::shared_ptr<UnifiedRecord> record)
329 {
330     auto html = static_cast<UDMF::Html*>(record.get());
331     if (html == nullptr) {
332         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "get HTML record failed.");
333         return nullptr;
334     }
335     auto pbRecord = std::make_shared<PasteDataRecord>();
336     auto utdId = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDType::HTML);
337     auto value = record->GetOriginValue();
338     if (std::holds_alternative<std::shared_ptr<Object>>(value)) {
339         pbRecord->AddEntry(utdId, std::make_shared<PasteDataEntry>(utdId, value));
340         return pbRecord;
341     }
342     auto object = std::make_shared<Object>();
343     object->value_[UDMF::UNIFORM_DATA_TYPE] = utdId;
344     object->value_[UDMF::HTML_CONTENT] = html->GetHtmlContent();
345     object->value_[UDMF::PLAIN_CONTENT] = html->GetPlainContent();
346     pbRecord->AddEntry(utdId, std::make_shared<PasteDataEntry>(utdId, object));
347     pbRecord->SetDetails(html->GetDetails());
348     return pbRecord;
349 }
350 
PasteRecord2Html(const std::shared_ptr<PasteDataRecord> record)351 std::shared_ptr<UnifiedRecord> PasteboardUtils::PasteRecord2Html(const std::shared_ptr<PasteDataRecord> record)
352 {
353     if (record == nullptr) {
354         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "to html, record is null.");
355         return nullptr;
356     }
357     auto udmfValue = record->GetUDMFValue();
358     if (!udmfValue) {
359         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "udmfvalue is null");
360         return nullptr;
361     }
362     auto html = std::make_shared<UDMF::Html>(UDMF::HTML, *udmfValue);
363     if (record->GetDetails()) {
364         html->SetDetails(*record->GetDetails());
365     }
366     return html;
367 }
368 
Link2PasteRecord(const std::shared_ptr<UnifiedRecord> record)369 std::shared_ptr<PasteDataRecord> PasteboardUtils::Link2PasteRecord(const std::shared_ptr<UnifiedRecord> record)
370 {
371     auto link = static_cast<UDMF::Link*>(record.get());
372     if (link == nullptr) {
373         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "get Link record failed.");
374         return nullptr;
375     }
376     auto pbRecord = std::make_shared<PasteDataRecord>();
377     auto utdId = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDType::HYPERLINK);
378     auto value = record->GetOriginValue();
379     if (std::holds_alternative<std::shared_ptr<Object>>(value)) {
380         pbRecord->AddEntry(utdId, std::make_shared<PasteDataEntry>(utdId, value));
381         return pbRecord;
382     }
383     auto object = std::make_shared<Object>();
384     object->value_[UDMF::UNIFORM_DATA_TYPE] = utdId;
385     object->value_[UDMF::URL] = link->GetUrl();
386     object->value_[UDMF::DESCRIPTION] = link->GetDescription();
387     pbRecord->AddEntry(utdId, std::make_shared<PasteDataEntry>(utdId, object));
388     pbRecord->SetDetails(link->GetDetails());
389     return pbRecord;
390 }
391 
PasteRecord2Link(const std::shared_ptr<PasteDataRecord> record)392 std::shared_ptr<UnifiedRecord> PasteboardUtils::PasteRecord2Link(const std::shared_ptr<PasteDataRecord> record)
393 {
394     if (record == nullptr) {
395         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "to link, record is null.");
396         return nullptr;
397     }
398     auto udmfValue = record->GetUDMFValue();
399     if (!udmfValue) {
400         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "udmfvalue is null");
401         return nullptr;
402     }
403     auto link = std::make_shared<UDMF::Link>(UDMF::HYPERLINK, *udmfValue);
404     if (record->GetDetails()) {
405         link->SetDetails(*record->GetDetails());
406     }
407     return link;
408 }
409 
File2PasteRecord(const std::shared_ptr<UnifiedRecord> record)410 std::shared_ptr<PasteDataRecord> PasteboardUtils::File2PasteRecord(const std::shared_ptr<UnifiedRecord> record)
411 {
412     auto file = static_cast<UDMF::File*>(record.get());
413     if (file == nullptr) {
414         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "get file record failed.");
415         return nullptr;
416     }
417     auto uriRecord = PasteDataRecord::NewUriRecord(OHOS::Uri(file->GetUri()));
418     uriRecord->SetDetails(file->GetDetails());
419     uriRecord->SetUDType(UDMF::FILE);
420     return uriRecord;
421 }
422 
PasteRecord2File(const std::shared_ptr<PasteDataRecord> record)423 std::shared_ptr<UnifiedRecord> PasteboardUtils::PasteRecord2File(const std::shared_ptr<PasteDataRecord> record)
424 {
425     if (record == nullptr) {
426         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "to file, record is null.");
427         return nullptr;
428     }
429     auto uri = record->GetUri();
430     if (uri == nullptr) {
431         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "get uri from paste record to file failed.");
432         return nullptr;
433     }
434     auto unifiedRecord = std::make_shared<UDMF::File>(uri->ToString());
435     auto details = record->GetDetails();
436     if (details != nullptr) {
437         unifiedRecord->SetDetails(*details);
438     }
439     return unifiedRecord;
440 }
441 
Image2PasteRecord(const std::shared_ptr<UnifiedRecord> record)442 std::shared_ptr<PasteDataRecord> PasteboardUtils::Image2PasteRecord(const std::shared_ptr<UnifiedRecord> record)
443 {
444     auto image = static_cast<UDMF::Image*>(record.get());
445     if (image == nullptr) {
446         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "get image record failed.");
447         return nullptr;
448     }
449     auto uriRecord = PasteDataRecord::NewUriRecord(OHOS::Uri(image->GetUri()));
450     uriRecord->SetDetails(image->GetDetails());
451     uriRecord->SetUDType(UDMF::IMAGE);
452     return uriRecord;
453 }
454 
PasteRecord2Image(const std::shared_ptr<PasteDataRecord> record)455 std::shared_ptr<UnifiedRecord> PasteboardUtils::PasteRecord2Image(const std::shared_ptr<PasteDataRecord> record)
456 {
457     if (record == nullptr) {
458         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "to image, record is null.");
459         return nullptr;
460     }
461     auto uri = record->GetUri();
462     if (uri == nullptr) {
463         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "get uri from paste record to image failed.");
464         return nullptr;
465     }
466     auto unifiedRecord = std::make_shared<UDMF::Image>(uri->ToString());
467     auto details = record->GetDetails();
468     if (details != nullptr) {
469         unifiedRecord->SetDetails(*details);
470     }
471     return unifiedRecord;
472 }
473 
Video2PasteRecord(const std::shared_ptr<UnifiedRecord> record)474 std::shared_ptr<PasteDataRecord> PasteboardUtils::Video2PasteRecord(const std::shared_ptr<UnifiedRecord> record)
475 {
476     auto video = static_cast<UDMF::Video*>(record.get());
477     if (video == nullptr) {
478         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "get video record failed.");
479         return nullptr;
480     }
481     auto uriRecord = PasteDataRecord::NewUriRecord(OHOS::Uri(video->GetUri()));
482     uriRecord->SetDetails(video->GetDetails());
483     uriRecord->SetUDType(UDMF::VIDEO);
484     return uriRecord;
485 }
486 
PasteRecord2Video(const std::shared_ptr<PasteDataRecord> record)487 std::shared_ptr<UnifiedRecord> PasteboardUtils::PasteRecord2Video(const std::shared_ptr<PasteDataRecord> record)
488 {
489     if (record == nullptr) {
490         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "to video, record is null.");
491         return nullptr;
492     }
493     auto uri = record->GetUri();
494     if (uri == nullptr) {
495         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "get uri from paste record to video failed.");
496         return nullptr;
497     }
498     auto unifiedRecord = std::make_shared<UDMF::Video>(uri->ToString());
499     auto details = record->GetDetails();
500     if (details != nullptr) {
501         unifiedRecord->SetDetails(*details);
502     }
503     return unifiedRecord;
504 }
505 
Audio2PasteRecord(const std::shared_ptr<UnifiedRecord> record)506 std::shared_ptr<PasteDataRecord> PasteboardUtils::Audio2PasteRecord(const std::shared_ptr<UnifiedRecord> record)
507 {
508     auto audio = static_cast<UDMF::Audio*>(record.get());
509     if (audio == nullptr) {
510         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "get audio record failed.");
511         return nullptr;
512     }
513     auto uriRecord = PasteDataRecord::NewUriRecord(OHOS::Uri(audio->GetUri()));
514     uriRecord->SetDetails(audio->GetDetails());
515     uriRecord->SetUDType(UDMF::AUDIO);
516     return uriRecord;
517 }
518 
PasteRecord2Audio(const std::shared_ptr<PasteDataRecord> record)519 std::shared_ptr<UnifiedRecord> PasteboardUtils::PasteRecord2Audio(const std::shared_ptr<PasteDataRecord> record)
520 {
521     if (record == nullptr) {
522         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "to audio, record is null.");
523         return nullptr;
524     }
525     auto uri = record->GetUri();
526     if (uri == nullptr) {
527         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "get uri from paste record to audio failed.");
528         return nullptr;
529     }
530     auto unifiedRecord = std::make_shared<UDMF::Audio>(uri->ToString());
531     auto details = record->GetDetails();
532     if (details != nullptr) {
533         unifiedRecord->SetDetails(*details);
534     }
535     return unifiedRecord;
536 }
537 
Folder2PasteRecord(const std::shared_ptr<UnifiedRecord> record)538 std::shared_ptr<PasteDataRecord> PasteboardUtils::Folder2PasteRecord(const std::shared_ptr<UnifiedRecord> record)
539 {
540     auto folder = static_cast<UDMF::Folder*>(record.get());
541     if (folder == nullptr) {
542         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "get folder record failed.");
543         return nullptr;
544     }
545     auto uriRecord = PasteDataRecord::NewUriRecord(OHOS::Uri(folder->GetUri()));
546     uriRecord->SetDetails(folder->GetDetails());
547     uriRecord->SetUDType(UDMF::FOLDER);
548     return uriRecord;
549 }
550 
PasteRecord2Folder(const std::shared_ptr<PasteDataRecord> record)551 std::shared_ptr<UnifiedRecord> PasteboardUtils::PasteRecord2Folder(const std::shared_ptr<PasteDataRecord> record)
552 {
553     if (record == nullptr) {
554         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "to folder, para record is null.");
555         return nullptr;
556     }
557     auto uri = record->GetUri();
558     if (uri == nullptr) {
559         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "get uri from paste record to folder failed.");
560         return nullptr;
561     }
562     auto unifiedRecord = std::make_shared<UDMF::Folder>(uri->ToString());
563     auto details = record->GetDetails();
564     if (details != nullptr) {
565         unifiedRecord->SetDetails(*details);
566     }
567     return unifiedRecord;
568 }
569 
PixelMap2PasteRecord(const std::shared_ptr<UnifiedRecord> record)570 std::shared_ptr<PasteDataRecord> PasteboardUtils::PixelMap2PasteRecord(const std::shared_ptr<UnifiedRecord> record)
571 {
572     auto pixelMap = static_cast<UDMF::SystemDefinedPixelMap*>(record.get());
573     if (pixelMap == nullptr) {
574         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "get pixelMap record failed.");
575         return nullptr;
576     }
577     auto recordValue = pixelMap->GetValue();
578     auto pixelMapValue = std::get_if<std::shared_ptr<Media::PixelMap>>(&recordValue);
579     if (pixelMapValue == nullptr) {
580         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "get pixelMap from unified record failed.");
581         return nullptr;
582     }
583     auto pixelMapRecord = PasteDataRecord::NewPixelMapRecord(*(pixelMapValue));
584     pixelMapRecord->SetUDType(UDMF::SYSTEM_DEFINED_PIXEL_MAP);
585     return pixelMapRecord;
586 }
587 
PasteRecord2PixelMap(const std::shared_ptr<PasteDataRecord> record)588 std::shared_ptr<UnifiedRecord> PasteboardUtils::PasteRecord2PixelMap(const std::shared_ptr<PasteDataRecord> record)
589 {
590     if (record == nullptr) {
591         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "to pixelMap, record is null.");
592         return nullptr;
593     }
594     auto pixelMapRecord = record->GetPixelMap();
595     if (pixelMapRecord == nullptr) {
596         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "get pixelMap from paste record failed.");
597         return nullptr;
598     }
599     return std::make_shared<UDMF::UnifiedRecord>(UDMF::SYSTEM_DEFINED_PIXEL_MAP, pixelMapRecord);
600 }
601 
AppItem2PasteRecord(const std::shared_ptr<UnifiedRecord> record)602 std::shared_ptr<PasteDataRecord> PasteboardUtils::AppItem2PasteRecord(const std::shared_ptr<UnifiedRecord> record)
603 {
604     auto appItem = static_cast<UDMF::SystemDefinedAppItem*>(record.get());
605     if (appItem == nullptr) {
606         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "get SystemDefinedAppItem record failed.");
607         return nullptr;
608     }
609     auto pbRecord = std::make_shared<PasteDataRecord>();
610     auto utdId = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDType::SYSTEM_DEFINED_APP_ITEM);
611     auto value = record->GetOriginValue();
612     if (std::holds_alternative<std::shared_ptr<Object>>(value)) {
613         pbRecord->AddEntry(utdId, std::make_shared<PasteDataEntry>(utdId, value));
614         return pbRecord;
615     }
616     auto object = std::make_shared<Object>();
617     object->value_[UDMF::UNIFORM_DATA_TYPE] = utdId;
618     object->value_[UDMF::APP_ID] = appItem->GetAppId();
619     object->value_[UDMF::APP_NAME] = appItem->GetAppName();
620     object->value_[UDMF::APP_ICON_ID] = appItem->GetAppIconId();
621     object->value_[UDMF::APP_LABEL_ID] = appItem->GetAppLabelId();
622     object->value_[UDMF::BUNDLE_NAME] = appItem->GetBundleName();
623     object->value_[UDMF::ABILITY_NAME] = appItem->GetAbilityName();
624     pbRecord->AddEntry(utdId, std::make_shared<PasteDataEntry>(utdId, object));
625     pbRecord->SetDetails(appItem->GetDetails());
626     return pbRecord;
627 }
628 
PasteRecord2AppItem(const std::shared_ptr<PasteDataRecord> record)629 std::shared_ptr<UnifiedRecord> PasteboardUtils::PasteRecord2AppItem(const std::shared_ptr<PasteDataRecord> record)
630 {
631     if (record == nullptr) {
632         return nullptr;
633     }
634     auto udmfValue = record->GetUDMFValue();
635     if (!udmfValue) {
636         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "udmfvalue is null");
637         return nullptr;
638     }
639     auto unifiedRecord = std::make_shared<UDMF::SystemDefinedAppItem>(UDMF::SYSTEM_DEFINED_APP_ITEM, *udmfValue);
640     if (record->GetDetails() != nullptr) {
641         unifiedRecord->SetDetails(*record->GetDetails());
642     }
643     return unifiedRecord;
644 }
645 
Form2PasteRecord(const std::shared_ptr<UnifiedRecord> record)646 std::shared_ptr<PasteDataRecord> PasteboardUtils::Form2PasteRecord(const std::shared_ptr<UnifiedRecord> record)
647 {
648     auto form = static_cast<UDMF::SystemDefinedForm*>(record.get());
649     if (form == nullptr) {
650         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "get SystemDefinedForm record failed.");
651         return nullptr;
652     }
653     std::vector<uint8_t> arrayBuffer;
654     auto kvRecord = PasteDataRecord::NewKvRecord(Convert(UDType::SYSTEM_DEFINED_FORM), arrayBuffer);
655     kvRecord->SetDetails(form->GetDetails());
656     kvRecord->SetSystemDefinedContent(form->GetItems());
657     kvRecord->SetUDType(UDType::SYSTEM_DEFINED_FORM);
658     return kvRecord;
659 }
660 
PasteRecord2Form(const std::shared_ptr<PasteDataRecord> record)661 std::shared_ptr<UnifiedRecord> PasteboardUtils::PasteRecord2Form(const std::shared_ptr<PasteDataRecord> record)
662 {
663     if (record == nullptr) {
664         return nullptr;
665     }
666     auto unifiedRecord = std::make_shared<UDMF::SystemDefinedForm>();
667     if (record->GetSystemDefinedContent() != nullptr) {
668         unifiedRecord->SetItems(*record->GetSystemDefinedContent());
669     }
670     if (record->GetDetails() != nullptr) {
671         unifiedRecord->SetDetails(*record->GetDetails());
672     }
673     return unifiedRecord;
674 }
675 
SystemDefined2PasteRecord(const std::shared_ptr<UnifiedRecord> record)676 std::shared_ptr<PasteDataRecord> PasteboardUtils::SystemDefined2PasteRecord(const std::shared_ptr<UnifiedRecord> record)
677 {
678     auto systemDefined = static_cast<UDMF::SystemDefinedRecord*>(record.get());
679     if (systemDefined == nullptr) {
680         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "get systemRecord record failed.");
681         return nullptr;
682     }
683     std::vector<uint8_t> arrayBuffer;
684     auto kvRecord = PasteDataRecord::NewKvRecord(Convert(UDType::SYSTEM_DEFINED_RECORD), arrayBuffer);
685     kvRecord->SetDetails(systemDefined->GetDetails());
686     kvRecord->SetUDType(UDType::SYSTEM_DEFINED_RECORD);
687     return kvRecord;
688 }
689 
PasteRecord2SystemDefined(const std::shared_ptr<PasteDataRecord> record)690 std::shared_ptr<UnifiedRecord> PasteboardUtils::PasteRecord2SystemDefined(const std::shared_ptr<PasteDataRecord> record)
691 {
692     if (record == nullptr) {
693         return nullptr;
694     }
695     auto unifiedRecord = std::make_shared<UDMF::SystemDefinedRecord>();
696     if (record->GetDetails() != nullptr) {
697         unifiedRecord->SetDetails(*record->GetDetails());
698     }
699     return unifiedRecord;
700 }
701 
Text2PasteRecord(const std::shared_ptr<UnifiedRecord> record)702 std::shared_ptr<PasteDataRecord> PasteboardUtils::Text2PasteRecord(const std::shared_ptr<UnifiedRecord> record)
703 {
704     auto text = static_cast<UDMF::Text*>(record.get());
705     if (text == nullptr) {
706         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "get TEXT record failed.");
707         return nullptr;
708     }
709     std::vector<uint8_t> arrayBuffer;
710     std::string type = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::TEXT);
711     auto kvRecord = PasteDataRecord::NewKvRecord(type, arrayBuffer);
712     kvRecord->SetUDType(UDMF::TEXT);
713     kvRecord->SetDetails(text->GetDetails());
714     return kvRecord;
715 }
716 
PasteRecord2Text(std::shared_ptr<PasteDataRecord> record)717 std::shared_ptr<UnifiedRecord> PasteboardUtils::PasteRecord2Text(std::shared_ptr<PasteDataRecord> record)
718 {
719     if (record == nullptr) {
720         return nullptr;
721     }
722     auto unifiedRecord = std::make_shared<UDMF::Text>();
723     if (record->GetDetails() != nullptr) {
724         unifiedRecord->SetDetails(*record->GetDetails());
725     }
726     return unifiedRecord;
727 }
728 
Custom2AppDefined(const std::shared_ptr<PasteDataRecord> record)729 std::vector<std::shared_ptr<UnifiedRecord>> PasteboardUtils::Custom2AppDefined(
730     const std::shared_ptr<PasteDataRecord> record)
731 {
732     std::vector<std::shared_ptr<UnifiedRecord>> unifiedRecords;
733     if (record == nullptr) {
734         return unifiedRecords;
735     }
736     if (record->GetCustomData() == nullptr) {
737         return unifiedRecords;
738     }
739     auto customData = record->GetCustomData();
740     if (customData == nullptr) {
741         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "customData is null");
742         return unifiedRecords;
743     }
744     for (auto& [type, rawData] : customData->GetItemData()) {
745         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "app defied type:%{public}s.", type.c_str());
746         unifiedRecords.push_back(std::make_shared<UDMF::ApplicationDefinedRecord>(type, rawData));
747     }
748     return unifiedRecords;
749 }
750 
AppDefined2PasteRecord(const std::shared_ptr<UnifiedRecord> record)751 std::shared_ptr<PasteDataRecord> PasteboardUtils::AppDefined2PasteRecord(const std::shared_ptr<UnifiedRecord> record)
752 {
753     auto appRecord = static_cast<UDMF::ApplicationDefinedRecord*>(record.get());
754     if (appRecord == nullptr) {
755         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "get ApplicationDefinedRecord record failed.");
756         return nullptr;
757     }
758     auto type = appRecord->GetApplicationDefinedType();
759     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "custom type:%{public}s.", type.c_str());
760     auto kvRecord = PasteDataRecord::NewKvRecord(type, appRecord->GetRawData());
761     kvRecord->SetUDType(appRecord->GetType());
762     return kvRecord;
763 }
764 
DeduplicateVector(const std::vector<std::string> & vec)765 std::vector<std::string> PasteboardUtils::DeduplicateVector(const std::vector<std::string> &vec)
766 {
767     std::unordered_set<std::string> tmp(vec.begin(), vec.end());
768     std::vector<std::string> result(tmp.begin(), tmp.end());
769     return result;
770 }
771 
PasteboardUtils()772 PasteboardUtils::PasteboardUtils()
773 {
774     InitDecodeMap();
775 }
776 
GetInstance()777 PasteboardUtils& PasteboardUtils::GetInstance()
778 {
779     static PasteboardUtils instance;
780     return instance;
781 }
782 } // namespace MiscServices
783 } // namespace OHOS