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 #include "paste_data_record.h"
16
17 #include <sys/stat.h>
18 #include <unistd.h>
19
20 #include "convert_utils.h"
21 #include "copy_uri_handler.h"
22 #include "parcel_util.h"
23 #include "paste_data_entry.h"
24 #include "paste_uri_handler.h"
25 #include "pasteboard_error.h"
26 #include "pasteboard_client.h"
27 #include "pasteboard_hilog.h"
28 #include "pixel_map_parcel.h"
29
30 using namespace OHOS::Media;
31
32 namespace OHOS {
33 namespace MiscServices {
34 namespace {
35 constexpr int MAX_TEXT_LEN = 20 * 1024 * 1024;
36 }
SetMimeType(std::string mimeType)37 PasteDataRecord::Builder &PasteDataRecord::Builder::SetMimeType(std::string mimeType)
38 {
39 record_->mimeType_ = std::move(mimeType);
40 return *this;
41 }
42 enum TAG_PASTEBOARD_RECORD : uint16_t {
43 TAG_MIMETYPE = TAG_BUFF + 1,
44 TAG_HTMLTEXT,
45 TAG_WANT,
46 TAG_PLAINTEXT,
47 TAG_URI,
48 TAG_PIXELMAP,
49 TAG_CUSTOM_DATA,
50 TAG_CONVERT_URI,
51 TAG_URI_PERMISSION,
52 TAG_UDC_UDTYPE,
53 TAG_UDC_DETAILS,
54 TAG_UDC_TEXTCONTENT,
55 TAG_UDC_SYSTEMCONTENTS,
56 TAG_UDC_UDMFVALUE,
57 TAG_UDC_ENTYIES,
58 TAG_DATA_ID,
59 TAG_RECORD_ID,
60 TAG_DELAY_RECORD_FLAG,
61 TAG_FROM,
62 };
63
64 enum TAG_CUSTOMDATA : uint16_t {
65 TAG_ITEM_DATA = TAG_BUFF + 1,
66 };
67
SetHtmlText(std::shared_ptr<std::string> htmlText)68 PasteDataRecord::Builder &PasteDataRecord::Builder::SetHtmlText(std::shared_ptr<std::string> htmlText)
69 {
70 record_->htmlText_ = std::move(htmlText);
71 return *this;
72 }
73
SetWant(std::shared_ptr<OHOS::AAFwk::Want> want)74 PasteDataRecord::Builder &PasteDataRecord::Builder::SetWant(std::shared_ptr<OHOS::AAFwk::Want> want)
75 {
76 record_->want_ = std::move(want);
77 return *this;
78 }
79
SetPlainText(std::shared_ptr<std::string> plainText)80 PasteDataRecord::Builder &PasteDataRecord::Builder::SetPlainText(std::shared_ptr<std::string> plainText)
81 {
82 record_->plainText_ = std::move(plainText);
83 return *this;
84 }
85
SetUri(std::shared_ptr<OHOS::Uri> uri)86 PasteDataRecord::Builder &PasteDataRecord::Builder::SetUri(std::shared_ptr<OHOS::Uri> uri)
87 {
88 record_->uri_ = std::move(uri);
89 return *this;
90 }
91
SetPixelMap(std::shared_ptr<OHOS::Media::PixelMap> pixelMap)92 PasteDataRecord::Builder &PasteDataRecord::Builder::SetPixelMap(std::shared_ptr<OHOS::Media::PixelMap> pixelMap)
93 {
94 record_->pixelMap_ = std::move(pixelMap);
95 return *this;
96 }
97
SetCustomData(std::shared_ptr<MineCustomData> customData)98 PasteDataRecord::Builder &PasteDataRecord::Builder::SetCustomData(std::shared_ptr<MineCustomData> customData)
99 {
100 record_->customData_ = std::move(customData);
101 return *this;
102 }
103
Build()104 std::shared_ptr<PasteDataRecord> PasteDataRecord::Builder::Build()
105 {
106 return record_;
107 }
108
Builder(const std::string & mimeType)109 PasteDataRecord::Builder::Builder(const std::string &mimeType)
110 {
111 record_ = std::make_shared<PasteDataRecord>();
112 if (record_ != nullptr) {
113 record_->mimeType_ = mimeType;
114 record_->htmlText_ = nullptr;
115 record_->want_ = nullptr;
116 record_->plainText_ = nullptr;
117 record_->uri_ = nullptr;
118 record_->convertUri_ = "";
119 record_->pixelMap_ = nullptr;
120 record_->customData_ = nullptr;
121 }
122 }
123
AddUriEntry()124 void PasteDataRecord::AddUriEntry()
125 {
126 auto object = std::make_shared<Object>();
127 object->value_[UDMF::UNIFORM_DATA_TYPE] = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::FILE_URI);
128 if (uri_ != nullptr) {
129 object->value_[UDMF::FILE_URI_PARAM] = uri_->ToString();
130 }
131 auto utdId = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::FILE_URI);
132 AddEntry(utdId, std::make_shared<PasteDataEntry>(utdId, object));
133 }
134
NewHtmlRecord(const std::string & htmlText)135 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewHtmlRecord(const std::string &htmlText)
136 {
137 if (htmlText.length() >= MAX_TEXT_LEN) {
138 return nullptr;
139 }
140 return Builder(MIMETYPE_TEXT_HTML).SetHtmlText(std::make_shared<std::string>(htmlText)).Build();
141 }
142
NewWantRecord(std::shared_ptr<OHOS::AAFwk::Want> want)143 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewWantRecord(std::shared_ptr<OHOS::AAFwk::Want> want)
144 {
145 return Builder(MIMETYPE_TEXT_WANT).SetWant(std::move(want)).Build();
146 }
147
NewPlaintTextRecord(const std::string & text)148 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewPlaintTextRecord(const std::string &text)
149 {
150 if (text.length() >= MAX_TEXT_LEN) {
151 return nullptr;
152 }
153 return Builder(MIMETYPE_TEXT_PLAIN).SetPlainText(std::make_shared<std::string>(text)).Build();
154 }
155
NewPixelMapRecord(std::shared_ptr<PixelMap> pixelMap)156 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewPixelMapRecord(std::shared_ptr<PixelMap> pixelMap)
157 {
158 return Builder(MIMETYPE_PIXELMAP).SetPixelMap(std::move(pixelMap)).Build();
159 }
160
NewUriRecord(const OHOS::Uri & uri)161 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewUriRecord(const OHOS::Uri &uri)
162 {
163 return Builder(MIMETYPE_TEXT_URI).SetUri(std::make_shared<OHOS::Uri>(uri)).Build();
164 }
165
NewKvRecord(const std::string & mimeType,const std::vector<uint8_t> & arrayBuffer)166 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewKvRecord(
167 const std::string &mimeType, const std::vector<uint8_t> &arrayBuffer)
168 {
169 std::shared_ptr<MineCustomData> customData = std::make_shared<MineCustomData>();
170 customData->AddItemData(mimeType, arrayBuffer);
171 return Builder(mimeType).SetCustomData(std::move(customData)).Build();
172 }
173
NewMultiTypeRecord(std::shared_ptr<std::map<std::string,std::shared_ptr<EntryValue>>> values,const std::string & recordMimeType)174 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewMultiTypeRecord(
175 std::shared_ptr<std::map<std::string, std::shared_ptr<EntryValue>>> values, const std::string &recordMimeType)
176 {
177 auto record = std::make_shared<PasteDataRecord>();
178 if (values == nullptr) {
179 return record;
180 }
181 if (!recordMimeType.empty()) {
182 auto recordDefaultIter = values->find(recordMimeType);
183 if (recordDefaultIter != values->end() && recordDefaultIter->second != nullptr) {
184 auto utdId = CommonUtils::Convert2UtdId(UDMF::UDType::UD_BUTT, recordMimeType);
185 record->AddEntry(utdId, std::make_shared<PasteDataEntry>(utdId, *(recordDefaultIter->second)));
186 }
187 }
188 for (auto [mimeType, value] : *values) {
189 if (mimeType == recordMimeType) {
190 continue;
191 }
192 auto utdId = CommonUtils::Convert2UtdId(UDMF::UDType::UD_BUTT, mimeType);
193 record->AddEntry(utdId, std::make_shared<PasteDataEntry>(utdId, *value));
194 }
195 return record;
196 }
197
NewMultiTypeDelayRecord(std::vector<std::string> mimeTypes,const std::shared_ptr<UDMF::EntryGetter> entryGetter)198 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewMultiTypeDelayRecord(
199 std::vector<std::string> mimeTypes, const std::shared_ptr<UDMF::EntryGetter> entryGetter)
200 {
201 auto record = std::make_shared<PasteDataRecord>();
202 for (auto mimeType : mimeTypes) {
203 auto utdId = CommonUtils::Convert2UtdId(UDMF::UDType::UD_BUTT, mimeType);
204 auto entry = std::make_shared<PasteDataEntry>();
205 entry->SetMimeType(mimeType);
206 entry->SetUtdId(utdId);
207 record->AddEntry(utdId, entry);
208 }
209 if (entryGetter != nullptr) {
210 record->SetEntryGetter(entryGetter);
211 record->SetDelayRecordFlag(true);
212 }
213 return record;
214 }
215
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)216 PasteDataRecord::PasteDataRecord(std::string mimeType, std::shared_ptr<std::string> htmlText,
217 std::shared_ptr<OHOS::AAFwk::Want> want, std::shared_ptr<std::string> plainText, std::shared_ptr<OHOS::Uri> uri)
218 : mimeType_{ std::move(mimeType) }, htmlText_{ std::move(htmlText) }, want_{ std::move(want) },
219 plainText_{ std::move(plainText) }, uri_{ std::move(uri) }
220 {
221 }
222
PasteDataRecord()223 PasteDataRecord::PasteDataRecord()
224 {
225 fd_ = std::make_shared<FileDescriptor>();
226 InitDecodeMap();
227 }
228
~PasteDataRecord()229 PasteDataRecord::~PasteDataRecord()
230 {
231 decodeMap.clear();
232 }
233
PasteDataRecord(const PasteDataRecord & record)234 PasteDataRecord::PasteDataRecord(const PasteDataRecord& record)
235 : mimeType_(record.mimeType_), htmlText_(record.htmlText_), want_(record.want_), plainText_(record.plainText_),
236 uri_(record.uri_), convertUri_(record.convertUri_), pixelMap_(record.pixelMap_), customData_(record.customData_),
237 hasGrantUriPermission_(record.hasGrantUriPermission_), fd_(record.fd_), udType_(record.udType_),
238 details_(record.details_), textContent_(record.textContent_),
239 systemDefinedContents_(record.systemDefinedContents_), udmfValue_(record.udmfValue_), entries_(record.entries_),
240 dataId_(record.dataId_), recordId_(record.recordId_), isDelay_(record.isDelay_),
241 entryGetter_(record.entryGetter_), from_(record.from_)
242 {
243 this->isConvertUriFromRemote = record.isConvertUriFromRemote;
244 InitDecodeMap();
245 }
246
InitDecodeMap()247 void PasteDataRecord::InitDecodeMap()
248 {
249 decodeMap = {
250 {TAG_MIMETYPE, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
251 ret = ret && ReadValue(buffer, mimeType_, head);}},
252 {TAG_HTMLTEXT, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
253 ret = ret && ReadValue(buffer, htmlText_, head);}},
254 {TAG_WANT, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
255 RawMem rawMem{};
256 ret = ret && ReadValue(buffer, rawMem, head);
257 want_ = ParcelUtil::Raw2Parcelable<AAFwk::Want>(rawMem);}},
258 {TAG_PLAINTEXT, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
259 ret = ret && ReadValue(buffer, plainText_, head); }},
260 {TAG_URI, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
261 RawMem rawMem{};
262 ret = ret && ReadValue(buffer, rawMem, head);
263 uri_ = ParcelUtil::Raw2Parcelable<OHOS::Uri>(rawMem);}},
264 {TAG_CONVERT_URI, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
265 ret = ret && ReadValue(buffer, convertUri_, head);}},
266 {TAG_PIXELMAP, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
267 std::vector<std::uint8_t> value;
268 ret = ret && ReadValue(buffer, value, head);
269 pixelMap_ = Vector2PixelMap(value);}},
270 {TAG_CUSTOM_DATA, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
271 ret = ret && ReadValue(buffer, customData_, head);}},
272 {TAG_URI_PERMISSION, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
273 ret = ret && ReadValue(buffer, hasGrantUriPermission_, head);}},
274 {TAG_UDC_UDTYPE, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
275 ret = ret && ReadValue(buffer, udType_, head);}},
276 {TAG_UDC_DETAILS, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
277 ret = ret && ReadValue(buffer, details_, head);}},
278 {TAG_UDC_TEXTCONTENT, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
279 ret = ret && ReadValue(buffer, textContent_, head);}},
280 {TAG_UDC_SYSTEMCONTENTS, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
281 ret = ret && ReadValue(buffer, systemDefinedContents_, head);}},
282 {TAG_UDC_UDMFVALUE, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
283 ret = ret && ReadValue(buffer, udmfValue_, head);}},
284 {TAG_UDC_ENTYIES, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
285 ret = ret && ReadValue(buffer, entries_, head);}},
286 {TAG_DATA_ID, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
287 ret = ret && ReadValue(buffer, dataId_, head);}},
288 {TAG_RECORD_ID, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
289 ret = ret && ReadValue(buffer, recordId_, head);}},
290 {TAG_DELAY_RECORD_FLAG, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
291 ret = ret && ReadValue(buffer, isDelay_, head);}},
292 {TAG_FROM, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
293 ret = ret && ReadValue(buffer, from_, head);}},
294 };
295 }
296
GetHtmlText() const297 std::shared_ptr<std::string> PasteDataRecord::GetHtmlText() const
298 {
299 if (htmlText_ != nullptr && mimeType_ == MIMETYPE_TEXT_HTML) {
300 return htmlText_;
301 }
302 for (const auto &entry : entries_) {
303 if (entry && entry->GetMimeType() == MIMETYPE_TEXT_HTML) {
304 return entry->ConvertToHtml();
305 }
306 }
307 return htmlText_;
308 }
309
GetMimeType() const310 std::string PasteDataRecord::GetMimeType() const
311 {
312 return this->mimeType_;
313 }
314
GetPlainText() const315 std::shared_ptr<std::string> PasteDataRecord::GetPlainText() const
316 {
317 if (plainText_ != nullptr && mimeType_ == MIMETYPE_TEXT_PLAIN) {
318 return plainText_;
319 }
320 for (const auto &entry : entries_) {
321 if (entry && entry->GetMimeType() == MIMETYPE_TEXT_PLAIN) {
322 return entry->ConvertToPlianText();
323 }
324 }
325 return plainText_;
326 }
327
GetPixelMap() const328 std::shared_ptr<PixelMap> PasteDataRecord::GetPixelMap() const
329 {
330 if (pixelMap_ != nullptr && mimeType_ == MIMETYPE_PIXELMAP) {
331 return pixelMap_;
332 }
333 for (const auto &entry : entries_) {
334 if (entry && entry->GetMimeType() == MIMETYPE_PIXELMAP) {
335 return entry->ConvertToPixelMap();
336 }
337 }
338 return pixelMap_;
339 }
340
GetUri() const341 std::shared_ptr<OHOS::Uri> PasteDataRecord::GetUri() const
342 {
343 if (convertUri_.empty()) {
344 return GetOrginUri();
345 }
346 return std::make_shared<OHOS::Uri>(convertUri_);
347 }
348
ClearPixelMap()349 void PasteDataRecord::ClearPixelMap()
350 {
351 this->pixelMap_ = nullptr;
352 }
353
SetUri(std::shared_ptr<OHOS::Uri> uri)354 void PasteDataRecord::SetUri(std::shared_ptr<OHOS::Uri> uri)
355 {
356 uri_ = std::move(uri);
357 AddUriEntry();
358 }
359
GetOrginUri() const360 std::shared_ptr<OHOS::Uri> PasteDataRecord::GetOrginUri() const
361 {
362 if (uri_ != nullptr && mimeType_ == MIMETYPE_TEXT_URI) {
363 return uri_;
364 }
365 for (const auto &entry : entries_) {
366 if (entry && entry->GetMimeType() == MIMETYPE_TEXT_URI) {
367 return entry->ConvertToUri();
368 }
369 }
370 return uri_;
371 }
372
GetWant() const373 std::shared_ptr<OHOS::AAFwk::Want> PasteDataRecord::GetWant() const
374 {
375 if (want_ != nullptr && mimeType_ == MIMETYPE_TEXT_WANT) {
376 return want_;
377 }
378 for (const auto &entry : entries_) {
379 if (entry && entry->GetMimeType() == MIMETYPE_TEXT_WANT) {
380 return entry->ConvertToWant();
381 }
382 }
383 return want_;
384 }
385
GetCustomData() const386 std::shared_ptr<MineCustomData> PasteDataRecord::GetCustomData() const
387 {
388 std::shared_ptr<MineCustomData> customData = std::make_shared<MineCustomData>();
389 if (customData_) {
390 const std::map<std::string, std::vector<uint8_t>> &itemData = customData_->GetItemData();
391 for (const auto &[key, value] : itemData) {
392 customData->AddItemData(key, value);
393 }
394 }
395 for (const auto &entry : entries_) {
396 if (entry && entry->GetMimeType() == entry->GetUtdId()) {
397 std::shared_ptr<MineCustomData> entryCustomData = entry->ConvertToCustomData();
398 if (entryCustomData == nullptr) {
399 continue;
400 }
401 const std::map<std::string, std::vector<uint8_t>> &itemData = entryCustomData->GetItemData();
402 for (const auto &[key, value] : itemData) {
403 customData->AddItemData(key, value);
404 }
405 }
406 }
407 return customData->GetItemData().empty() ? nullptr : customData;
408 }
409
ConvertToText() const410 std::string PasteDataRecord::ConvertToText() const
411 {
412 if (this->htmlText_) {
413 return *this->htmlText_;
414 } else if (this->plainText_) {
415 return *this->plainText_;
416 } else if (this->uri_) {
417 return this->uri_->ToString();
418 } else {
419 return "";
420 }
421 }
422
Encode(std::vector<std::uint8_t> & buffer)423 bool PasteDataRecord::Encode(std::vector<std::uint8_t> &buffer)
424 {
425 bool ret = Write(buffer, TAG_MIMETYPE, mimeType_);
426 ret = Write(buffer, TAG_HTMLTEXT, htmlText_) && ret;
427 ret = Write(buffer, TAG_WANT, ParcelUtil::Parcelable2Raw(want_.get())) && ret;
428 ret = Write(buffer, TAG_PLAINTEXT, plainText_) && ret;
429 ret = Write(buffer, TAG_URI, ParcelUtil::Parcelable2Raw(uri_.get())) && ret;
430 ret = Write(buffer, TAG_CONVERT_URI, convertUri_) && ret;
431 auto pixelVector = PixelMap2Vector(pixelMap_);
432 ret = Write(buffer, TAG_PIXELMAP, pixelVector) && ret;
433 ret = Write(buffer, TAG_CUSTOM_DATA, customData_) && ret;
434 ret = Write(buffer, TAG_URI_PERMISSION, hasGrantUriPermission_) && ret;
435 ret = Write(buffer, TAG_UDC_UDTYPE, udType_) && ret;
436 ret = Write(buffer, TAG_UDC_DETAILS, details_) && ret;
437 ret = Write(buffer, TAG_UDC_TEXTCONTENT, textContent_) && ret;
438 ret = Write(buffer, TAG_UDC_SYSTEMCONTENTS, systemDefinedContents_) && ret;
439 ret = Write(buffer, TAG_UDC_UDMFVALUE, udmfValue_) && ret;
440 ret = Write(buffer, TAG_UDC_ENTYIES, entries_) && ret;
441 ret = Write(buffer, TAG_DATA_ID, dataId_) && ret;
442 ret = Write(buffer, TAG_RECORD_ID, recordId_) && ret;
443 ret = Write(buffer, TAG_DELAY_RECORD_FLAG, isDelay_) && ret;
444 ret = Write(buffer, TAG_FROM, from_) && ret;
445 return ret;
446 }
447
Decode(const std::vector<std::uint8_t> & buffer)448 bool PasteDataRecord::Decode(const std::vector<std::uint8_t> &buffer)
449 {
450 for (; IsEnough();) {
451 TLVHead head{};
452 bool ret = ReadHead(buffer, head);
453 auto it = decodeMap.find(head.tag);
454 if (it == decodeMap.end()) {
455 ret = ret && Skip(head.len, buffer.size());
456 } else {
457 auto func = it->second;
458 func(ret, buffer, head);
459 }
460 if (!ret) {
461 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "read value,tag:%{public}u, len:%{public}u",
462 head.tag, head.len);
463 return false;
464 }
465 }
466 return true;
467 }
Count()468 size_t PasteDataRecord::Count()
469 {
470 size_t expectedSize = 0;
471 expectedSize += TLVObject::Count(mimeType_);
472 expectedSize += TLVObject::Count(htmlText_);
473 expectedSize += TLVObject::Count(ParcelUtil::Parcelable2Raw(want_.get()));
474 expectedSize += TLVObject::Count(plainText_);
475 expectedSize += TLVObject::Count(ParcelUtil::Parcelable2Raw(uri_.get()));
476 expectedSize += TLVObject::Count(convertUri_);
477 auto pixelVector = PixelMap2Vector(pixelMap_);
478 expectedSize += TLVObject::Count(pixelVector);
479 expectedSize += TLVObject::Count(customData_);
480 expectedSize += TLVObject::Count(hasGrantUriPermission_);
481 expectedSize += TLVObject::Count(udType_);
482 expectedSize += TLVObject::Count(details_);
483 expectedSize += TLVObject::Count(textContent_);
484 expectedSize += TLVObject::Count(systemDefinedContents_);
485 expectedSize += TLVObject::Count(udmfValue_);
486 expectedSize += TLVObject::Count(entries_);
487 expectedSize += TLVObject::Count(dataId_);
488 expectedSize += TLVObject::Count(recordId_);
489 expectedSize += TLVObject::Count(isDelay_);
490 expectedSize += TLVObject::Count(from_);
491 return expectedSize;
492 }
493
WriteFd(MessageParcel & parcel,UriHandler & uriHandler,bool isClient)494 bool PasteDataRecord::WriteFd(MessageParcel &parcel, UriHandler &uriHandler, bool isClient)
495 {
496 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "isClient: %{public}d", isClient);
497 if (fd_->GetFd() >= 0) {
498 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "write fd_, fd_ is %{public}d", fd_->GetFd());
499 return parcel.WriteFileDescriptor(fd_->GetFd());
500 }
501 std::string tempUri = GetPassUri();
502 if (tempUri.empty()) {
503 return false;
504 }
505 int32_t fd = uriHandler.ToFd(tempUri, isClient);
506 bool ret = parcel.WriteFileDescriptor(fd);
507 uriHandler.ReleaseFd(fd);
508
509 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "ret is %{public}d", ret);
510 return ret;
511 }
512
ReadFd(MessageParcel & parcel,UriHandler & uriHandler)513 bool PasteDataRecord::ReadFd(MessageParcel &parcel, UriHandler &uriHandler)
514 {
515 int32_t fd = parcel.ReadFileDescriptor();
516 if (fd >= 0) {
517 convertUri_ = uriHandler.ToUri(fd);
518 }
519 if (!uriHandler.IsPaste()) {
520 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "Set fd, fd is %{public}d", fd);
521 fd_->SetFd(fd);
522 }
523 return true;
524 }
NeedFd(const UriHandler & uriHandler)525 bool PasteDataRecord::NeedFd(const UriHandler &uriHandler)
526 {
527 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "start");
528 std::string tempUri = GetPassUri();
529 if (tempUri.empty()) {
530 return false;
531 }
532 if (!uriHandler.IsFile(tempUri) && fd_->GetFd() < 0) {
533 PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "invalid file uri, fd:%{public}d", fd_->GetFd());
534 return false;
535 }
536 return true;
537 }
GetPassUri()538 std::string PasteDataRecord::GetPassUri()
539 {
540 std::string tempUri;
541 if (uri_ != nullptr) {
542 tempUri = uri_->ToString();
543 }
544 if (!convertUri_.empty()) {
545 tempUri = convertUri_;
546 }
547 return tempUri;
548 }
549
ReplaceShareUri(int32_t userId)550 void PasteDataRecord::ReplaceShareUri(int32_t userId)
551 {
552 if (convertUri_.empty()) {
553 return;
554 }
555
556 // convert uri format: /mnt/hmdfs/100/account/merge_view/services/psteboard_service/.share/xxx.txt
557 constexpr const char *SHARE_PATH_PREFIX = "/mnt/hmdfs/";
558 auto frontPos = convertUri_.find(SHARE_PATH_PREFIX);
559 auto rearPos = convertUri_.find("/account/");
560 if (frontPos == 0 && rearPos != std::string::npos) {
561 convertUri_ = SHARE_PATH_PREFIX + std::to_string(userId) + convertUri_.substr(rearPos);
562 }
563 }
SetConvertUri(const std::string & value)564 void PasteDataRecord::SetConvertUri(const std::string &value)
565 {
566 convertUri_ = value;
567 }
GetConvertUri() const568 std::string PasteDataRecord::GetConvertUri() const
569 {
570 return convertUri_;
571 }
SetGrantUriPermission(bool hasPermission)572 void PasteDataRecord::SetGrantUriPermission(bool hasPermission)
573 {
574 hasGrantUriPermission_ = hasPermission;
575 }
HasGrantUriPermission()576 bool PasteDataRecord::HasGrantUriPermission()
577 {
578 return hasGrantUriPermission_;
579 }
580
SetTextContent(const std::string & content)581 void PasteDataRecord::SetTextContent(const std::string& content)
582 {
583 this->textContent_ = content;
584 }
585
GetTextContent() const586 std::string PasteDataRecord::GetTextContent() const
587 {
588 return this->textContent_;
589 }
590
SetDetails(const Details & details)591 void PasteDataRecord::SetDetails(const Details& details)
592 {
593 this->details_ = std::make_shared<Details>(details);
594 }
595
GetDetails() const596 std::shared_ptr<Details> PasteDataRecord::GetDetails() const
597 {
598 return this->details_;
599 }
600
SetSystemDefinedContent(const Details & contents)601 void PasteDataRecord::SetSystemDefinedContent(const Details& contents)
602 {
603 this->systemDefinedContents_ = std::make_shared<Details>(contents);
604 }
605
GetSystemDefinedContent() const606 std::shared_ptr<Details> PasteDataRecord::GetSystemDefinedContent() const
607 {
608 return this->systemDefinedContents_;
609 }
GetUDType() const610 int32_t PasteDataRecord::GetUDType() const
611 {
612 return this->udType_;
613 }
614
SetUDType(int32_t type)615 void PasteDataRecord::SetUDType(int32_t type)
616 {
617 this->udType_ = type;
618 }
619
GetValidMimeTypes(const std::vector<std::string> & mimeTypes) const620 std::vector<std::string> PasteDataRecord::GetValidMimeTypes(const std::vector<std::string>& mimeTypes) const
621 {
622 std::vector<std::string> res;
623 auto allTypes = GetMimeTypes();
624 for (auto const& type : mimeTypes) {
625 if (allTypes.find(type) != allTypes.end()) {
626 res.emplace_back(type);
627 }
628 }
629 return res;
630 }
631
GetValidTypes(const std::vector<std::string> & types) const632 std::vector<std::string> PasteDataRecord::GetValidTypes(const std::vector<std::string>& types) const
633 {
634 std::vector<std::string> res;
635 auto allTypes = GetUdtTypes();
636 for (auto const& type : types) {
637 if (allTypes.find(type) != allTypes.end()) {
638 res.emplace_back(type);
639 }
640 }
641 return res;
642 }
643
HasEmptyEntry() const644 bool PasteDataRecord::HasEmptyEntry() const
645 {
646 if (udmfValue_ && !std::holds_alternative<std::monostate>(*udmfValue_)) {
647 return false;
648 }
649 for (auto const &entry : GetEntries()) {
650 if (std::holds_alternative<std::monostate>(entry->GetValue())) {
651 return true;
652 }
653 }
654 return false;
655 }
656
SetUDMFValue(const std::shared_ptr<EntryValue> & udmfValue)657 void PasteDataRecord::SetUDMFValue(const std::shared_ptr<EntryValue>& udmfValue)
658 {
659 this->udmfValue_ = udmfValue;
660 }
661
GetUDMFValue()662 std::shared_ptr<EntryValue> PasteDataRecord::GetUDMFValue()
663 {
664 if (udmfValue_) {
665 PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "udmfValue_ is not null");
666 return this->udmfValue_;
667 }
668 if (mimeType_.empty()) {
669 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "mimetype is null");
670 return nullptr;
671 }
672 auto object = std::make_shared<Object>();
673 if (mimeType_ == MIMETYPE_TEXT_PLAIN) {
674 object->value_[UDMF::UNIFORM_DATA_TYPE] = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::PLAIN_TEXT);
675 if (plainText_ != nullptr) {
676 object->value_[UDMF::CONTENT] = *plainText_;
677 }
678 } else if (mimeType_ == MIMETYPE_TEXT_HTML) {
679 object->value_[UDMF::UNIFORM_DATA_TYPE] = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::HTML);
680 if (htmlText_ != nullptr) {
681 object->value_[UDMF::HTML_CONTENT] = *htmlText_;
682 }
683 } else if (mimeType_ == MIMETYPE_PIXELMAP) {
684 object->value_[UDMF::UNIFORM_DATA_TYPE] = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::SYSTEM_DEFINED_PIXEL_MAP);
685 if (pixelMap_ != nullptr) {
686 object->value_[UDMF::PIXEL_MAP] = pixelMap_;
687 }
688 } else if (mimeType_ == MIMETYPE_TEXT_URI) {
689 object->value_[UDMF::UNIFORM_DATA_TYPE] = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::FILE_URI);
690 auto uri = GetUri();
691 if (uri != nullptr) {
692 object->value_[UDMF::FILE_URI_PARAM] = uri->ToString();
693 }
694 } else if (mimeType_ == MIMETYPE_TEXT_WANT) {
695 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "mimeType is want, udmf not surpport");
696 } else if (customData_ != nullptr) {
697 auto itemData = customData_->GetItemData();
698 if (itemData.size() == 0) {
699 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "no customData");
700 return udmfValue_;
701 }
702 if (itemData.size() != 1) {
703 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT,
704 "not surrport u8 map, mimeType:%{public}s, customData.size:%{public}zu", mimeType_.c_str(),
705 itemData.size());
706 }
707 udmfValue_ = std::make_shared<EntryValue>(itemData.begin()->second);
708 return udmfValue_;
709 }
710 udmfValue_ = std::make_shared<EntryValue>(object);
711 return udmfValue_;
712 }
713
GetUdtTypes() const714 std::set<std::string> PasteDataRecord::GetUdtTypes() const
715 {
716 std::set<std::string> types;
717 types.emplace(CommonUtils::Convert2UtdId(udType_, mimeType_));
718 for (auto const& entry: entries_) {
719 types.emplace(entry->GetUtdId());
720 }
721 return types;
722 }
723
GetMimeTypes() const724 std::set<std::string> PasteDataRecord::GetMimeTypes() const
725 {
726 std::set<std::string> types;
727 types.emplace(mimeType_);
728 for (auto const& entry: entries_) {
729 types.emplace(entry->GetMimeType());
730 }
731 return types;
732 }
733
AddEntryByMimeType(const std::string & mimeType,std::shared_ptr<PasteDataEntry> value)734 void PasteDataRecord::AddEntryByMimeType(const std::string& mimeType, std::shared_ptr<PasteDataEntry> value)
735 {
736 if (value == nullptr) {
737 return;
738 }
739 auto utdId = CommonUtils::Convert2UtdId(UDMF::UDType::UD_BUTT, mimeType);
740 value->SetUtdId(utdId);
741 AddEntry(utdId, value);
742 }
743
AddEntry(const std::string & utdType,std::shared_ptr<PasteDataEntry> value)744 void PasteDataRecord::AddEntry(const std::string& utdType, std::shared_ptr<PasteDataEntry> value)
745 {
746 if (!value) {
747 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "entry is null");
748 return;
749 }
750 if (utdType != value->GetUtdId()) {
751 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "type is diff. utdtype:%{public}s, UtdId:%{public}s",
752 utdType.c_str(), value->GetUtdId().c_str());
753 return;
754 }
755 // first entry save to record, or record type same
756 if (mimeType_.empty() || utdType == CommonUtils::Convert2UtdId(udType_, mimeType_)) {
757 mimeType_ = value->GetMimeType();
758 auto udType = UDMF::UtdUtils::GetUtdEnumFromUtdId(utdType);
759 udType_ = udType == UDMF::UDType::UD_BUTT ? UDMF::UDType::APPLICATION_DEFINED_RECORD : udType;
760 udmfValue_ = std::make_shared<EntryValue>(value->GetValue());
761 if (mimeType_ == MIMETYPE_PIXELMAP) {
762 pixelMap_ = value->ConvertToPixelMap();
763 } else if (mimeType_ == MIMETYPE_TEXT_HTML) {
764 htmlText_ = value->ConvertToHtml();
765 } else if (mimeType_ == MIMETYPE_TEXT_PLAIN) {
766 plainText_ = value->ConvertToPlianText();
767 } else if (mimeType_ == MIMETYPE_TEXT_URI) {
768 uri_ = value->ConvertToUri();
769 } else if (mimeType_ == MIMETYPE_TEXT_WANT) {
770 want_ = value->ConvertToWant();
771 } else {
772 customData_ = value->ConvertToCustomData();
773 }
774 return;
775 }
776 // not firest entry
777 bool has = false;
778 for (auto& entry : entries_) {
779 if (entry->GetUtdId() == utdType) {
780 entry = value;
781 has = true;
782 break;
783 }
784 }
785 if (!has) {
786 entries_.emplace_back(value);
787 }
788 }
789
GetEntryByMimeType(const std::string & mimeType)790 std::shared_ptr<PasteDataEntry> PasteDataRecord::GetEntryByMimeType(const std::string& mimeType)
791 {
792 if (!udmfValue_) {
793 udmfValue_ = GetUDMFValue();
794 }
795 auto utdId = CommonUtils::Convert2UtdId(UDMF::UDType::UD_BUTT, mimeType);
796 return GetEntry(utdId);
797 }
798
GetEntry(const std::string & utdType)799 std::shared_ptr<PasteDataEntry> PasteDataRecord::GetEntry(const std::string& utdType)
800 {
801 if (!udmfValue_) {
802 udmfValue_ = GetUDMFValue();
803 }
804 if (CommonUtils::Convert2UtdId(udType_, mimeType_) == utdType) {
805 if (udmfValue_ == nullptr) {
806 return nullptr;
807 }
808 auto entry = std::make_shared<PasteDataEntry>(utdType, *udmfValue_);
809 if (isDelay_ && !entry->HasContent(utdType)) {
810 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "Begin GetRecordValueByType1");
811 PasteboardClient::GetInstance()->GetRecordValueByType(dataId_, recordId_, *entry);
812 }
813 if (CommonUtils::IsFileUri(utdType) && GetUri() != nullptr) {
814 return std::make_shared<PasteDataEntry>(utdType, GetUri()->ToString());
815 } else if (mimeType_ == MIMETYPE_TEXT_WANT) {
816 return std::make_shared<PasteDataEntry>(utdType, want_);
817 }
818 return entry;
819 }
820 for (auto const &entry : entries_) {
821 if (entry->GetUtdId() == utdType ||
822 (CommonUtils::IsFileUri(utdType) && CommonUtils::IsFileUri(entry->GetUtdId()))) {
823 if (isDelay_ && !entry->HasContent(utdType)) {
824 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "Begin GetRecordValueByType2");
825 PasteboardClient::GetInstance()->GetRecordValueByType(dataId_, recordId_, *entry);
826 }
827 if (CommonUtils::IsFileUri(utdType) && GetUri() != nullptr) {
828 return std::make_shared<PasteDataEntry>(utdType, GetUri()->ToString());
829 }
830 return entry;
831 }
832 }
833 return nullptr;
834 }
835
GetEntries() const836 std::vector<std::shared_ptr<PasteDataEntry>> PasteDataRecord::GetEntries() const
837 {
838 std::vector<std::shared_ptr<PasteDataEntry>> entries = entries_;
839 if (udmfValue_) {
840 entries.insert(entries.begin(),
841 std::make_shared<PasteDataEntry>(CommonUtils::Convert2UtdId(udType_, mimeType_), *udmfValue_));
842 }
843 return entries;
844 }
845
SetDataId(uint32_t dataId)846 void PasteDataRecord::SetDataId(uint32_t dataId)
847 {
848 dataId_ = dataId;
849 }
850
GetDataId() const851 uint32_t PasteDataRecord::GetDataId() const
852 {
853 return dataId_;
854 }
855
SetRecordId(uint32_t recordId)856 void PasteDataRecord::SetRecordId(uint32_t recordId)
857 {
858 recordId_ = recordId;
859 }
860
GetRecordId() const861 uint32_t PasteDataRecord::GetRecordId() const
862 {
863 return recordId_;
864 }
865
SetDelayRecordFlag(bool isDelay)866 void PasteDataRecord::SetDelayRecordFlag(bool isDelay)
867 {
868 isDelay_ = isDelay;
869 }
870
IsDelayRecord() const871 bool PasteDataRecord::IsDelayRecord() const
872 {
873 return isDelay_;
874 }
875
SetEntryGetter(const std::shared_ptr<UDMF::EntryGetter> entryGetter)876 void PasteDataRecord::SetEntryGetter(const std::shared_ptr<UDMF::EntryGetter> entryGetter)
877 {
878 entryGetter_ = std::move(entryGetter);
879 }
880
SetFrom(uint32_t from)881 void PasteDataRecord::SetFrom(uint32_t from)
882 {
883 from_ = from;
884 }
885
GetFrom() const886 uint32_t PasteDataRecord::GetFrom() const
887 {
888 return from_;
889 }
890
GetEntryGetter()891 std::shared_ptr<UDMF::EntryGetter> PasteDataRecord::GetEntryGetter()
892 {
893 return entryGetter_;
894 }
895
~FileDescriptor()896 FileDescriptor::~FileDescriptor()
897 {
898 if (fd_ >= 0) {
899 close(fd_);
900 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "close fd_: %{public}d", fd_);
901 }
902 }
SetFd(int32_t fd)903 void FileDescriptor::SetFd(int32_t fd)
904 {
905 fd_ = fd;
906 }
GetFd() const907 int32_t FileDescriptor::GetFd() const
908 {
909 return fd_;
910 }
911 } // namespace MiscServices
912 } // namespace OHOS