• 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_common.h"
17 #include "pasteboard_hilog.h"
18 #include "pasteboard_service_loader.h"
19 
20 using namespace OHOS::Media;
21 
22 namespace OHOS {
23 namespace MiscServices {
24 constexpr int MAX_TEXT_LEN = 100 * 1024 * 1024;
25 constexpr uid_t ANCO_SERVICE_BROKER_UID = 5557;
26 
SetMimeType(std::string mimeType)27 PasteDataRecord::Builder &PasteDataRecord::Builder::SetMimeType(std::string mimeType)
28 {
29     record_->mimeType_ = std::move(mimeType);
30     return *this;
31 }
32 enum TAG_PASTEBOARD_RECORD : uint16_t {
33     TAG_MIMETYPE = TAG_BUFF + 1,
34     TAG_HTMLTEXT,
35     TAG_WANT,
36     TAG_PLAINTEXT,
37     TAG_URI,
38     TAG_PIXELMAP,
39     TAG_CUSTOM_DATA,
40     TAG_CONVERT_URI,
41     TAG_URI_PERMISSION,
42     TAG_UDC_UDTYPE,
43     TAG_UDC_DETAILS,
44     TAG_UDC_TEXTCONTENT,
45     TAG_UDC_SYSTEMCONTENTS,
46     TAG_UDC_UDMFVALUE,
47     TAG_UDC_ENTRIES,
48     TAG_DATA_ID,
49     TAG_RECORD_ID,
50     TAG_DELAY_RECORD_FLAG,
51     TAG_FROM,
52 };
53 
SetHtmlText(std::shared_ptr<std::string> htmlText)54 PasteDataRecord::Builder &PasteDataRecord::Builder::SetHtmlText(std::shared_ptr<std::string> htmlText)
55 {
56     if (htmlText == nullptr) {
57         return *this;
58     }
59     auto entry = std::make_shared<PasteDataEntry>();
60     entry->SetValue(*htmlText);
61     record_->AddEntryByMimeType(MIMETYPE_TEXT_HTML, entry);
62     return *this;
63 }
64 
SetWant(std::shared_ptr<OHOS::AAFwk::Want> want)65 PasteDataRecord::Builder &PasteDataRecord::Builder::SetWant(std::shared_ptr<OHOS::AAFwk::Want> want)
66 {
67     if (want == nullptr) {
68         return *this;
69     }
70     auto entry = std::make_shared<PasteDataEntry>();
71     entry->SetValue(std::move(want));
72     record_->AddEntryByMimeType(MIMETYPE_TEXT_WANT, entry);
73     return *this;
74 }
75 
SetPlainText(std::shared_ptr<std::string> plainText)76 PasteDataRecord::Builder &PasteDataRecord::Builder::SetPlainText(std::shared_ptr<std::string> plainText)
77 {
78     if (plainText == nullptr) {
79         return *this;
80     }
81     auto entry = std::make_shared<PasteDataEntry>();
82     entry->SetValue(*plainText);
83     record_->AddEntryByMimeType(MIMETYPE_TEXT_PLAIN, entry);
84     return *this;
85 }
SetUri(std::shared_ptr<OHOS::Uri> uri)86 PasteDataRecord::Builder &PasteDataRecord::Builder::SetUri(std::shared_ptr<OHOS::Uri> uri)
87 {
88     if (uri == nullptr) {
89         return *this;
90     }
91     auto entry = std::make_shared<PasteDataEntry>();
92     entry->SetValue(uri->ToString());
93     record_->AddEntryByMimeType(MIMETYPE_TEXT_URI, entry);
94     return *this;
95 }
96 
SetPixelMap(std::shared_ptr<OHOS::Media::PixelMap> pixelMap)97 PasteDataRecord::Builder &PasteDataRecord::Builder::SetPixelMap(std::shared_ptr<OHOS::Media::PixelMap> pixelMap)
98 {
99     if (pixelMap == nullptr) {
100         return *this;
101     }
102     auto entry = std::make_shared<PasteDataEntry>();
103     entry->SetValue(std::move(pixelMap));
104     record_->AddEntryByMimeType(MIMETYPE_PIXELMAP, entry);
105     return *this;
106 }
107 
SetCustomData(std::shared_ptr<MineCustomData> customData)108 PasteDataRecord::Builder &PasteDataRecord::Builder::SetCustomData(std::shared_ptr<MineCustomData> customData)
109 {
110     record_->customData_ = std::move(customData);
111     return *this;
112 }
113 
Build()114 std::shared_ptr<PasteDataRecord> PasteDataRecord::Builder::Build()
115 {
116     if (record_->mimeType_.empty()) {
117         return record_;
118     }
119     auto entries = record_->GetEntries();
120     auto record = std::make_shared<PasteDataRecord>();
121     for (size_t i = 0; i < entries.size(); ++i) {
122         if (record_->mimeType_ == entries[i]->GetMimeType()) {
123             record->AddEntry(entries[i]->GetUtdId(), entries[i]);
124         }
125     }
126     for (size_t i = 0; i < entries.size(); ++i) {
127         if (record_->mimeType_ != entries[i]->GetMimeType()) {
128             record->AddEntry(entries[i]->GetUtdId(), entries[i]);
129         }
130     }
131     record->customData_ = std::move(record_->customData_);
132     record->mimeType_ = record_->mimeType_;
133     return record;
134 }
135 
Builder(const std::string & mimeType)136 PasteDataRecord::Builder::Builder(const std::string &mimeType)
137 {
138     record_ = std::make_shared<PasteDataRecord>();
139     if (record_ != nullptr) {
140         record_->mimeType_ = mimeType;
141         record_->htmlText_ = nullptr;
142         record_->want_ = nullptr;
143         record_->plainText_ = nullptr;
144         record_->uri_ = nullptr;
145         record_->convertUri_ = "";
146         record_->pixelMap_ = nullptr;
147         record_->customData_ = nullptr;
148     }
149 }
150 
AddUriEntry()151 void PasteDataRecord::AddUriEntry()
152 {
153     auto object = std::make_shared<Object>();
154     object->value_[UDMF::UNIFORM_DATA_TYPE] = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::FILE_URI);
155     if (uri_ != nullptr) {
156         object->value_[UDMF::FILE_URI_PARAM] = uri_->ToString();
157     }
158     auto utdId = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::FILE_URI);
159     AddEntry(utdId, std::make_shared<PasteDataEntry>(utdId, object));
160 }
161 
NewHtmlRecord(const std::string & htmlText)162 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewHtmlRecord(const std::string &htmlText)
163 {
164     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE((htmlText.length() < MAX_TEXT_LEN), nullptr,
165         PASTEBOARD_MODULE_CLIENT, "record length not support, length=%{public}zu", htmlText.length());
166     return Builder(MIMETYPE_TEXT_HTML).SetHtmlText(std::make_shared<std::string>(htmlText)).Build();
167 }
168 
NewWantRecord(std::shared_ptr<OHOS::AAFwk::Want> want)169 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewWantRecord(std::shared_ptr<OHOS::AAFwk::Want> want)
170 {
171     return Builder(MIMETYPE_TEXT_WANT).SetWant(std::move(want)).Build();
172 }
173 
NewPlainTextRecord(const std::string & text)174 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewPlainTextRecord(const std::string &text)
175 {
176     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE((text.length() < MAX_TEXT_LEN), nullptr,
177         PASTEBOARD_MODULE_CLIENT, "PlainText length not support, length=%{public}zu", text.length());
178     return Builder(MIMETYPE_TEXT_PLAIN).SetPlainText(std::make_shared<std::string>(text)).Build();
179 }
180 
NewPixelMapRecord(std::shared_ptr<PixelMap> pixelMap)181 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewPixelMapRecord(std::shared_ptr<PixelMap> pixelMap)
182 {
183     return Builder(MIMETYPE_PIXELMAP).SetPixelMap(std::move(pixelMap)).Build();
184 }
185 
NewUriRecord(const OHOS::Uri & uri)186 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewUriRecord(const OHOS::Uri &uri)
187 {
188     return Builder(MIMETYPE_TEXT_URI).SetUri(std::make_shared<OHOS::Uri>(uri)).Build();
189 }
190 
NewKvRecord(const std::string & mimeType,const std::vector<uint8_t> & arrayBuffer)191 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewKvRecord(
192     const std::string &mimeType, const std::vector<uint8_t> &arrayBuffer)
193 {
194     std::shared_ptr<MineCustomData> customData = std::make_shared<MineCustomData>();
195     customData->AddItemData(mimeType, arrayBuffer);
196     return Builder(mimeType).SetCustomData(std::move(customData)).Build();
197 }
198 
NewMultiTypeRecord(std::shared_ptr<std::map<std::string,std::shared_ptr<EntryValue>>> values,const std::string & recordMimeType)199 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewMultiTypeRecord(
200     std::shared_ptr<std::map<std::string, std::shared_ptr<EntryValue>>> values, const std::string &recordMimeType)
201 {
202     auto record = std::make_shared<PasteDataRecord>();
203     if (values == nullptr) {
204         return record;
205     }
206     if (!recordMimeType.empty()) {
207         auto recordDefaultIter = values->find(recordMimeType);
208         if (recordDefaultIter != values->end() && recordDefaultIter->second != nullptr) {
209             auto utdId = CommonUtils::Convert2UtdId(UDMF::UDType::UD_BUTT, recordMimeType);
210             record->AddEntry(utdId, std::make_shared<PasteDataEntry>(utdId, *(recordDefaultIter->second)));
211         }
212     }
213     for (auto [mimeType, value] : *values) {
214         if (mimeType == recordMimeType) {
215             continue;
216         }
217         auto utdId = CommonUtils::Convert2UtdId(UDMF::UDType::UD_BUTT, mimeType);
218         record->AddEntry(utdId, std::make_shared<PasteDataEntry>(utdId, *value));
219     }
220     return record;
221 }
222 
NewMultiTypeDelayRecord(std::vector<std::string> mimeTypes,const std::shared_ptr<UDMF::EntryGetter> entryGetter)223 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewMultiTypeDelayRecord(
224     std::vector<std::string> mimeTypes, const std::shared_ptr<UDMF::EntryGetter> entryGetter)
225 {
226     auto record = std::make_shared<PasteDataRecord>();
227     for (auto mimeType : mimeTypes) {
228         auto utdId = CommonUtils::Convert2UtdId(UDMF::UDType::UD_BUTT, mimeType);
229         auto entry = std::make_shared<PasteDataEntry>();
230         entry->SetMimeType(mimeType);
231         entry->SetUtdId(utdId);
232         record->AddEntry(utdId, entry);
233     }
234     if (entryGetter != nullptr) {
235         record->SetEntryGetter(entryGetter);
236         record->SetDelayRecordFlag(true);
237     }
238     return record;
239 }
240 
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)241 PasteDataRecord::PasteDataRecord(std::string mimeType, std::shared_ptr<std::string> htmlText,
242     std::shared_ptr<OHOS::AAFwk::Want> want, std::shared_ptr<std::string> plainText, std::shared_ptr<OHOS::Uri> uri)
243     : mimeType_{ std::move(mimeType) }, htmlText_{ std::move(htmlText) }, want_{ std::move(want) },
244       plainText_{ std::move(plainText) }, uri_{ std::move(uri) }
245 {
246 }
247 
PasteDataRecord()248 PasteDataRecord::PasteDataRecord()
249 {
250 }
251 
~PasteDataRecord()252 PasteDataRecord::~PasteDataRecord()
253 {
254     std::vector<std::shared_ptr<PasteDataEntry>>().swap(entries_);
255 }
256 
PasteDataRecord(const PasteDataRecord & record)257 PasteDataRecord::PasteDataRecord(const PasteDataRecord &record)
258     : isDelay_(record.isDelay_), hasGrantUriPermission_(record.hasGrantUriPermission_), udType_(record.udType_),
259       dataId_(record.dataId_), recordId_(record.recordId_), from_(record.from_), convertUri_(record.convertUri_),
260       textContent_(record.textContent_), mimeType_(record.mimeType_), htmlText_(record.htmlText_),
261       want_(record.want_), plainText_(record.plainText_), uri_(record.uri_), pixelMap_(record.pixelMap_),
262       customData_(record.customData_), details_(record.details_), systemDefinedContents_(record.systemDefinedContents_),
263       udmfValue_(record.udmfValue_), entries_(record.entries_), entryGetter_(record.entryGetter_)
264 {
265     this->isConvertUriFromRemote = record.isConvertUriFromRemote;
266 }
267 
GetHtmlTextV0() const268 std::shared_ptr<std::string> PasteDataRecord::GetHtmlTextV0() const
269 {
270     for (const auto &entry : entries_) {
271         if (entry && entry->GetMimeType() == MIMETYPE_TEXT_HTML) {
272             return entry->ConvertToHtml();
273         }
274     }
275     return htmlText_;
276 }
277 
GetHtmlText()278 std::shared_ptr<std::string> PasteDataRecord::GetHtmlText()
279 {
280     auto htmlText = GetHtmlTextV0();
281     if (htmlText) {
282         return htmlText;
283     }
284     auto entry = GetEntryByMimeType(MIMETYPE_TEXT_HTML);
285     if (entry == nullptr) {
286         return htmlText_;
287     }
288     return entry->ConvertToHtml();
289 }
290 
GetMimeType() const291 std::string PasteDataRecord::GetMimeType() const
292 {
293     if (!mimeType_.empty()) {
294         return mimeType_;
295     }
296     if (!entries_.empty()) {
297         return entries_.front()->GetMimeType();
298     }
299     return this->mimeType_;
300 }
301 
GetPlainTextV0() const302 std::shared_ptr<std::string> PasteDataRecord::GetPlainTextV0() const
303 {
304     for (const auto &entry : entries_) {
305         if (entry && entry->GetMimeType() == MIMETYPE_TEXT_PLAIN) {
306             return entry->ConvertToPlainText();
307         }
308     }
309     return plainText_;
310 }
311 
GetPlainText()312 std::shared_ptr<std::string> PasteDataRecord::GetPlainText()
313 {
314     auto plainText = GetPlainTextV0();
315     if (plainText) {
316         return plainText;
317     }
318     auto entry = GetEntryByMimeType(MIMETYPE_TEXT_PLAIN);
319     if (entry == nullptr) {
320         return plainText_;
321     }
322     return entry->ConvertToPlainText();
323 }
324 
GetPixelMapV0() const325 std::shared_ptr<PixelMap> PasteDataRecord::GetPixelMapV0() const
326 {
327     for (const auto &entry : entries_) {
328         if (entry && entry->GetMimeType() == MIMETYPE_PIXELMAP) {
329             return entry->ConvertToPixelMap();
330         }
331     }
332     return pixelMap_;
333 }
334 
GetPixelMap()335 std::shared_ptr<PixelMap> PasteDataRecord::GetPixelMap()
336 {
337     auto pixelMap = GetPixelMapV0();
338     if (pixelMap) {
339         return pixelMap;
340     }
341     auto entry = GetEntryByMimeType(MIMETYPE_PIXELMAP);
342     if (entry == nullptr) {
343         return pixelMap_;
344     }
345     return entry->ConvertToPixelMap();
346 }
347 
GetUriV0() const348 std::shared_ptr<OHOS::Uri> PasteDataRecord::GetUriV0() const
349 {
350     if (convertUri_.empty()) {
351         return GetOriginUri();
352     }
353     return std::make_shared<OHOS::Uri>(convertUri_);
354 }
355 
GetUri()356 std::shared_ptr<OHOS::Uri> PasteDataRecord::GetUri()
357 {
358     auto uri = GetUriV0();
359     if (uri) {
360         return uri;
361     }
362     auto entry = GetEntryByMimeType(MIMETYPE_TEXT_URI);
363     if (entry == nullptr) {
364         return GetUriV0();
365     }
366     return entry->ConvertToUri();
367 }
368 
ClearPixelMap()369 void PasteDataRecord::ClearPixelMap()
370 {
371     this->pixelMap_ = nullptr;
372     entries_.erase(std::remove_if(entries_.begin(), entries_.end(),
373         [](const auto &entry) {
374             return entry != nullptr && entry->GetMimeType() == MIMETYPE_PIXELMAP;
375         }), entries_.end());
376 }
377 
SetUri(std::shared_ptr<OHOS::Uri> uri)378 void PasteDataRecord::SetUri(std::shared_ptr<OHOS::Uri> uri)
379 {
380     if (uri == nullptr) {
381         return;
382     }
383 
384     for (auto &entry : entries_) {
385         if (entry != nullptr && entry->GetMimeType() == MIMETYPE_TEXT_URI) {
386             auto entryValue = entry->GetValue();
387             if (std::holds_alternative<std::shared_ptr<Object>>(entryValue)) {
388                 auto object = std::get<std::shared_ptr<Object>>(entryValue);
389                 object->value_[UDMF::FILE_URI_PARAM] = uri->ToString();
390             } else {
391                 entry->SetValue(uri->ToString());
392             }
393             return;
394         }
395     }
396 
397     auto entry = std::make_shared<PasteDataEntry>();
398     entry->SetValue(uri->ToString());
399     AddEntryByMimeType(MIMETYPE_TEXT_URI, entry);
400 }
401 
GetOriginUri() const402 std::shared_ptr<OHOS::Uri> PasteDataRecord::GetOriginUri() const
403 {
404     for (const auto &entry : entries_) {
405         if (entry && entry->GetMimeType() == MIMETYPE_TEXT_URI) {
406             return entry->ConvertToUri();
407         }
408     }
409     return uri_;
410 }
411 
GetWant() const412 std::shared_ptr<OHOS::AAFwk::Want> PasteDataRecord::GetWant() const
413 {
414     for (const auto &entry : entries_) {
415         if (entry && entry->GetMimeType() == MIMETYPE_TEXT_WANT) {
416             return entry->ConvertToWant();
417         }
418     }
419     return want_;
420 }
421 
GetCustomData() const422 std::shared_ptr<MineCustomData> PasteDataRecord::GetCustomData() const
423 {
424     std::shared_ptr<MineCustomData> customData = std::make_shared<MineCustomData>();
425     if (customData_) {
426         const std::map<std::string, std::vector<uint8_t>> &itemData = customData_->GetItemData();
427         for (const auto &[key, value] : itemData) {
428             customData->AddItemData(key, value);
429         }
430     }
431     for (const auto &entry : entries_) {
432         if (entry && entry->GetMimeType() == entry->GetUtdId()) {
433             std::shared_ptr<MineCustomData> entryCustomData = entry->ConvertToCustomData();
434             if (entryCustomData == nullptr) {
435                 continue;
436             }
437             const std::map<std::string, std::vector<uint8_t>> &itemData = entryCustomData->GetItemData();
438             for (const auto &[key, value] : itemData) {
439                 customData->AddItemData(key, value);
440             }
441         }
442     }
443     return customData->GetItemData().empty() ? nullptr : customData;
444 }
445 
ConvertToText() const446 std::string PasteDataRecord::ConvertToText() const
447 {
448     auto htmlText = GetHtmlTextV0();
449     if (htmlText != nullptr) {
450         return *htmlText;
451     }
452     auto plainText = GetPlainTextV0();
453     if (plainText != nullptr) {
454         return *plainText;
455     }
456     auto originUri = GetOriginUri();
457     if (originUri != nullptr) {
458         return originUri->ToString();
459     }
460     return "";
461 }
462 
EncodeTLVLocal(WriteOnlyBuffer & buffer) const463 bool PasteDataRecord::EncodeTLVLocal(WriteOnlyBuffer &buffer) const
464 {
465     bool ret = buffer.Write(TAG_MIMETYPE, mimeType_);
466     ret = ret && buffer.Write(TAG_HTMLTEXT, htmlText_);
467     ret = ret && buffer.Write(TAG_WANT, TLVUtils::Parcelable2Raw(want_.get()));
468     ret = ret && buffer.Write(TAG_PLAINTEXT, plainText_);
469     ret = ret && buffer.Write(TAG_URI, TLVUtils::Parcelable2Raw(uri_.get()));
470     ret = ret && buffer.Write(TAG_CONVERT_URI, convertUri_);
471     ret = ret && buffer.Write(TAG_PIXELMAP, pixelMap_);
472     ret = ret && buffer.Write(TAG_CUSTOM_DATA, customData_);
473     ret = ret && buffer.Write(TAG_URI_PERMISSION, hasGrantUriPermission_);
474     ret = ret && buffer.Write(TAG_UDC_UDTYPE, udType_);
475     ret = ret && buffer.Write(TAG_UDC_DETAILS, details_);
476     ret = ret && buffer.Write(TAG_UDC_TEXTCONTENT, textContent_);
477     ret = ret && buffer.Write(TAG_UDC_SYSTEMCONTENTS, systemDefinedContents_);
478     ret = ret && buffer.Write(TAG_UDC_UDMFVALUE, udmfValue_);
479     ret = ret && buffer.Write(TAG_UDC_ENTRIES, entries_);
480     ret = ret && buffer.Write(TAG_DATA_ID, dataId_);
481     ret = ret && buffer.Write(TAG_RECORD_ID, recordId_);
482     ret = ret && buffer.Write(TAG_DELAY_RECORD_FLAG, isDelay_);
483     ret = ret && buffer.Write(TAG_FROM, from_);
484     return ret;
485 }
486 
EncodeTLVRemote(WriteOnlyBuffer & buffer) const487 bool PasteDataRecord::EncodeTLVRemote(WriteOnlyBuffer &buffer) const
488 {
489     bool ret = true;
490 
491     auto remoteValue = Local2Remote();
492     if (remoteValue != nullptr) {
493         ret = ret && buffer.Write(TAG_MIMETYPE, remoteValue->mimeType_);
494         ret = ret && buffer.Write(TAG_UDC_UDTYPE, remoteValue->udType_);
495         ret = ret && buffer.Write(TAG_HTMLTEXT, remoteValue->htmlText_);
496         ret = ret && buffer.Write(TAG_PLAINTEXT, remoteValue->plainText_);
497         ret = ret && buffer.Write(TAG_PIXELMAP, remoteValue->pixelMap_);
498         ret = ret && buffer.Write(TAG_WANT, TLVUtils::Parcelable2Raw(remoteValue->want_.get()));
499         ret = ret && buffer.Write(TAG_URI, TLVUtils::Parcelable2Raw(remoteValue->uri_.get()));
500         ret = ret && buffer.Write(TAG_UDC_UDMFVALUE, remoteValue->udmfValue_);
501         ret = ret && buffer.Write(TAG_UDC_ENTRIES, remoteValue->entries_);
502     }
503 
504     ret = ret && buffer.Write(TAG_CONVERT_URI, convertUri_);
505     ret = ret && buffer.Write(TAG_CUSTOM_DATA, customData_);
506     ret = ret && buffer.Write(TAG_URI_PERMISSION, hasGrantUriPermission_);
507     ret = ret && buffer.Write(TAG_UDC_DETAILS, details_);
508     ret = ret && buffer.Write(TAG_UDC_TEXTCONTENT, textContent_);
509     ret = ret && buffer.Write(TAG_UDC_SYSTEMCONTENTS, systemDefinedContents_);
510     ret = ret && buffer.Write(TAG_DATA_ID, dataId_);
511     ret = ret && buffer.Write(TAG_RECORD_ID, recordId_);
512     ret = ret && buffer.Write(TAG_DELAY_RECORD_FLAG, isDelay_);
513     ret = ret && buffer.Write(TAG_FROM, from_);
514     return ret;
515 }
516 
EncodeTLV(WriteOnlyBuffer & buffer) const517 bool PasteDataRecord::EncodeTLV(WriteOnlyBuffer &buffer) const
518 {
519     return IsRemoteEncode() ? EncodeTLVRemote(buffer) : EncodeTLVLocal(buffer);
520 }
521 
DecodeItem1(uint16_t tag,ReadOnlyBuffer & buffer,TLVHead & head)522 bool PasteDataRecord::DecodeItem1(uint16_t tag, ReadOnlyBuffer &buffer, TLVHead &head)
523 {
524     switch (tag) {
525         case TAG_MIMETYPE:
526             return buffer.ReadValue(mimeType_, head);
527         case TAG_HTMLTEXT:
528             return buffer.ReadValue(htmlText_, head);
529         case TAG_WANT:
530             return buffer.ReadValue(want_, head);
531         case TAG_PLAINTEXT:
532             return buffer.ReadValue(plainText_, head);
533         case TAG_URI:
534             return buffer.ReadValue(uri_, head);
535         case TAG_CONVERT_URI:
536             return buffer.ReadValue(convertUri_, head);
537         case TAG_PIXELMAP:
538             return buffer.ReadValue(pixelMap_, head);
539         case TAG_CUSTOM_DATA:
540             return buffer.ReadValue(customData_, head);
541         case TAG_URI_PERMISSION:
542             return buffer.ReadValue(hasGrantUriPermission_, head);
543         default:
544             return DecodeItem2(tag, buffer, head);
545     }
546 }
547 
DecodeItem2(uint16_t tag,ReadOnlyBuffer & buffer,TLVHead & head)548 bool PasteDataRecord::DecodeItem2(uint16_t tag, ReadOnlyBuffer &buffer, TLVHead &head)
549 {
550     switch (tag) {
551         case TAG_UDC_UDTYPE:
552             return buffer.ReadValue(udType_, head);
553         case TAG_UDC_DETAILS:
554             return buffer.ReadValue(details_, head);
555         case TAG_UDC_TEXTCONTENT:
556             return buffer.ReadValue(textContent_, head);
557         case TAG_UDC_SYSTEMCONTENTS:
558             return buffer.ReadValue(systemDefinedContents_, head);
559         case TAG_UDC_UDMFVALUE:
560             return buffer.ReadValue(udmfValue_, head);
561         case TAG_UDC_ENTRIES:
562             return buffer.ReadValue(entries_, head);
563         case TAG_DATA_ID:
564             return buffer.ReadValue(dataId_, head);
565         case TAG_RECORD_ID:
566             return buffer.ReadValue(recordId_, head);
567         case TAG_DELAY_RECORD_FLAG:
568             return buffer.ReadValue(isDelay_, head);
569         case TAG_FROM:
570             return buffer.ReadValue(from_, head);
571         default:
572             return buffer.Skip(head.len);
573     }
574 }
575 
DecodeTLV(ReadOnlyBuffer & buffer)576 bool PasteDataRecord::DecodeTLV(ReadOnlyBuffer &buffer)
577 {
578     for (; buffer.IsEnough();) {
579         TLVHead head{};
580         bool ret = buffer.ReadHead(head);
581         PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret, false, PASTEBOARD_MODULE_COMMON, "read head failed");
582         ret = DecodeItem1(head.tag, buffer, head);
583         PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret, false, PASTEBOARD_MODULE_COMMON,
584             "read value failed, tag=%{public}hu, len=%{public}u", head.tag, head.len);
585     }
586 
587     auto entry = Remote2Local();
588     if (entry != nullptr) {
589         entries_.insert(entries_.begin(), std::move(entry));
590     }
591     udmfValue_ = nullptr;
592     plainText_ = (getuid() == ANCO_SERVICE_BROKER_UID) ? GetPlainTextV0() : nullptr;
593     htmlText_ = nullptr;
594     pixelMap_ = nullptr;
595     want_ = nullptr;
596     uri_ = nullptr;
597     return true;
598 }
599 
CountTLVLocal() const600 size_t PasteDataRecord::CountTLVLocal() const
601 {
602     size_t expectedSize = 0;
603     expectedSize += TLVCountable::Count(mimeType_);
604     expectedSize += TLVCountable::Count(htmlText_);
605     expectedSize += TLVCountable::Count(TLVUtils::Parcelable2Raw(want_.get()));
606     expectedSize += TLVCountable::Count(plainText_);
607     expectedSize += TLVCountable::Count(TLVUtils::Parcelable2Raw(uri_.get()));
608     expectedSize += TLVCountable::Count(convertUri_);
609     expectedSize += TLVCountable::Count(pixelMap_);
610     expectedSize += TLVCountable::Count(customData_);
611     expectedSize += TLVCountable::Count(hasGrantUriPermission_);
612     expectedSize += TLVCountable::Count(udType_);
613     expectedSize += TLVCountable::Count(details_);
614     expectedSize += TLVCountable::Count(textContent_);
615     expectedSize += TLVCountable::Count(systemDefinedContents_);
616     expectedSize += TLVCountable::Count(udmfValue_);
617     expectedSize += TLVCountable::Count(entries_);
618     expectedSize += TLVCountable::Count(dataId_);
619     expectedSize += TLVCountable::Count(recordId_);
620     expectedSize += TLVCountable::Count(isDelay_);
621     expectedSize += TLVCountable::Count(from_);
622     return expectedSize;
623 }
624 
CountTLVRemote() const625 size_t PasteDataRecord::CountTLVRemote() const
626 {
627     size_t expectedSize = 0;
628     auto remoteValue = Local2Remote();
629     if (remoteValue != nullptr) {
630         expectedSize += TLVCountable::Count(remoteValue->mimeType_);
631         expectedSize += TLVCountable::Count(remoteValue->udType_);
632         expectedSize += TLVCountable::Count(remoteValue->htmlText_);
633         expectedSize += TLVCountable::Count(remoteValue->plainText_);
634         expectedSize += TLVCountable::Count(remoteValue->pixelMap_);
635         expectedSize += TLVCountable::Count(TLVUtils::Parcelable2Raw(remoteValue->want_.get()));
636         expectedSize += TLVCountable::Count(TLVUtils::Parcelable2Raw(remoteValue->uri_.get()));
637         expectedSize += TLVCountable::Count(remoteValue->udmfValue_);
638         expectedSize += TLVCountable::Count(remoteValue->entries_);
639     }
640 
641     expectedSize += TLVCountable::Count(convertUri_);
642     expectedSize += TLVCountable::Count(customData_);
643     expectedSize += TLVCountable::Count(hasGrantUriPermission_);
644     expectedSize += TLVCountable::Count(details_);
645     expectedSize += TLVCountable::Count(textContent_);
646     expectedSize += TLVCountable::Count(systemDefinedContents_);
647     expectedSize += TLVCountable::Count(dataId_);
648     expectedSize += TLVCountable::Count(recordId_);
649     expectedSize += TLVCountable::Count(isDelay_);
650     expectedSize += TLVCountable::Count(from_);
651     return expectedSize;
652 }
653 
CountTLV() const654 size_t PasteDataRecord::CountTLV() const
655 {
656     return IsRemoteEncode() ? CountTLVRemote() : CountTLVLocal();
657 }
658 
Remote2Local() const659 std::shared_ptr<PasteDataEntry> PasteDataRecord::Remote2Local() const
660 {
661     PASTEBOARD_CHECK_AND_RETURN_RET_LOGD(!mimeType_.empty(), nullptr, PASTEBOARD_MODULE_COMMON, "mimeType empty");
662 
663     auto entry = std::make_shared<PasteDataEntry>();
664     auto utdId = CommonUtils::Convert2UtdId(udType_, mimeType_);
665     entry->SetUtdId(utdId);
666     entry->SetMimeType(mimeType_);
667 
668     if (udmfValue_ != nullptr) {
669         if (std::holds_alternative<std::shared_ptr<Object>>(*udmfValue_)) {
670             auto object = std::get<std::shared_ptr<Object>>(*udmfValue_);
671             if (object != nullptr && !object->value_.empty()) {
672                 entry->SetValue(object);
673                 return entry;
674             }
675         } else if (std::holds_alternative<std::vector<uint8_t>>(*udmfValue_)) {
676             auto array = std::get<std::vector<uint8_t>>(*udmfValue_);
677             entry->SetValue(array);
678             return entry;
679         }
680     }
681 
682     auto object = std::make_shared<Object>();
683     if (mimeType_ == MIMETYPE_TEXT_PLAIN && plainText_ != nullptr) {
684         object->value_[UDMF::UNIFORM_DATA_TYPE] = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::PLAIN_TEXT);
685         object->value_[UDMF::CONTENT] = *plainText_;
686     } else if (mimeType_ == MIMETYPE_TEXT_HTML && htmlText_ != nullptr) {
687         object->value_[UDMF::UNIFORM_DATA_TYPE] = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::HTML);
688         object->value_[UDMF::HTML_CONTENT] = *htmlText_;
689         if (plainText_ != nullptr) {
690             object->value_[UDMF::PLAIN_CONTENT] = *plainText_;
691         }
692     } else if (mimeType_ == MIMETYPE_TEXT_URI && uri_ != nullptr) {
693         object->value_[UDMF::UNIFORM_DATA_TYPE] = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::FILE_URI);
694         object->value_[UDMF::FILE_URI_PARAM] = uri_->ToString();
695     } else if (mimeType_ == MIMETYPE_PIXELMAP && pixelMap_ != nullptr) {
696         object->value_[UDMF::UNIFORM_DATA_TYPE] = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::SYSTEM_DEFINED_PIXEL_MAP);
697         object->value_[UDMF::PIXEL_MAP] = std::move(pixelMap_);
698     } else if (mimeType_ == MIMETYPE_TEXT_WANT && want_ != nullptr) {
699         entry->SetValue(std::move(want_));
700         return entry;
701     } else {
702         return nullptr;
703     }
704 
705     entry->SetValue(object);
706     return entry;
707 }
708 
Local2Remote() const709 std::shared_ptr<RemoteRecordValue> PasteDataRecord::Local2Remote() const
710 {
711     auto value = std::make_shared<RemoteRecordValue>();
712     value->mimeType_ = mimeType_;
713     if (entries_.empty()) {
714         return value;
715     }
716 
717     auto firstEntry = entries_.front();
718     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(firstEntry != nullptr, value, PASTEBOARD_MODULE_COMMON, "firstEntry is null");
719 
720     auto entryValue = firstEntry->GetValue();
721     std::string mimeType = firstEntry->GetMimeType();
722     std::string utdId = firstEntry->GetUtdId();
723     value->udType_ = UDMF::UtdUtils::GetUtdEnumFromUtdId(utdId);
724     value->mimeType_ = mimeType;
725 
726     if (mimeType == MIMETYPE_TEXT_PLAIN) {
727         value->plainText_ = firstEntry->ConvertToPlainText();
728     } else if (mimeType == MIMETYPE_TEXT_WANT) {
729         value->want_ = firstEntry->ConvertToWant();
730     } else if (mimeType == MIMETYPE_TEXT_URI) {
731         value->uri_ = firstEntry->ConvertToUri();
732     } else if (mimeType == MIMETYPE_PIXELMAP) {
733         value->pixelMap_ = firstEntry->ConvertToPixelMap();
734     } else if (mimeType == MIMETYPE_TEXT_HTML) {
735         value->htmlText_ = firstEntry->ConvertToHtml();
736         if (std::holds_alternative<std::shared_ptr<Object>>(entryValue)) {
737             auto object = std::get<std::shared_ptr<Object>>(entryValue);
738             std::string plainText;
739             object->GetValue(UDMF::PLAIN_CONTENT, plainText);
740             if (!plainText.empty()) {
741                 value->plainText_ = std::make_shared<std::string>(plainText);
742             }
743         }
744     }
745 
746     value->udmfValue_ = entryValue;
747     value->entries_.assign(entries_.begin() + 1, entries_.end());
748     return value;
749 }
750 
GetPassUri()751 std::string PasteDataRecord::GetPassUri()
752 {
753     std::string tempUri;
754     if (uri_ != nullptr) {
755         tempUri = uri_->ToString();
756     }
757     if (!convertUri_.empty()) {
758         tempUri = convertUri_;
759     }
760     return tempUri;
761 }
762 
SetConvertUri(const std::string & value)763 void PasteDataRecord::SetConvertUri(const std::string &value)
764 {
765     convertUri_ = value;
766 }
767 
GetConvertUri() const768 std::string PasteDataRecord::GetConvertUri() const
769 {
770     return convertUri_;
771 }
772 
SetGrantUriPermission(bool hasPermission)773 void PasteDataRecord::SetGrantUriPermission(bool hasPermission)
774 {
775     hasGrantUriPermission_ = hasPermission;
776 }
777 
HasGrantUriPermission()778 bool PasteDataRecord::HasGrantUriPermission()
779 {
780     return hasGrantUriPermission_;
781 }
782 
SetTextContent(const std::string & content)783 void PasteDataRecord::SetTextContent(const std::string &content)
784 {
785     this->textContent_ = content;
786 }
787 
GetTextContent() const788 std::string PasteDataRecord::GetTextContent() const
789 {
790     return this->textContent_;
791 }
792 
SetDetails(const Details & details)793 void PasteDataRecord::SetDetails(const Details &details)
794 {
795     this->details_ = std::make_shared<Details>(details);
796 }
797 
GetDetails() const798 std::shared_ptr<Details> PasteDataRecord::GetDetails() const
799 {
800     return this->details_;
801 }
802 
SetSystemDefinedContent(const Details & contents)803 void PasteDataRecord::SetSystemDefinedContent(const Details &contents)
804 {
805     this->systemDefinedContents_ = std::make_shared<Details>(contents);
806 }
807 
GetSystemDefinedContent() const808 std::shared_ptr<Details> PasteDataRecord::GetSystemDefinedContent() const
809 {
810     return this->systemDefinedContents_;
811 }
812 
GetUDType() const813 int32_t PasteDataRecord::GetUDType() const
814 {
815     return this->udType_;
816 }
817 
SetUDType(int32_t type)818 void PasteDataRecord::SetUDType(int32_t type)
819 {
820     this->udType_ = type;
821 }
822 
GetValidMimeTypes(const std::vector<std::string> & mimeTypes) const823 std::vector<std::string> PasteDataRecord::GetValidMimeTypes(const std::vector<std::string> &mimeTypes) const
824 {
825     std::vector<std::string> res;
826     auto allTypes = GetMimeTypes();
827     for (auto const& type : mimeTypes) {
828         if (allTypes.find(type) != allTypes.end()) {
829             res.emplace_back(type);
830         }
831     }
832     return res;
833 }
834 
GetValidTypes(const std::vector<std::string> & types) const835 std::vector<std::string> PasteDataRecord::GetValidTypes(const std::vector<std::string> &types) const
836 {
837     std::vector<std::string> res;
838     auto allTypes = GetUdtTypes();
839     for (auto const &type : types) {
840         if (allTypes.find(type) != allTypes.end()) {
841             res.emplace_back(type);
842         }
843     }
844     return res;
845 }
846 
HasEmptyEntry() const847 bool PasteDataRecord::HasEmptyEntry() const
848 {
849     for (auto const &entry : GetEntries()) {
850         if (std::holds_alternative<std::monostate>(entry->GetValue())) {
851             return true;
852         }
853     }
854     return false;
855 }
856 
GetUdtTypes() const857 std::set<std::string> PasteDataRecord::GetUdtTypes() const
858 {
859     std::set<std::string> types;
860     if (!mimeType_.empty()) {
861         types.emplace(CommonUtils::Convert2UtdId(udType_, mimeType_));
862     }
863     for (auto const &entry : entries_) {
864         types.emplace(entry->GetUtdId());
865     }
866     return types;
867 }
868 
GetMimeTypes() const869 std::set<std::string> PasteDataRecord::GetMimeTypes() const
870 {
871     std::set<std::string> types;
872     if (!mimeType_.empty()) {
873         types.emplace(mimeType_);
874     }
875     for (auto const& entry: entries_) {
876         types.emplace(entry->GetMimeType());
877     }
878     return types;
879 }
880 
AddEntryByMimeType(const std::string & mimeType,std::shared_ptr<PasteDataEntry> value)881 void PasteDataRecord::AddEntryByMimeType(const std::string &mimeType, std::shared_ptr<PasteDataEntry> value)
882 {
883     PASTEBOARD_CHECK_AND_RETURN_LOGE(value != nullptr, PASTEBOARD_MODULE_CLIENT, "value is null");
884     auto utdId = CommonUtils::Convert2UtdId(UDMF::UDType::UD_BUTT, mimeType);
885     value->SetUtdId(utdId);
886     value->SetMimeType(mimeType);
887     AddEntry(utdId, value);
888 }
889 
AddEntry(const std::string & utdType,std::shared_ptr<PasteDataEntry> value)890 void PasteDataRecord::AddEntry(const std::string &utdType, std::shared_ptr<PasteDataEntry> value)
891 {
892     PASTEBOARD_CHECK_AND_RETURN_LOGE(value != nullptr, PASTEBOARD_MODULE_CLIENT, "Entry value is null");
893     if (utdType != value->GetUtdId()) {
894         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Type is diff, UtdType:%{public}s, UtdId:%{public}s",
895             utdType.c_str(), value->GetUtdId().c_str());
896         return;
897     }
898 
899     bool has = false;
900     for (auto &entry : entries_) {
901         if (entry->GetUtdId() == utdType ||
902             (entry->GetMimeType() == MIMETYPE_TEXT_URI && value->GetMimeType() == MIMETYPE_TEXT_URI)) {
903             entry = value;
904             has = true;
905             break;
906         }
907     }
908 
909     PASTEBOARD_CHECK_AND_RETURN_LOGD(!has, PASTEBOARD_MODULE_COMMON, "replace entry, type=%{public}s", utdType.c_str());
910     if (entries_.empty()) {
911         auto udType = UDMF::UtdUtils::GetUtdEnumFromUtdId(utdType);
912         udType_ = udType == UDMF::UDType::UD_BUTT ? UDMF::UDType::APPLICATION_DEFINED_RECORD : udType;
913     }
914     entries_.emplace_back(value);
915 }
916 
GetEntryByMimeType(const std::string & mimeType)917 std::shared_ptr<PasteDataEntry> PasteDataRecord::GetEntryByMimeType(const std::string &mimeType)
918 {
919     auto utdId = CommonUtils::Convert2UtdId(UDMF::UDType::UD_BUTT, mimeType);
920     std::shared_ptr<PasteDataEntry> entry = GetEntry(utdId);
921     if (entry == nullptr && customData_ != nullptr) {
922         const std::map<std::string, std::vector<uint8_t>> &itemData = customData_->GetItemData();
923         for (const auto &[key, value] : itemData) {
924             if (mimeType == key) {
925                 entry = std::make_shared<PasteDataEntry>(utdId, mimeType, value);
926                 return entry;
927             }
928         }
929     }
930     if (entry == nullptr && mimeType == MIMETYPE_TEXT_PLAIN) {
931         utdId = CommonUtils::Convert2UtdId(UDMF::UDType::HYPERLINK, mimeType);
932         entry = GetEntry(utdId);
933     }
934     return entry;
935 }
936 
GetEntry(const std::string & utdType)937 std::shared_ptr<PasteDataEntry> PasteDataRecord::GetEntry(const std::string &utdType)
938 {
939     for (auto const &entry : entries_) {
940         if (entry->GetUtdId() == utdType ||
941             (CommonUtils::IsFileUri(utdType) && CommonUtils::IsFileUri(entry->GetUtdId()))) {
942             if (isDelay_ && !entry->HasContent(utdType) && !PasteBoardCommon::IsPasteboardService()) {
943                 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "get delay entry value, dataId=%{public}u, "
944                     "recordId=%{public}u, type=%{public}s", dataId_, recordId_, utdType.c_str());
945                 PasteboardServiceLoader::GetInstance().GetRecordValueByType(dataId_, recordId_, *entry);
946             }
947             if (CommonUtils::IsFileUri(utdType) && GetUriV0() != nullptr) {
948                 return std::make_shared<PasteDataEntry>(utdType, GetUriV0()->ToString());
949             }
950             return entry;
951         }
952     }
953     return nullptr;
954 }
955 
GetEntries() const956 std::vector<std::shared_ptr<PasteDataEntry>> PasteDataRecord::GetEntries() const
957 {
958     return entries_;
959 }
960 
SetDataId(uint32_t dataId)961 void PasteDataRecord::SetDataId(uint32_t dataId)
962 {
963     dataId_ = dataId;
964 }
965 
GetDataId() const966 uint32_t PasteDataRecord::GetDataId() const
967 {
968     return dataId_;
969 }
970 
SetRecordId(uint32_t recordId)971 void PasteDataRecord::SetRecordId(uint32_t recordId)
972 {
973     recordId_ = recordId;
974 }
975 
GetRecordId() const976 uint32_t PasteDataRecord::GetRecordId() const
977 {
978     return recordId_;
979 }
980 
SetDelayRecordFlag(bool isDelay)981 void PasteDataRecord::SetDelayRecordFlag(bool isDelay)
982 {
983     isDelay_ = isDelay;
984 }
985 
IsDelayRecord() const986 bool PasteDataRecord::IsDelayRecord() const
987 {
988     return isDelay_;
989 }
990 
SetEntryGetter(const std::shared_ptr<UDMF::EntryGetter> entryGetter)991 void PasteDataRecord::SetEntryGetter(const std::shared_ptr<UDMF::EntryGetter> entryGetter)
992 {
993     entryGetter_ = std::move(entryGetter);
994 }
995 
SetFrom(uint32_t from)996 void PasteDataRecord::SetFrom(uint32_t from)
997 {
998     from_ = from;
999 }
1000 
GetFrom() const1001 uint32_t PasteDataRecord::GetFrom() const
1002 {
1003     return from_;
1004 }
1005 
GetEntryGetter()1006 std::shared_ptr<UDMF::EntryGetter> PasteDataRecord::GetEntryGetter()
1007 {
1008     return entryGetter_;
1009 }
1010 } // namespace MiscServices
1011 } // namespace OHOS
1012