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