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