• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-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 
16 #include "pasteboard_client.h"
17 #include "pasteboard_common.h"
18 #include "pasteboard_hilog.h"
19 
20 using namespace OHOS::Media;
21 
22 namespace OHOS {
23 namespace MiscServices {
24 constexpr int MAX_TEXT_LEN = 20 * 1024 * 1024;
25 
SetMimeType(std::string mimeType)26 PasteDataRecord::Builder &PasteDataRecord::Builder::SetMimeType(std::string mimeType)
27 {
28     record_->mimeType_ = std::move(mimeType);
29     return *this;
30 }
31 enum TAG_PASTEBOARD_RECORD : uint16_t {
32     TAG_MIMETYPE = TAG_BUFF + 1,
33     TAG_HTMLTEXT,
34     TAG_WANT,
35     TAG_PLAINTEXT,
36     TAG_URI,
37     TAG_PIXELMAP,
38     TAG_CUSTOM_DATA,
39     TAG_CONVERT_URI,
40     TAG_URI_PERMISSION,
41     TAG_UDC_UDTYPE,
42     TAG_UDC_DETAILS,
43     TAG_UDC_TEXTCONTENT,
44     TAG_UDC_SYSTEMCONTENTS,
45     TAG_UDC_UDMFVALUE,
46     TAG_UDC_ENTRIES,
47     TAG_DATA_ID,
48     TAG_RECORD_ID,
49     TAG_DELAY_RECORD_FLAG,
50     TAG_FROM,
51 };
52 
SetHtmlText(std::shared_ptr<std::string> htmlText)53 PasteDataRecord::Builder &PasteDataRecord::Builder::SetHtmlText(std::shared_ptr<std::string> htmlText)
54 {
55     record_->htmlText_ = std::move(htmlText);
56     return *this;
57 }
58 
SetWant(std::shared_ptr<OHOS::AAFwk::Want> want)59 PasteDataRecord::Builder &PasteDataRecord::Builder::SetWant(std::shared_ptr<OHOS::AAFwk::Want> want)
60 {
61     record_->want_ = std::move(want);
62     return *this;
63 }
64 
SetPlainText(std::shared_ptr<std::string> plainText)65 PasteDataRecord::Builder &PasteDataRecord::Builder::SetPlainText(std::shared_ptr<std::string> plainText)
66 {
67     record_->plainText_ = std::move(plainText);
68     return *this;
69 }
SetUri(std::shared_ptr<OHOS::Uri> uri)70 PasteDataRecord::Builder &PasteDataRecord::Builder::SetUri(std::shared_ptr<OHOS::Uri> uri)
71 {
72     record_->uri_ = std::move(uri);
73     return *this;
74 }
75 
SetPixelMap(std::shared_ptr<OHOS::Media::PixelMap> pixelMap)76 PasteDataRecord::Builder &PasteDataRecord::Builder::SetPixelMap(std::shared_ptr<OHOS::Media::PixelMap> pixelMap)
77 {
78     record_->pixelMap_ = std::move(pixelMap);
79     return *this;
80 }
81 
SetCustomData(std::shared_ptr<MineCustomData> customData)82 PasteDataRecord::Builder &PasteDataRecord::Builder::SetCustomData(std::shared_ptr<MineCustomData> customData)
83 {
84     record_->customData_ = std::move(customData);
85     return *this;
86 }
87 
Build()88 std::shared_ptr<PasteDataRecord> PasteDataRecord::Builder::Build()
89 {
90     return record_;
91 }
92 
Builder(const std::string & mimeType)93 PasteDataRecord::Builder::Builder(const std::string &mimeType)
94 {
95     record_ = std::make_shared<PasteDataRecord>();
96     if (record_ != nullptr) {
97         record_->mimeType_ = mimeType;
98         record_->htmlText_ = nullptr;
99         record_->want_ = nullptr;
100         record_->plainText_ = nullptr;
101         record_->uri_ = nullptr;
102         record_->convertUri_ = "";
103         record_->pixelMap_ = nullptr;
104         record_->customData_ = nullptr;
105     }
106 }
107 
AddUriEntry()108 void PasteDataRecord::AddUriEntry()
109 {
110     auto object = std::make_shared<Object>();
111     object->value_[UDMF::UNIFORM_DATA_TYPE] = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::FILE_URI);
112     if (uri_ != nullptr) {
113         object->value_[UDMF::FILE_URI_PARAM] = uri_->ToString();
114     }
115     auto utdId = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::FILE_URI);
116     AddEntry(utdId, std::make_shared<PasteDataEntry>(utdId, object));
117 }
118 
NewHtmlRecord(const std::string & htmlText)119 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewHtmlRecord(const std::string &htmlText)
120 {
121     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE((htmlText.length() < MAX_TEXT_LEN), nullptr,
122         PASTEBOARD_MODULE_CLIENT, "record length not support, length=%{public}zu", htmlText.length());
123     return Builder(MIMETYPE_TEXT_HTML).SetHtmlText(std::make_shared<std::string>(htmlText)).Build();
124 }
125 
NewWantRecord(std::shared_ptr<OHOS::AAFwk::Want> want)126 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewWantRecord(std::shared_ptr<OHOS::AAFwk::Want> want)
127 {
128     return Builder(MIMETYPE_TEXT_WANT).SetWant(std::move(want)).Build();
129 }
130 
NewPlainTextRecord(const std::string & text)131 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewPlainTextRecord(const std::string &text)
132 {
133     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE((text.length() < MAX_TEXT_LEN), nullptr,
134         PASTEBOARD_MODULE_CLIENT, "PlainText length not support, length=%{public}zu", text.length());
135     return Builder(MIMETYPE_TEXT_PLAIN).SetPlainText(std::make_shared<std::string>(text)).Build();
136 }
137 
NewPixelMapRecord(std::shared_ptr<PixelMap> pixelMap)138 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewPixelMapRecord(std::shared_ptr<PixelMap> pixelMap)
139 {
140     return Builder(MIMETYPE_PIXELMAP).SetPixelMap(std::move(pixelMap)).Build();
141 }
142 
NewUriRecord(const OHOS::Uri & uri)143 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewUriRecord(const OHOS::Uri &uri)
144 {
145     return Builder(MIMETYPE_TEXT_URI).SetUri(std::make_shared<OHOS::Uri>(uri)).Build();
146 }
147 
NewKvRecord(const std::string & mimeType,const std::vector<uint8_t> & arrayBuffer)148 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewKvRecord(
149     const std::string &mimeType, const std::vector<uint8_t> &arrayBuffer)
150 {
151     std::shared_ptr<MineCustomData> customData = std::make_shared<MineCustomData>();
152     customData->AddItemData(mimeType, arrayBuffer);
153     return Builder(mimeType).SetCustomData(std::move(customData)).Build();
154 }
155 
NewMultiTypeRecord(std::shared_ptr<std::map<std::string,std::shared_ptr<EntryValue>>> values,const std::string & recordMimeType)156 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewMultiTypeRecord(
157     std::shared_ptr<std::map<std::string, std::shared_ptr<EntryValue>>> values, const std::string &recordMimeType)
158 {
159     auto record = std::make_shared<PasteDataRecord>();
160     if (values == nullptr) {
161         return record;
162     }
163     if (!recordMimeType.empty()) {
164         auto recordDefaultIter = values->find(recordMimeType);
165         if (recordDefaultIter != values->end() && recordDefaultIter->second != nullptr) {
166             auto utdId = CommonUtils::Convert2UtdId(UDMF::UDType::UD_BUTT, recordMimeType);
167             record->AddEntry(utdId, std::make_shared<PasteDataEntry>(utdId, *(recordDefaultIter->second)));
168         }
169     }
170     for (auto [mimeType, value] : *values) {
171         if (mimeType == recordMimeType) {
172             continue;
173         }
174         auto utdId = CommonUtils::Convert2UtdId(UDMF::UDType::UD_BUTT, mimeType);
175         record->AddEntry(utdId, std::make_shared<PasteDataEntry>(utdId, *value));
176     }
177     return record;
178 }
179 
NewMultiTypeDelayRecord(std::vector<std::string> mimeTypes,const std::shared_ptr<UDMF::EntryGetter> entryGetter)180 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewMultiTypeDelayRecord(
181     std::vector<std::string> mimeTypes, const std::shared_ptr<UDMF::EntryGetter> entryGetter)
182 {
183     auto record = std::make_shared<PasteDataRecord>();
184     for (auto mimeType : mimeTypes) {
185         auto utdId = CommonUtils::Convert2UtdId(UDMF::UDType::UD_BUTT, mimeType);
186         auto entry = std::make_shared<PasteDataEntry>();
187         entry->SetMimeType(mimeType);
188         entry->SetUtdId(utdId);
189         record->AddEntry(utdId, entry);
190     }
191     if (entryGetter != nullptr) {
192         record->SetEntryGetter(entryGetter);
193         record->SetDelayRecordFlag(true);
194     }
195     return record;
196 }
197 
PasteDataRecord(std::string mimeType,std::shared_ptr<std::string> htmlText,std::shared_ptr<OHOS::AAFwk::Want> want,std::shared_ptr<std::string> plainText,std::shared_ptr<OHOS::Uri> uri)198 PasteDataRecord::PasteDataRecord(std::string mimeType, std::shared_ptr<std::string> htmlText,
199     std::shared_ptr<OHOS::AAFwk::Want> want, std::shared_ptr<std::string> plainText, std::shared_ptr<OHOS::Uri> uri)
200     : mimeType_{ std::move(mimeType) }, htmlText_{ std::move(htmlText) }, want_{ std::move(want) },
201       plainText_{ std::move(plainText) }, uri_{ std::move(uri) }
202 {
203     InitDecodeMap();
204 }
205 
PasteDataRecord()206 PasteDataRecord::PasteDataRecord()
207 {
208     InitDecodeMap();
209 }
210 
~PasteDataRecord()211 PasteDataRecord::~PasteDataRecord()
212 {
213     decodeMap.clear();
214 }
215 
PasteDataRecord(const PasteDataRecord & record)216 PasteDataRecord::PasteDataRecord(const PasteDataRecord &record)
217     : mimeType_(record.mimeType_), htmlText_(record.htmlText_), want_(record.want_), plainText_(record.plainText_),
218       uri_(record.uri_), convertUri_(record.convertUri_), pixelMap_(record.pixelMap_), customData_(record.customData_),
219       hasGrantUriPermission_(record.hasGrantUriPermission_), udType_(record.udType_),
220       details_(record.details_), textContent_(record.textContent_),
221       systemDefinedContents_(record.systemDefinedContents_), udmfValue_(record.udmfValue_), entries_(record.entries_),
222       dataId_(record.dataId_), recordId_(record.recordId_), isDelay_(record.isDelay_),
223       entryGetter_(record.entryGetter_), from_(record.from_)
224 {
225     this->isConvertUriFromRemote = record.isConvertUriFromRemote;
226     InitDecodeMap();
227 }
228 
InitDecodeMap()229 void PasteDataRecord::InitDecodeMap()
230 {
231     decodeMap = {
232         {TAG_MIMETYPE,
233             [&](ReadOnlyBuffer &buffer, TLVHead &head) { return buffer.ReadValue(mimeType_, head); }},
234         {TAG_HTMLTEXT,
235             [&](ReadOnlyBuffer &buffer, TLVHead &head) { return buffer.ReadValue(htmlText_, head); }},
236         {TAG_WANT,
237             [&](ReadOnlyBuffer &buffer, TLVHead &head) { return buffer.ReadValue(want_, head); }},
238         {TAG_PLAINTEXT,
239             [&](ReadOnlyBuffer &buffer, TLVHead &head) { return buffer.ReadValue(plainText_, head); }},
240         {TAG_URI,
241             [&](ReadOnlyBuffer &buffer, TLVHead &head) { return buffer.ReadValue(uri_, head); }},
242         {TAG_CONVERT_URI,
243             [&](ReadOnlyBuffer &buffer, TLVHead &head) { return buffer.ReadValue(convertUri_, head); }},
244         {TAG_PIXELMAP,
245             [&](ReadOnlyBuffer &buffer, TLVHead &head) { return buffer.ReadValue(pixelMap_, head); }},
246         {TAG_CUSTOM_DATA,
247             [&](ReadOnlyBuffer &buffer, TLVHead &head) { return buffer.ReadValue(customData_, head);}},
248         {TAG_URI_PERMISSION,
249             [&](ReadOnlyBuffer &buffer, TLVHead &head) { return buffer.ReadValue(hasGrantUriPermission_, head); }},
250         {TAG_UDC_UDTYPE,
251             [&](ReadOnlyBuffer &buffer, TLVHead &head) { return buffer.ReadValue(udType_, head); }},
252         {TAG_UDC_DETAILS,
253             [&](ReadOnlyBuffer &buffer, TLVHead &head) { return buffer.ReadValue(details_, head); }},
254         {TAG_UDC_TEXTCONTENT,
255             [&](ReadOnlyBuffer &buffer, TLVHead &head) { return buffer.ReadValue(textContent_, head); }},
256         {TAG_UDC_SYSTEMCONTENTS,
257             [&](ReadOnlyBuffer &buffer, TLVHead &head) { return buffer.ReadValue(systemDefinedContents_, head); }},
258         {TAG_UDC_UDMFVALUE,
259             [&](ReadOnlyBuffer &buffer, TLVHead &head) { return buffer.ReadValue(udmfValue_, head); }},
260         {TAG_UDC_ENTRIES,
261             [&](ReadOnlyBuffer &buffer, TLVHead &head) { return buffer.ReadValue(entries_, head); }},
262         {TAG_DATA_ID,
263             [&](ReadOnlyBuffer &buffer, TLVHead &head) { return buffer.ReadValue(dataId_, head); }},
264         {TAG_RECORD_ID,
265             [&](ReadOnlyBuffer &buffer, TLVHead &head) { return buffer.ReadValue(recordId_, head); }},
266         {TAG_DELAY_RECORD_FLAG,
267             [&](ReadOnlyBuffer &buffer, TLVHead &head) { return buffer.ReadValue(isDelay_, head); }},
268         {TAG_FROM,
269             [&](ReadOnlyBuffer &buffer, TLVHead &head) { return buffer.ReadValue(from_, head); }},
270     };
271 }
272 
GetHtmlText() const273 std::shared_ptr<std::string> PasteDataRecord::GetHtmlText() const
274 {
275     if (htmlText_ != nullptr && mimeType_ == MIMETYPE_TEXT_HTML) {
276         return htmlText_;
277     }
278     for (const auto &entry : entries_) {
279         if (entry && entry->GetMimeType() == MIMETYPE_TEXT_HTML) {
280             return entry->ConvertToHtml();
281         }
282     }
283     return htmlText_;
284 }
285 
GetMimeType() const286 std::string PasteDataRecord::GetMimeType() const
287 {
288     return this->mimeType_;
289 }
290 
GetPlainText() const291 std::shared_ptr<std::string> PasteDataRecord::GetPlainText() const
292 {
293     if (plainText_ != nullptr && mimeType_ == MIMETYPE_TEXT_PLAIN) {
294         return plainText_;
295     }
296     for (const auto &entry : entries_) {
297         if (entry && entry->GetMimeType() == MIMETYPE_TEXT_PLAIN) {
298             return entry->ConvertToPlainText();
299         }
300     }
301     return plainText_;
302 }
303 
GetPixelMap() const304 std::shared_ptr<PixelMap> PasteDataRecord::GetPixelMap() const
305 {
306     if (pixelMap_ != nullptr && mimeType_ == MIMETYPE_PIXELMAP) {
307         return pixelMap_;
308     }
309     for (const auto &entry : entries_) {
310         if (entry && entry->GetMimeType() == MIMETYPE_PIXELMAP) {
311             return entry->ConvertToPixelMap();
312         }
313     }
314     return pixelMap_;
315 }
316 
GetUri() const317 std::shared_ptr<OHOS::Uri> PasteDataRecord::GetUri() const
318 {
319     if (convertUri_.empty()) {
320         return GetOriginUri();
321     }
322     return std::make_shared<OHOS::Uri>(convertUri_);
323 }
324 
ClearPixelMap()325 void PasteDataRecord::ClearPixelMap()
326 {
327     this->pixelMap_ = nullptr;
328 }
329 
SetUri(std::shared_ptr<OHOS::Uri> uri)330 void PasteDataRecord::SetUri(std::shared_ptr<OHOS::Uri> uri)
331 {
332     uri_ = std::move(uri);
333     AddUriEntry();
334 }
335 
GetOriginUri() const336 std::shared_ptr<OHOS::Uri> PasteDataRecord::GetOriginUri() const
337 {
338     if (uri_ != nullptr && mimeType_ == MIMETYPE_TEXT_URI) {
339         return uri_;
340     }
341     for (const auto &entry : entries_) {
342         if (entry && entry->GetMimeType() == MIMETYPE_TEXT_URI) {
343             return entry->ConvertToUri();
344         }
345     }
346     return uri_;
347 }
348 
GetWant() const349 std::shared_ptr<OHOS::AAFwk::Want> PasteDataRecord::GetWant() const
350 {
351     if (want_ != nullptr && mimeType_ == MIMETYPE_TEXT_WANT) {
352         return want_;
353     }
354     for (const auto &entry : entries_) {
355         if (entry && entry->GetMimeType() == MIMETYPE_TEXT_WANT) {
356             return entry->ConvertToWant();
357         }
358     }
359     return want_;
360 }
361 
GetCustomData() const362 std::shared_ptr<MineCustomData> PasteDataRecord::GetCustomData() const
363 {
364     std::shared_ptr<MineCustomData> customData = std::make_shared<MineCustomData>();
365     if (customData_) {
366         const std::map<std::string, std::vector<uint8_t>> &itemData = customData_->GetItemData();
367         for (const auto &[key, value] : itemData) {
368             customData->AddItemData(key, value);
369         }
370     }
371     for (const auto &entry : entries_) {
372         if (entry && entry->GetMimeType() == entry->GetUtdId()) {
373             std::shared_ptr<MineCustomData> entryCustomData = entry->ConvertToCustomData();
374             if (entryCustomData == nullptr) {
375                 continue;
376             }
377             const std::map<std::string, std::vector<uint8_t>> &itemData = entryCustomData->GetItemData();
378             for (const auto &[key, value] : itemData) {
379                 customData->AddItemData(key, value);
380             }
381         }
382     }
383     return customData->GetItemData().empty() ? nullptr : customData;
384 }
385 
ConvertToText() const386 std::string PasteDataRecord::ConvertToText() const
387 {
388     auto htmlText = GetHtmlText();
389     if (htmlText != nullptr) {
390         return *htmlText;
391     }
392     auto plainText = GetPlainText();
393     if (plainText != nullptr) {
394         return *plainText;
395     }
396     auto originUri = GetOriginUri();
397     if (originUri != nullptr) {
398         return originUri->ToString();
399     }
400     return "";
401 }
402 
EncodeTLV(WriteOnlyBuffer & buffer) const403 bool PasteDataRecord::EncodeTLV(WriteOnlyBuffer &buffer) const
404 {
405     bool ret = buffer.Write(TAG_MIMETYPE, mimeType_);
406     ret = ret && buffer.Write(TAG_HTMLTEXT, htmlText_);
407     ret = ret && buffer.Write(TAG_WANT, TLVUtils::Parcelable2Raw(want_.get()));
408     ret = ret && buffer.Write(TAG_PLAINTEXT, plainText_);
409     ret = ret && buffer.Write(TAG_URI, TLVUtils::Parcelable2Raw(uri_.get()));
410     ret = ret && buffer.Write(TAG_CONVERT_URI, convertUri_);
411     ret = ret && buffer.Write(TAG_PIXELMAP, pixelMap_);
412     ret = ret && buffer.Write(TAG_CUSTOM_DATA, customData_);
413     ret = ret && buffer.Write(TAG_URI_PERMISSION, hasGrantUriPermission_);
414     ret = ret && buffer.Write(TAG_UDC_UDTYPE, udType_);
415     ret = ret && buffer.Write(TAG_UDC_DETAILS, details_);
416     ret = ret && buffer.Write(TAG_UDC_TEXTCONTENT, textContent_);
417     ret = ret && buffer.Write(TAG_UDC_SYSTEMCONTENTS, systemDefinedContents_);
418     ret = ret && buffer.Write(TAG_UDC_UDMFVALUE, udmfValue_);
419     ret = ret && buffer.Write(TAG_UDC_ENTRIES, entries_);
420     ret = ret && buffer.Write(TAG_DATA_ID, dataId_);
421     ret = ret && buffer.Write(TAG_RECORD_ID, recordId_);
422     ret = ret && buffer.Write(TAG_DELAY_RECORD_FLAG, isDelay_);
423     ret = ret && buffer.Write(TAG_FROM, from_);
424     return ret;
425 }
426 
DecodeTLV(ReadOnlyBuffer & buffer)427 bool PasteDataRecord::DecodeTLV(ReadOnlyBuffer &buffer)
428 {
429     for (; buffer.IsEnough();) {
430         TLVHead head{};
431         bool ret = buffer.ReadHead(head);
432         PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret, false, PASTEBOARD_MODULE_COMMON, "read head failed");
433 
434         auto it = decodeMap.find(head.tag);
435         if (it == decodeMap.end()) {
436             ret = buffer.Skip(head.len);
437         } else {
438             ret = it->second(buffer, head);
439         }
440         PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret, false, PASTEBOARD_MODULE_COMMON,
441             "read value failed, tag=%{public}hu, len=%{public}u", head.tag, head.len);
442     }
443     return true;
444 }
445 
CountTLV() const446 size_t PasteDataRecord::CountTLV() const
447 {
448     size_t expectedSize = 0;
449     expectedSize += TLVCountable::Count(mimeType_);
450     expectedSize += TLVCountable::Count(htmlText_);
451     expectedSize += TLVCountable::Count(TLVUtils::Parcelable2Raw(want_.get()));
452     expectedSize += TLVCountable::Count(plainText_);
453     expectedSize += TLVCountable::Count(TLVUtils::Parcelable2Raw(uri_.get()));
454     expectedSize += TLVCountable::Count(convertUri_);
455     expectedSize += TLVCountable::Count(pixelMap_);
456     expectedSize += TLVCountable::Count(customData_);
457     expectedSize += TLVCountable::Count(hasGrantUriPermission_);
458     expectedSize += TLVCountable::Count(udType_);
459     expectedSize += TLVCountable::Count(details_);
460     expectedSize += TLVCountable::Count(textContent_);
461     expectedSize += TLVCountable::Count(systemDefinedContents_);
462     expectedSize += TLVCountable::Count(udmfValue_);
463     expectedSize += TLVCountable::Count(entries_);
464     expectedSize += TLVCountable::Count(dataId_);
465     expectedSize += TLVCountable::Count(recordId_);
466     expectedSize += TLVCountable::Count(isDelay_);
467     expectedSize += TLVCountable::Count(from_);
468     return expectedSize;
469 }
470 
GetPassUri()471 std::string PasteDataRecord::GetPassUri()
472 {
473     std::string tempUri;
474     if (uri_ != nullptr) {
475         tempUri = uri_->ToString();
476     }
477     if (!convertUri_.empty()) {
478         tempUri = convertUri_;
479     }
480     return tempUri;
481 }
482 
SetConvertUri(const std::string & value)483 void PasteDataRecord::SetConvertUri(const std::string &value)
484 {
485     convertUri_ = value;
486 }
487 
GetConvertUri() const488 std::string PasteDataRecord::GetConvertUri() const
489 {
490     return convertUri_;
491 }
492 
SetGrantUriPermission(bool hasPermission)493 void PasteDataRecord::SetGrantUriPermission(bool hasPermission)
494 {
495     hasGrantUriPermission_ = hasPermission;
496 }
497 
HasGrantUriPermission()498 bool PasteDataRecord::HasGrantUriPermission()
499 {
500     return hasGrantUriPermission_;
501 }
502 
SetTextContent(const std::string & content)503 void PasteDataRecord::SetTextContent(const std::string &content)
504 {
505     this->textContent_ = content;
506 }
507 
GetTextContent() const508 std::string PasteDataRecord::GetTextContent() const
509 {
510     return this->textContent_;
511 }
512 
SetDetails(const Details & details)513 void PasteDataRecord::SetDetails(const Details &details)
514 {
515     this->details_ = std::make_shared<Details>(details);
516 }
517 
GetDetails() const518 std::shared_ptr<Details> PasteDataRecord::GetDetails() const
519 {
520     return this->details_;
521 }
522 
SetSystemDefinedContent(const Details & contents)523 void PasteDataRecord::SetSystemDefinedContent(const Details &contents)
524 {
525     this->systemDefinedContents_ = std::make_shared<Details>(contents);
526 }
527 
GetSystemDefinedContent() const528 std::shared_ptr<Details> PasteDataRecord::GetSystemDefinedContent() const
529 {
530     return this->systemDefinedContents_;
531 }
532 
GetUDType() const533 int32_t PasteDataRecord::GetUDType() const
534 {
535     return this->udType_;
536 }
537 
SetUDType(int32_t type)538 void PasteDataRecord::SetUDType(int32_t type)
539 {
540     this->udType_ = type;
541 }
542 
GetValidMimeTypes(const std::vector<std::string> & mimeTypes) const543 std::vector<std::string> PasteDataRecord::GetValidMimeTypes(const std::vector<std::string> &mimeTypes) const
544 {
545     std::vector<std::string> res;
546     auto allTypes = GetMimeTypes();
547     for (auto const& type : mimeTypes) {
548         if (allTypes.find(type) != allTypes.end()) {
549             res.emplace_back(type);
550         }
551     }
552     return res;
553 }
554 
GetValidTypes(const std::vector<std::string> & types) const555 std::vector<std::string> PasteDataRecord::GetValidTypes(const std::vector<std::string> &types) const
556 {
557     std::vector<std::string> res;
558     auto allTypes = GetUdtTypes();
559     for (auto const &type : types) {
560         if (allTypes.find(type) != allTypes.end()) {
561             res.emplace_back(type);
562         }
563     }
564     return res;
565 }
566 
HasEmptyEntry() const567 bool PasteDataRecord::HasEmptyEntry() const
568 {
569     if (udmfValue_ && !std::holds_alternative<std::monostate>(*udmfValue_)) {
570         return false;
571     }
572     for (auto const &entry : GetEntries()) {
573         if (std::holds_alternative<std::monostate>(entry->GetValue())) {
574             return true;
575         }
576     }
577     return false;
578 }
579 
SetUDMFValue(const std::shared_ptr<EntryValue> & udmfValue)580 void PasteDataRecord::SetUDMFValue(const std::shared_ptr<EntryValue> &udmfValue)
581 {
582     this->udmfValue_ = udmfValue;
583 }
584 
GetUDMFValue()585 std::shared_ptr<EntryValue> PasteDataRecord::GetUDMFValue()
586 {
587     if (udmfValue_) {
588         PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "udmfValue_ is not null");
589         return this->udmfValue_;
590     }
591     if (mimeType_.empty()) {
592         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "mimetype is null");
593         return nullptr;
594     }
595     auto object = std::make_shared<Object>();
596     if (mimeType_ == MIMETYPE_TEXT_PLAIN) {
597         object->value_[UDMF::UNIFORM_DATA_TYPE] = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::PLAIN_TEXT);
598         if (plainText_ != nullptr) {
599             object->value_[UDMF::CONTENT] = *plainText_;
600         }
601     } else if (mimeType_ == MIMETYPE_TEXT_HTML) {
602         object->value_[UDMF::UNIFORM_DATA_TYPE] = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::HTML);
603         if (htmlText_ != nullptr) {
604             object->value_[UDMF::HTML_CONTENT] = *htmlText_;
605         }
606         if (plainText_ != nullptr) {
607             object->value_[UDMF::PLAIN_CONTENT] = *plainText_;
608         }
609     } else if (mimeType_ == MIMETYPE_PIXELMAP) {
610         object->value_[UDMF::UNIFORM_DATA_TYPE] = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::SYSTEM_DEFINED_PIXEL_MAP);
611         if (pixelMap_ != nullptr) {
612             object->value_[UDMF::PIXEL_MAP] = pixelMap_;
613         }
614     } else if (mimeType_ == MIMETYPE_TEXT_URI) {
615         object->value_[UDMF::UNIFORM_DATA_TYPE] = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::FILE_URI);
616         auto uri = GetUri();
617         if (uri != nullptr) {
618             object->value_[UDMF::FILE_URI_PARAM] = uri->ToString();
619         }
620     } else if (mimeType_ == MIMETYPE_TEXT_WANT) {
621         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "mimeType is want, udmf not supports");
622     } else if (customData_ != nullptr) {
623         auto itemData = customData_->GetItemData();
624         if (itemData.size() == 0) {
625             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "no customData");
626             return udmfValue_;
627         }
628         if (itemData.size() != 1) {
629             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT,
630                 "not supports u8 map, mimeType:%{public}s, customData.size:%{public}zu", mimeType_.c_str(),
631                 itemData.size());
632         }
633         udmfValue_ = std::make_shared<EntryValue>(itemData.begin()->second);
634         return udmfValue_;
635     }
636     udmfValue_ = std::make_shared<EntryValue>(object);
637     return udmfValue_;
638 }
639 
GetUdtTypes() const640 std::set<std::string> PasteDataRecord::GetUdtTypes() const
641 {
642     std::set<std::string> types;
643     types.emplace(CommonUtils::Convert2UtdId(udType_, mimeType_));
644     for (auto const &entry : entries_) {
645         types.emplace(entry->GetUtdId());
646     }
647     return types;
648 }
649 
GetMimeTypes() const650 std::set<std::string> PasteDataRecord::GetMimeTypes() const
651 {
652     std::set<std::string> types;
653     types.emplace(mimeType_);
654     for (auto const& entry: entries_) {
655         types.emplace(entry->GetMimeType());
656     }
657     return types;
658 }
659 
AddEntryByMimeType(const std::string & mimeType,std::shared_ptr<PasteDataEntry> value)660 void PasteDataRecord::AddEntryByMimeType(const std::string &mimeType, std::shared_ptr<PasteDataEntry> value)
661 {
662     PASTEBOARD_CHECK_AND_RETURN_LOGE(value != nullptr, PASTEBOARD_MODULE_CLIENT, "value is null");
663     auto utdId = CommonUtils::Convert2UtdId(UDMF::UDType::UD_BUTT, mimeType);
664     value->SetUtdId(utdId);
665     AddEntry(utdId, value);
666 }
667 
AddEntry(const std::string & utdType,std::shared_ptr<PasteDataEntry> value)668 void PasteDataRecord::AddEntry(const std::string &utdType, std::shared_ptr<PasteDataEntry> value)
669 {
670     PASTEBOARD_CHECK_AND_RETURN_LOGE(value != nullptr, PASTEBOARD_MODULE_CLIENT, "Entry value is null");
671     if (utdType != value->GetUtdId()) {
672         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "type is diff. utdtype:%{public}s, UtdId:%{public}s",
673             utdType.c_str(), value->GetUtdId().c_str());
674         return;
675     }
676     // first entry save to record, or record type same
677     if (mimeType_.empty() || utdType == CommonUtils::Convert2UtdId(udType_, mimeType_)) {
678         mimeType_ = value->GetMimeType();
679         auto udType = UDMF::UtdUtils::GetUtdEnumFromUtdId(utdType);
680         udType_ = udType == UDMF::UDType::UD_BUTT ? UDMF::UDType::APPLICATION_DEFINED_RECORD : udType;
681         udmfValue_ = std::make_shared<EntryValue>(value->GetValue());
682         if (mimeType_ == MIMETYPE_PIXELMAP) {
683             pixelMap_ = value->ConvertToPixelMap();
684         } else if (mimeType_ == MIMETYPE_TEXT_HTML) {
685             htmlText_ = value->ConvertToHtml();
686             plainText_ = value->ConvertToPlainText();
687         } else if (mimeType_ == MIMETYPE_TEXT_PLAIN) {
688             plainText_ = value->ConvertToPlainText();
689         } else if (mimeType_ == MIMETYPE_TEXT_URI) {
690             uri_ = value->ConvertToUri();
691         } else if (mimeType_ == MIMETYPE_TEXT_WANT) {
692             want_ = value->ConvertToWant();
693         } else {
694             customData_ = value->ConvertToCustomData();
695         }
696         return;
697     }
698     // not first entry
699     bool has = false;
700     for (auto &entry : entries_) {
701         if (entry->GetUtdId() == utdType) {
702             entry = value;
703             has = true;
704             break;
705         }
706     }
707     if (!has) {
708         entries_.emplace_back(value);
709     }
710 }
711 
GetEntryByMimeType(const std::string & mimeType)712 std::shared_ptr<PasteDataEntry> PasteDataRecord::GetEntryByMimeType(const std::string &mimeType)
713 {
714     if (udmfValue_ == nullptr) {
715         udmfValue_ = GetUDMFValue();
716     }
717     auto utdId = CommonUtils::Convert2UtdId(UDMF::UDType::UD_BUTT, mimeType);
718     return GetEntry(utdId);
719 }
720 
GetEntry(const std::string & utdType)721 std::shared_ptr<PasteDataEntry> PasteDataRecord::GetEntry(const std::string &utdType)
722 {
723     if (udmfValue_ == nullptr) {
724         udmfValue_ = GetUDMFValue();
725     }
726     if (CommonUtils::Convert2UtdId(udType_, mimeType_) == utdType) {
727         if (udmfValue_ == nullptr) {
728             return nullptr;
729         }
730         auto entry = std::make_shared<PasteDataEntry>(utdType, *udmfValue_);
731         if (isDelay_ && !entry->HasContent(utdType) && !PasteBoardCommon::IsPasteboardService()) {
732             PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "get delay record value, dataId=%{public}u, "
733                 "recordId=%{public}u, type=%{public}s", dataId_, recordId_, utdType.c_str());
734             PasteboardClient::GetInstance()->GetRecordValueByType(dataId_, recordId_, *entry);
735         }
736         if (CommonUtils::IsFileUri(utdType) && GetUri() != nullptr) {
737             return std::make_shared<PasteDataEntry>(utdType, GetUri()->ToString());
738         } else if (mimeType_ == MIMETYPE_TEXT_WANT) {
739             return std::make_shared<PasteDataEntry>(utdType, want_);
740         }
741         return entry;
742     }
743     for (auto const &entry : entries_) {
744         if (entry->GetUtdId() == utdType ||
745             (CommonUtils::IsFileUri(utdType) && CommonUtils::IsFileUri(entry->GetUtdId()))) {
746             if (isDelay_ && !entry->HasContent(utdType) && !PasteBoardCommon::IsPasteboardService()) {
747                 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "get delay entry value, dataId=%{public}u, "
748                     "recordId=%{public}u, type=%{public}s", dataId_, recordId_, utdType.c_str());
749                 PasteboardClient::GetInstance()->GetRecordValueByType(dataId_, recordId_, *entry);
750             }
751             if (CommonUtils::IsFileUri(utdType) && GetUri() != nullptr) {
752                 return std::make_shared<PasteDataEntry>(utdType, GetUri()->ToString());
753             }
754             return entry;
755         }
756     }
757     return nullptr;
758 }
759 
GetEntries() const760 std::vector<std::shared_ptr<PasteDataEntry>> PasteDataRecord::GetEntries() const
761 {
762     std::vector<std::shared_ptr<PasteDataEntry>> entries = entries_;
763     if (udmfValue_ != nullptr) {
764         entries.insert(entries.begin(),
765             std::make_shared<PasteDataEntry>(CommonUtils::Convert2UtdId(udType_, mimeType_), *udmfValue_));
766     }
767     return entries;
768 }
769 
SetDataId(uint32_t dataId)770 void PasteDataRecord::SetDataId(uint32_t dataId)
771 {
772     dataId_ = dataId;
773 }
774 
GetDataId() const775 uint32_t PasteDataRecord::GetDataId() const
776 {
777     return dataId_;
778 }
779 
SetRecordId(uint32_t recordId)780 void PasteDataRecord::SetRecordId(uint32_t recordId)
781 {
782     recordId_ = recordId;
783 }
784 
GetRecordId() const785 uint32_t PasteDataRecord::GetRecordId() const
786 {
787     return recordId_;
788 }
789 
SetDelayRecordFlag(bool isDelay)790 void PasteDataRecord::SetDelayRecordFlag(bool isDelay)
791 {
792     isDelay_ = isDelay;
793 }
794 
IsDelayRecord() const795 bool PasteDataRecord::IsDelayRecord() const
796 {
797     return isDelay_;
798 }
799 
SetEntryGetter(const std::shared_ptr<UDMF::EntryGetter> entryGetter)800 void PasteDataRecord::SetEntryGetter(const std::shared_ptr<UDMF::EntryGetter> entryGetter)
801 {
802     entryGetter_ = std::move(entryGetter);
803 }
804 
SetFrom(uint32_t from)805 void PasteDataRecord::SetFrom(uint32_t from)
806 {
807     from_ = from;
808 }
809 
GetFrom() const810 uint32_t PasteDataRecord::GetFrom() const
811 {
812     return from_;
813 }
814 
GetEntryGetter()815 std::shared_ptr<UDMF::EntryGetter> PasteDataRecord::GetEntryGetter()
816 {
817     return entryGetter_;
818 }
819 } // namespace MiscServices
820 } // namespace OHOS
821