1 
2 /*
3  * Copyright (C) 2021 Huawei Device Co., Ltd.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "paste_data.h"
18 
19 #include <new>
20 
21 #include "parcel_util.h"
22 #include "paste_data_record.h"
23 #include "pasteboard_hilog.h"
24 #include "type_traits"
25 
26 using namespace std::chrono;
27 using namespace OHOS::Media;
28 
29 namespace OHOS {
30 namespace MiscServices {
31 enum TAG_PASTEBOARD : uint16_t {
32     TAG_PROPS = TAG_BUFF + 1,
33     TAG_RECORDS,
34     TAG_DRAGGED_DATA_FLAG,
35     TAG_LOCAL_PASTE_FLAG,
36     TAG_DELAY_DATA_FLAG,
37     TAG_DEVICE_ID,
38     TAG_PASTE_ID,
39     TAG_DELAY_RECORD_FLAG,
40     TAG_DATA_ID,
41 };
42 enum TAG_PROPERTY : uint16_t {
43     TAG_ADDITIONS = TAG_BUFF + 1,
44     TAG_MIMETYPES,
45     TAG_TAG,
46     TAG_LOCAL_ONLY,
47     TAG_TIMESTAMP,
48     TAG_SHAREOPTION,
49     TAG_TOKENID,
50     TAG_ISREMOTE,
51     TAG_BUNDLENAME,
52     TAG_SETTIME,
53     TAG_SCREENSTATUS,
54 };
55 
56 std::string PasteData::sharePath = "";
57 std::string PasteData::WEBVIEW_PASTEDATA_TAG = "WebviewPasteDataTag";
58 const std::string PasteData::DISTRIBUTEDFILES_TAG = "distributedfiles";
59 const std::string PasteData::PATH_SHARE = "/data/storage/el2/share/r/";
60 const std::string PasteData::FILE_SCHEME_PREFIX = "file://";
61 const std::string PasteData::IMG_LOCAL_URI = "file:///";
62 const std::string PasteData::SHARE_PATH_PREFIX = "/mnt/hmdfs/";
63 const std::string PasteData::SHARE_PATH_PREFIX_ACCOUNT = "/account/merge_view/services/";
64 const std::string PasteData::REMOTE_FILE_SIZE = "remoteFileSize";
65 const std::string PasteData::REMOTE_FILE_SIZE_LONG = "remoteFileSizeLong";
66 
PasteData()67 PasteData::PasteData()
68 {
69     props_.timestamp = steady_clock::now().time_since_epoch().count();
70     props_.localOnly = false;
71     props_.shareOption = ShareOption::CrossDevice;
72     InitDecodeMap();
73 }
74 
~PasteData()75 PasteData::~PasteData()
76 {
77     records_.clear();
78 }
79 
PasteData(const PasteData & data)80 PasteData::PasteData(const PasteData &data) : orginAuthority_(data.orginAuthority_), valid_(data.valid_),
81     isDraggedData_(data.isDraggedData_), isLocalPaste_(data.isLocalPaste_), isDelayData_(data.isDelayData_),
82     pasteId_(data.pasteId_), isDelayRecord_(data.isDelayRecord_), dataId_(data.dataId_)
83 {
84     this->props_ = data.props_;
85     for (const auto &item : data.records_) {
86         this->records_.emplace_back(std::make_shared<PasteDataRecord>(*item));
87     }
88     InitDecodeMap();
89 }
90 
PasteData(std::vector<std::shared_ptr<PasteDataRecord>> records)91 PasteData::PasteData(std::vector<std::shared_ptr<PasteDataRecord>> records) : records_{ std::move(records) }
92 {
93     props_.timestamp = steady_clock::now().time_since_epoch().count();
94     props_.localOnly = false;
95     props_.shareOption = ShareOption::CrossDevice;
96     InitDecodeMap();
97 }
98 
operator =(const PasteData & data)99 PasteData& PasteData::operator=(const PasteData &data)
100 {
101     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "PasteData copy");
102     if (this == &data) {
103         return *this;
104     }
105     this->orginAuthority_ = data.orginAuthority_;
106     this->valid_ = data.valid_;
107     this->isDraggedData_ = data.isDraggedData_;
108     this->isLocalPaste_ = data.isLocalPaste_;
109     this->isDelayData_ = data.isDelayData_;
110     this->isDelayRecord_ = data.isDelayRecord_;
111     this->dataId_ = data.dataId_;
112     this->props_ = data.props_;
113     this->records_.clear();
114     this->deviceId_ = data.deviceId_;
115     this->pasteId_ = data.pasteId_;
116     for (const auto &item : data.records_) {
117         this->records_.emplace_back(std::make_shared<PasteDataRecord>(*item));
118     }
119     return *this;
120 }
121 
GetProperty() const122 PasteDataProperty PasteData::GetProperty() const
123 {
124     return PasteDataProperty(props_);
125 }
126 
SetProperty(const PasteDataProperty & property)127 void PasteData::SetProperty(const PasteDataProperty &property)
128 {
129     this->props_ = property;
130 }
131 
AddHtmlRecord(const std::string & html)132 void PasteData::AddHtmlRecord(const std::string &html)
133 {
134     this->AddRecord(PasteDataRecord::NewHtmlRecord(html));
135 }
136 
AddPixelMapRecord(std::shared_ptr<PixelMap> pixelMap)137 void PasteData::AddPixelMapRecord(std::shared_ptr<PixelMap> pixelMap)
138 {
139     this->AddRecord(PasteDataRecord::NewPixelMapRecord(std::move(pixelMap)));
140 }
141 
AddWantRecord(std::shared_ptr<OHOS::AAFwk::Want> want)142 void PasteData::AddWantRecord(std::shared_ptr<OHOS::AAFwk::Want> want)
143 {
144     this->AddRecord(PasteDataRecord::NewWantRecord(std::move(want)));
145 }
146 
AddTextRecord(const std::string & text)147 void PasteData::AddTextRecord(const std::string &text)
148 {
149     this->AddRecord(PasteDataRecord::NewPlaintTextRecord(text));
150 }
151 
AddUriRecord(const OHOS::Uri & uri)152 void PasteData::AddUriRecord(const OHOS::Uri &uri)
153 {
154     this->AddRecord(PasteDataRecord::NewUriRecord(uri));
155 }
156 
AddKvRecord(const std::string & mimeType,const std::vector<uint8_t> & arrayBuffer)157 void PasteData::AddKvRecord(const std::string &mimeType, const std::vector<uint8_t> &arrayBuffer)
158 {
159     AddRecord(PasteDataRecord::NewKvRecord(mimeType, arrayBuffer));
160 }
161 
AddRecord(std::shared_ptr<PasteDataRecord> record)162 void PasteData::AddRecord(std::shared_ptr<PasteDataRecord> record)
163 {
164     if (record == nullptr) {
165         return;
166     }
167     record->SetRecordId(++recordId_);
168     records_.insert(records_.begin(), std::move(record));
169     RefreshMimeProp();
170 }
171 
AddRecord(PasteDataRecord & record)172 void PasteData::AddRecord(PasteDataRecord &record)
173 {
174     this->AddRecord(std::make_shared<PasteDataRecord>(record));
175     RefreshMimeProp();
176 }
177 
GetMimeTypes()178 std::vector<std::string> PasteData::GetMimeTypes()
179 {
180     std::vector<std::string> mimeType;
181     for (const auto &item : records_) {
182         mimeType.push_back(item->GetMimeType());
183     }
184     return mimeType;
185 }
186 
GetMimeTypesWithEntry()187 std::vector<std::string> PasteData::GetMimeTypesWithEntry()
188 {
189     std::set<std::string> mimeTypes;
190     for (const auto &item : records_) {
191         auto itemTypes = item->GetMimeTypes();
192         mimeTypes.insert(itemTypes.begin(), itemTypes.end());
193     }
194     return std::vector<std::string>(mimeTypes.begin(), mimeTypes.end());
195 }
196 
GetPrimaryHtml()197 std::shared_ptr<std::string> PasteData::GetPrimaryHtml()
198 {
199     for (const auto &item : records_) {
200         std::shared_ptr<std::string> primary = item->GetHtmlText();
201         if (primary) {
202             return primary;
203         }
204     }
205     return nullptr;
206 }
207 
GetPrimaryPixelMap()208 std::shared_ptr<PixelMap> PasteData::GetPrimaryPixelMap()
209 {
210     for (const auto &item : records_) {
211         std::shared_ptr<PixelMap> primary = item->GetPixelMap();
212         if (primary) {
213             return primary;
214         }
215     }
216     return nullptr;
217 }
218 
GetPrimaryWant()219 std::shared_ptr<OHOS::AAFwk::Want> PasteData::GetPrimaryWant()
220 {
221     for (const auto &item : records_) {
222         std::shared_ptr<OHOS::AAFwk::Want> primary = item->GetWant();
223         if (primary) {
224             return primary;
225         }
226     }
227     return nullptr;
228 }
229 
GetPrimaryText()230 std::shared_ptr<std::string> PasteData::GetPrimaryText()
231 {
232     for (const auto &item : records_) {
233         std::shared_ptr<std::string> primary = item->GetPlainText();
234         if (primary) {
235             return primary;
236         }
237     }
238     return nullptr;
239 }
240 
GetPrimaryUri()241 std::shared_ptr<OHOS::Uri> PasteData::GetPrimaryUri()
242 {
243     for (const auto &item : records_) {
244         std::shared_ptr<OHOS::Uri> primary = item->GetUri();
245         if (primary) {
246             return primary;
247         }
248     }
249     return nullptr;
250 }
251 
GetPrimaryMimeType()252 std::shared_ptr<std::string> PasteData::GetPrimaryMimeType()
253 {
254     if (records_.empty()) {
255         return nullptr;
256     }
257     return std::make_shared<std::string>(records_.front()->GetMimeType());
258 }
259 
GetRecordAt(std::size_t index) const260 std::shared_ptr<PasteDataRecord> PasteData::GetRecordAt(std::size_t index) const
261 {
262     if (records_.size() > index) {
263         return records_[index];
264     } else {
265         return nullptr;
266     }
267 }
268 
GetRecordCount() const269 std::size_t PasteData::GetRecordCount() const
270 {
271     return records_.size();
272 }
273 
GetShareOption()274 ShareOption PasteData::GetShareOption()
275 {
276     return props_.shareOption;
277 }
278 
SetShareOption(ShareOption shareOption)279 void PasteData::SetShareOption(ShareOption shareOption)
280 {
281     props_.shareOption = shareOption;
282     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "shareOption = %{public}d.", shareOption);
283 }
284 
GetTokenId()285 std::uint32_t PasteData::GetTokenId()
286 {
287     return props_.tokenId;
288 }
289 
SetTokenId(uint32_t tokenId)290 void PasteData::SetTokenId(uint32_t tokenId)
291 {
292     props_.tokenId = tokenId;
293 }
294 
RemoveRecordAt(std::size_t number)295 bool PasteData::RemoveRecordAt(std::size_t number)
296 {
297     if (records_.size() > number) {
298         records_.erase(records_.begin() + static_cast<std::int64_t>(number));
299         RefreshMimeProp();
300         return true;
301     } else {
302         return false;
303     }
304 }
305 
ReplaceRecordAt(std::size_t number,std::shared_ptr<PasteDataRecord> record)306 bool PasteData::ReplaceRecordAt(std::size_t number, std::shared_ptr<PasteDataRecord> record)
307 {
308     if (record == nullptr) {
309         return false;
310     }
311     if (records_.size() > number) {
312         records_[number] = std::move(record);
313         RefreshMimeProp();
314         return true;
315     } else {
316         return false;
317     }
318 }
319 
HasMimeType(const std::string & mimeType)320 bool PasteData::HasMimeType(const std::string &mimeType)
321 {
322     for (auto &item : records_) {
323         if (item->GetMimeType() == mimeType) {
324             return true;
325         }
326     }
327     return false;
328 }
329 
AllRecords() const330 std::vector<std::shared_ptr<PasteDataRecord>> PasteData::AllRecords() const
331 {
332     return this->records_;
333 }
334 
IsDraggedData() const335 bool PasteData::IsDraggedData() const
336 {
337     return isDraggedData_;
338 }
339 
IsLocalPaste() const340 bool PasteData::IsLocalPaste() const
341 {
342     return isLocalPaste_;
343 }
344 
SetDraggedDataFlag(bool isDraggedData)345 void PasteData::SetDraggedDataFlag(bool isDraggedData)
346 {
347     isDraggedData_ = isDraggedData;
348 }
349 
SetLocalPasteFlag(bool isLocalPaste)350 void PasteData::SetLocalPasteFlag(bool isLocalPaste)
351 {
352     isLocalPaste_ = isLocalPaste;
353 }
354 
SetRemote(bool isRemote)355 void PasteData::SetRemote(bool isRemote)
356 {
357     props_.isRemote = isRemote;
358 }
359 
IsRemote()360 bool PasteData::IsRemote()
361 {
362     return props_.isRemote;
363 }
364 
SetBundleName(const std::string & bundleName)365 void PasteData::SetBundleName(const std::string &bundleName)
366 {
367     props_.bundleName = bundleName;
368 }
369 
GetBundleName() const370 std::string PasteData::GetBundleName() const
371 {
372     return props_.bundleName;
373 }
374 
SetOrginAuthority(const std::string & bundleName)375 void PasteData::SetOrginAuthority(const std::string &bundleName)
376 {
377     orginAuthority_ = bundleName;
378 }
379 
GetOrginAuthority() const380 std::string PasteData::GetOrginAuthority() const
381 {
382     return orginAuthority_;
383 }
384 
SetTime(const std::string & setTime)385 void PasteData::SetTime(const std::string &setTime)
386 {
387     props_.setTime = setTime;
388 }
389 
GetTime()390 std::string PasteData::GetTime()
391 {
392     return props_.setTime;
393 }
394 
SetScreenStatus(ScreenEvent screenStatus)395 void PasteData::SetScreenStatus(ScreenEvent screenStatus)
396 {
397     props_.screenStatus = screenStatus;
398 }
399 
GetScreenStatus()400 ScreenEvent PasteData::GetScreenStatus()
401 {
402     return props_.screenStatus;
403 }
404 
SetTag(std::string & tag)405 void PasteData::SetTag(std::string &tag)
406 {
407     props_.tag = tag;
408 }
409 
GetTag()410 std::string PasteData::GetTag()
411 {
412     return props_.tag;
413 }
414 
SetAdditions(AAFwk::WantParams & additions)415 void PasteData::SetAdditions(AAFwk::WantParams &additions)
416 {
417     props_.additions = additions;
418 }
419 
SetAddition(const std::string & key,AAFwk::IInterface * value)420 void PasteData::SetAddition(const std::string &key, AAFwk::IInterface *value)
421 {
422     props_.additions.SetParam(key, value);
423 }
424 
SetLocalOnly(bool localOnly)425 void PasteData::SetLocalOnly(bool localOnly)
426 {
427     props_.localOnly = localOnly;
428 }
429 
GetLocalOnly()430 bool PasteData::GetLocalOnly()
431 {
432     return props_.localOnly;
433 }
434 
RefreshMimeProp()435 void PasteData::RefreshMimeProp()
436 {
437     std::vector<std::string> mimeTypes;
438     for (const auto &record : records_) {
439         if (record == nullptr) {
440             continue;
441         }
442         mimeTypes.insert(mimeTypes.end(), record->GetMimeType());
443     }
444     props_.mimeTypes = mimeTypes;
445 }
446 
Encode(std::vector<std::uint8_t> & buffer)447 bool PasteData::Encode(std::vector<std::uint8_t> &buffer)
448 {
449     Init(buffer);
450 
451     bool ret = Write(buffer, TAG_PROPS, props_);
452     ret = Write(buffer, TAG_RECORDS, records_) && ret;
453     ret = Write(buffer, TAG_DRAGGED_DATA_FLAG, isDraggedData_) && ret;
454     ret = Write(buffer, TAG_LOCAL_PASTE_FLAG, isLocalPaste_) && ret;
455     ret = Write(buffer, TAG_DELAY_DATA_FLAG, isDelayData_) && ret;
456     ret = Write(buffer, TAG_DEVICE_ID, deviceId_) && ret;
457     ret = Write(buffer, TAG_PASTE_ID, pasteId_) && ret;
458     ret = Write(buffer, TAG_DELAY_RECORD_FLAG, isDelayRecord_) && ret;
459     ret = Write(buffer, TAG_DATA_ID, dataId_) && ret;
460     return ret;
461 }
462 
InitDecodeMap()463 void PasteData::InitDecodeMap()
464 {
465     decodeMap_ = {
466         {TAG_PROPS, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
467             ret = ret && ReadValue(buffer, props_, head);}},
468         {TAG_RECORDS, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
469             ret = ret && ReadValue(buffer, records_, head);}},
470         {TAG_DRAGGED_DATA_FLAG, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
471             ret = ret && ReadValue(buffer, isDraggedData_, head);}},
472         {TAG_LOCAL_PASTE_FLAG, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
473             ret = ret && ReadValue(buffer, isLocalPaste_, head);}},
474         {TAG_DELAY_DATA_FLAG, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
475             ret = ret && ReadValue(buffer, isDelayData_, head);}},
476         {TAG_DEVICE_ID, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
477             ret = ret && ReadValue(buffer, deviceId_, head);}},
478         {TAG_PASTE_ID, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
479             ret = ret && ReadValue(buffer, pasteId_, head);}},
480         {TAG_DELAY_RECORD_FLAG, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
481             ret = ret && ReadValue(buffer, isDelayRecord_, head);}},
482         {TAG_DATA_ID, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
483             ret = ret && ReadValue(buffer, dataId_, head);}},
484     };
485 }
486 
Decode(const std::vector<std::uint8_t> & buffer)487 bool PasteData::Decode(const std::vector<std::uint8_t> &buffer)
488 {
489     total_ = buffer.size();
490     for (; IsEnough();) {
491         TLVHead head{};
492         bool ret = ReadHead(buffer, head);
493         auto it = decodeMap_.find(head.tag);
494         if (it == decodeMap_.end()) {
495             ret = ret && Skip(head.len, buffer.size());
496         } else {
497             auto func = it->second;
498             func(ret, buffer, head);
499         }
500         if (!ret) {
501             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "read value,tag:%{public}u, len:%{public}u",
502                 head.tag, head.len);
503             return false;
504         }
505     }
506     return true;
507 }
508 
Count()509 size_t PasteData::Count()
510 {
511     size_t expectSize = 0;
512     expectSize += props_.Count() + sizeof(TLVHead);
513     expectSize += TLVObject::Count(records_);
514     expectSize += TLVObject::Count(isDraggedData_);
515     expectSize += TLVObject::Count(isLocalPaste_);
516     expectSize += TLVObject::Count(isDelayData_);
517     expectSize += TLVObject::Count(deviceId_);
518     expectSize += TLVObject::Count(pasteId_);
519     expectSize += TLVObject::Count(isDelayRecord_);
520     expectSize += TLVObject::Count(dataId_);
521     return expectSize;
522 }
523 
IsValid() const524 bool PasteData::IsValid() const
525 {
526     return valid_;
527 }
528 
SetInvalid()529 void PasteData::SetInvalid()
530 {
531     valid_ = false;
532 }
533 
SetDelayData(bool isDelay)534 void PasteData::SetDelayData(bool isDelay)
535 {
536     isDelayData_ = isDelay;
537 }
538 
IsDelayData() const539 bool PasteData::IsDelayData() const
540 {
541     return isDelayData_;
542 }
543 
SetDelayRecord(bool isDelay)544 void PasteData::SetDelayRecord(bool isDelay)
545 {
546     isDelayRecord_ = isDelay;
547 }
548 
IsDelayRecord() const549 bool PasteData::IsDelayRecord() const
550 {
551     return isDelayRecord_;
552 }
553 
SetDataId(uint32_t dataId)554 void PasteData::SetDataId(uint32_t dataId)
555 {
556     dataId_ = dataId;
557 }
558 
GetDataId() const559 uint32_t PasteData::GetDataId() const
560 {
561     return dataId_;
562 }
563 
Marshalling(Parcel & parcel) const564 bool PasteData::Marshalling(Parcel &parcel) const
565 {
566     std::vector<uint8_t> pasteDataTlv(0);
567     if (!const_cast<PasteData*>(this)->Encode(pasteDataTlv)) {
568         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Encode failed");
569         return false;
570     }
571     if (!parcel.WriteUInt8Vector(pasteDataTlv)) {
572         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "WriteUInt8Vector failed");
573         return false;
574     }
575     return true;
576 }
577 
Unmarshalling(Parcel & parcel)578 PasteData* PasteData::Unmarshalling(Parcel& parcel)
579 {
580     PasteData* pasteData = new (std::nothrow) PasteData();
581     if (pasteData != nullptr && !pasteData->ReadFromParcel(parcel)) {
582         delete pasteData;
583         pasteData = nullptr;
584     }
585     return pasteData;
586 }
587 
ReadFromParcel(Parcel & parcel)588 bool PasteData::ReadFromParcel(Parcel &parcel)
589 {
590     std::vector<uint8_t> pasteDataTlv(0);
591     if (!parcel.ReadUInt8Vector(&pasteDataTlv)) {
592         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "ReadUInt8Vector failed");
593         return false;
594     }
595     if (pasteDataTlv.size() == 0) {
596         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "ReadFromParcel size  = 0 ");
597         return false;
598     }
599     if (!Decode(pasteDataTlv)) {
600         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Decode failed");
601         return false;
602     }
603     return true;
604 }
605 
PasteDataProperty(const PasteDataProperty & property)606 PasteDataProperty::PasteDataProperty(const PasteDataProperty &property)
607     : tag(property.tag), timestamp(property.timestamp), localOnly(property.localOnly),
608     shareOption(property.shareOption), tokenId(property.tokenId), isRemote(property.isRemote),
609     bundleName(property.bundleName), setTime(property.setTime), screenStatus(property.screenStatus)
610 {
611     this->additions = property.additions;
612     std::copy(property.mimeTypes.begin(), property.mimeTypes.end(), std::back_inserter(this->mimeTypes));
613 }
614 
~PasteDataProperty()615 PasteDataProperty::~PasteDataProperty()
616 {
617     mimeTypes.clear();
618 }
619 
operator =(const PasteDataProperty & property)620 PasteDataProperty& PasteDataProperty::operator=(const PasteDataProperty &property)
621 {
622     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "PasteDataProperty copy");
623     if (this == &property) {
624         return *this;
625     }
626     this->tag = property.tag;
627     this->timestamp = property.timestamp;
628     this->localOnly = property.localOnly;
629     this->shareOption = property.shareOption;
630     this->tokenId = property.tokenId;
631     this->isRemote = property.isRemote;
632     this->bundleName = property.bundleName;
633     this->setTime = property.setTime;
634     this->screenStatus = property.screenStatus;
635     this->additions = property.additions;
636     this->mimeTypes.clear();
637     std::copy(property.mimeTypes.begin(), property.mimeTypes.end(), std::back_inserter(this->mimeTypes));
638     return *this;
639 }
640 
641 
Encode(std::vector<std::uint8_t> & buffer)642 bool PasteDataProperty::Encode(std::vector<std::uint8_t> &buffer)
643 {
644     bool ret = Write(buffer, TAG_ADDITIONS, ParcelUtil::Parcelable2Raw(&additions));
645     ret = Write(buffer, TAG_MIMETYPES, mimeTypes) && ret;
646     ret = Write(buffer, TAG_TAG, tag) && ret;
647     ret = Write(buffer, TAG_LOCAL_ONLY, localOnly) && ret;
648     ret = Write(buffer, TAG_TIMESTAMP, timestamp) && ret;
649     ret = Write(buffer, TAG_SHAREOPTION, (int32_t &)shareOption) && ret;
650     ret = Write(buffer, TAG_TOKENID, tokenId) && ret;
651     ret = Write(buffer, TAG_ISREMOTE, isRemote) && ret;
652     ret = Write(buffer, TAG_BUNDLENAME, bundleName) && ret;
653     ret = Write(buffer, TAG_SETTIME, setTime) && ret;
654     ret = Write(buffer, TAG_SCREENSTATUS, (int32_t &)screenStatus) && ret;
655     return ret;
656 }
657 
Decode(const std::vector<std::uint8_t> & buffer)658 bool PasteDataProperty::Decode(const std::vector<std::uint8_t> &buffer)
659 {
660     for (; IsEnough();) {
661         if (!DecodeTag(buffer)) {
662             return false;
663         }
664     }
665     return true;
666 }
667 
DecodeTag(const std::vector<std::uint8_t> & buffer)668 bool PasteDataProperty::DecodeTag(const std::vector<std::uint8_t> &buffer)
669 {
670     TLVHead head{};
671     bool ret = ReadHead(buffer, head);
672     switch (head.tag) {
673         case TAG_ADDITIONS: {
674             RawMem rawMem{};
675             ret = ret && ReadValue(buffer, rawMem, head);
676             auto buff = ParcelUtil::Raw2Parcelable<AAFwk::WantParams>(rawMem);
677             if (buff != nullptr) {
678                 additions = *buff;
679             }
680             break;
681         }
682         case TAG_MIMETYPES:
683             ret = ret && ReadValue(buffer, mimeTypes, head);
684             break;
685         case TAG_TAG:
686             ret = ret && ReadValue(buffer, tag, head);
687             break;
688         case TAG_LOCAL_ONLY:
689             ret = ret && ReadValue(buffer, localOnly, head);
690             break;
691         case TAG_TIMESTAMP:
692             ret = ret && ReadValue(buffer, timestamp, head);
693             break;
694         case TAG_SHAREOPTION:
695             ret = ret && ReadValue(buffer, (int32_t &)shareOption, head);
696             break;
697         case TAG_TOKENID:
698             ret = ret && ReadValue(buffer, tokenId, head);
699             break;
700         case TAG_ISREMOTE:
701             ret = ret && ReadValue(buffer, isRemote, head);
702             break;
703         case TAG_BUNDLENAME:
704             ret = ret && ReadValue(buffer, bundleName, head);
705             break;
706         case TAG_SETTIME:
707             ret = ret && ReadValue(buffer, setTime, head);
708             break;
709         case TAG_SCREENSTATUS:
710             ret = ret && ReadValue(buffer, (int32_t &)screenStatus, head);
711             break;
712         default:
713             ret = ret && Skip(head.len, buffer.size());
714             break;
715     }
716     return ret;
717 }
718 
Count()719 size_t PasteDataProperty::Count()
720 {
721     size_t expectedSize = 0;
722     expectedSize += TLVObject::Count(ParcelUtil::Parcelable2Raw(&additions));
723     expectedSize += TLVObject::Count(mimeTypes);
724     expectedSize += TLVObject::Count(tag);
725     expectedSize += TLVObject::Count(localOnly);
726     expectedSize += TLVObject::Count(timestamp);
727     expectedSize += TLVObject::Count(shareOption);
728     expectedSize += TLVObject::Count(tokenId);
729     expectedSize += TLVObject::Count(isRemote);
730     expectedSize += TLVObject::Count(bundleName);
731     expectedSize += TLVObject::Count(setTime);
732     expectedSize += TLVObject::Count(screenStatus);
733     return expectedSize;
734 }
735 
WriteUriFd(MessageParcel & parcel,UriHandler & uriHandler,bool isClient)736 bool PasteData::WriteUriFd(MessageParcel &parcel, UriHandler &uriHandler, bool isClient)
737 {
738     std::vector<uint32_t> uriIndexList;
739     for (size_t i = 0; i < GetRecordCount(); ++i) {
740         auto record = GetRecordAt(i);
741         if (record == nullptr) {
742             PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "record null");
743             continue;
744         }
745         if (isLocalPaste_) {
746             PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "isLocalPaste");
747             continue;
748         }
749         if (record->NeedFd(uriHandler)) {
750             uriIndexList.push_back(i);
751         }
752     }
753     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "write fd vector size:%{public}zu", uriIndexList.size());
754     if (!parcel.WriteUInt32Vector(uriIndexList)) {
755         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Failed to write fd index vector");
756         return false;
757     }
758     for (auto index : uriIndexList) {
759         auto record = GetRecordAt(index);
760         if (record == nullptr || !record->WriteFd(parcel, uriHandler, isClient)) {
761             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Failed to write fd");
762             return false;
763         }
764     }
765     return true;
766 }
767 
ReadUriFd(MessageParcel & parcel,UriHandler & uriHandler)768 bool PasteData::ReadUriFd(MessageParcel &parcel, UriHandler &uriHandler)
769 {
770     std::vector<uint32_t> fdRecordMap;
771     if (!parcel.ReadUInt32Vector(&fdRecordMap)) {
772         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Failed to read fd index vector");
773         return false;
774     }
775     for (auto index : fdRecordMap) {
776         auto record = GetRecordAt(index);
777         if (record == nullptr || !record->ReadFd(parcel, uriHandler)) {
778             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Failed to read fd");
779             return false;
780         }
781     }
782     return true;
783 }
784 
ReplaceShareUri(int32_t userId)785 void PasteData::ReplaceShareUri(int32_t userId)
786 {
787     auto count = GetRecordCount();
788     for (size_t i = 0; i < count; ++i) {
789         auto record = GetRecordAt(i);
790         if (record == nullptr) {
791             continue;
792         }
793         record->ReplaceShareUri(userId);
794     }
795 }
796 
ShareOptionToString(ShareOption shareOption,std::string & out)797 void PasteData::ShareOptionToString(ShareOption shareOption, std::string &out)
798 {
799     if (shareOption == ShareOption::InApp) {
800         out = "InAPP";
801     } else if (shareOption == ShareOption::LocalDevice) {
802         out = "LocalDevice";
803     } else {
804         out = "CrossDevice";
805     }
806 }
807 
GetDeviceId() const808 std::string PasteData::GetDeviceId() const
809 {
810     return deviceId_;
811 }
812 
SetPasteId(const std::string & pasteId)813 void PasteData::SetPasteId(const std::string &pasteId)
814 {
815     pasteId_ = pasteId;
816 }
817 
GetPasteId() const818 std::string PasteData::GetPasteId() const
819 {
820     return pasteId_;
821 }
822 } // namespace MiscServices
823 } // namespace OHOS