• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GetPrimaryHtml()187 std::shared_ptr<std::string> PasteData::GetPrimaryHtml()
188 {
189     for (const auto &item : records_) {
190         if (item->GetHtmlText() != nullptr) {
191             return item->GetHtmlText();
192         }
193     }
194     return nullptr;
195 }
196 
GetPrimaryPixelMap()197 std::shared_ptr<PixelMap> PasteData::GetPrimaryPixelMap()
198 {
199     for (const auto &item : records_) {
200         if (item->GetPixelMap() != nullptr) {
201             return item->GetPixelMap();
202         }
203     }
204     return nullptr;
205 }
206 
GetPrimaryWant()207 std::shared_ptr<OHOS::AAFwk::Want> PasteData::GetPrimaryWant()
208 {
209     for (const auto &item : records_) {
210         if (item->GetWant() != nullptr) {
211             return item->GetWant();
212         }
213     }
214     return nullptr;
215 }
216 
GetPrimaryText()217 std::shared_ptr<std::string> PasteData::GetPrimaryText()
218 {
219     for (const auto &item : records_) {
220         if (item->GetPlainText() != nullptr) {
221             return item->GetPlainText();
222         }
223     }
224     return nullptr;
225 }
226 
GetPrimaryUri()227 std::shared_ptr<OHOS::Uri> PasteData::GetPrimaryUri()
228 {
229     for (const auto &item : records_) {
230         if (item->GetUri() != nullptr) {
231             return item->GetUri();
232         }
233     }
234     return nullptr;
235 }
236 
GetPrimaryMimeType()237 std::shared_ptr<std::string> PasteData::GetPrimaryMimeType()
238 {
239     if (!records_.empty()) {
240         return std::make_shared<std::string>(records_.front()->GetMimeType());
241     } else {
242         return nullptr;
243     }
244 }
245 
GetRecordAt(std::size_t index) const246 std::shared_ptr<PasteDataRecord> PasteData::GetRecordAt(std::size_t index) const
247 {
248     if (records_.size() > index) {
249         return records_[index];
250     } else {
251         return nullptr;
252     }
253 }
254 
GetRecordCount() const255 std::size_t PasteData::GetRecordCount() const
256 {
257     return records_.size();
258 }
259 
GetShareOption()260 ShareOption PasteData::GetShareOption()
261 {
262     return props_.shareOption;
263 }
264 
SetShareOption(ShareOption shareOption)265 void PasteData::SetShareOption(ShareOption shareOption)
266 {
267     props_.shareOption = shareOption;
268     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "shareOption = %{public}d.", shareOption);
269 }
270 
GetTokenId()271 std::uint32_t PasteData::GetTokenId()
272 {
273     return props_.tokenId;
274 }
275 
SetTokenId(uint32_t tokenId)276 void PasteData::SetTokenId(uint32_t tokenId)
277 {
278     props_.tokenId = tokenId;
279 }
280 
RemoveRecordAt(std::size_t number)281 bool PasteData::RemoveRecordAt(std::size_t number)
282 {
283     if (records_.size() > number) {
284         records_.erase(records_.begin() + static_cast<std::int64_t>(number));
285         RefreshMimeProp();
286         return true;
287     } else {
288         return false;
289     }
290 }
291 
ReplaceRecordAt(std::size_t number,std::shared_ptr<PasteDataRecord> record)292 bool PasteData::ReplaceRecordAt(std::size_t number, std::shared_ptr<PasteDataRecord> record)
293 {
294     if (record == nullptr) {
295         return false;
296     }
297     if (records_.size() > number) {
298         records_[number] = std::move(record);
299         RefreshMimeProp();
300         return true;
301     } else {
302         return false;
303     }
304 }
305 
HasMimeType(const std::string & mimeType)306 bool PasteData::HasMimeType(const std::string &mimeType)
307 {
308     for (auto &item : records_) {
309         if (item->GetMimeType() == mimeType) {
310             return true;
311         }
312     }
313     return false;
314 }
315 
AllRecords() const316 std::vector<std::shared_ptr<PasteDataRecord>> PasteData::AllRecords() const
317 {
318     return this->records_;
319 }
320 
IsDraggedData() const321 bool PasteData::IsDraggedData() const
322 {
323     return isDraggedData_;
324 }
325 
IsLocalPaste() const326 bool PasteData::IsLocalPaste() const
327 {
328     return isLocalPaste_;
329 }
330 
SetDraggedDataFlag(bool isDraggedData)331 void PasteData::SetDraggedDataFlag(bool isDraggedData)
332 {
333     isDraggedData_ = isDraggedData;
334 }
335 
SetLocalPasteFlag(bool isLocalPaste)336 void PasteData::SetLocalPasteFlag(bool isLocalPaste)
337 {
338     isLocalPaste_ = isLocalPaste;
339 }
340 
SetRemote(bool isRemote)341 void PasteData::SetRemote(bool isRemote)
342 {
343     props_.isRemote = isRemote;
344 }
345 
IsRemote()346 bool PasteData::IsRemote()
347 {
348     return props_.isRemote;
349 }
350 
SetBundleName(const std::string & bundleName)351 void PasteData::SetBundleName(const std::string &bundleName)
352 {
353     props_.bundleName = bundleName;
354 }
355 
GetBundleName() const356 std::string PasteData::GetBundleName() const
357 {
358     return props_.bundleName;
359 }
360 
SetOrginAuthority(const std::string & bundleName)361 void PasteData::SetOrginAuthority(const std::string &bundleName)
362 {
363     orginAuthority_ = bundleName;
364 }
365 
GetOrginAuthority() const366 std::string PasteData::GetOrginAuthority() const
367 {
368     return orginAuthority_;
369 }
370 
SetTime(const std::string & setTime)371 void PasteData::SetTime(const std::string &setTime)
372 {
373     props_.setTime = setTime;
374 }
375 
GetTime()376 std::string PasteData::GetTime()
377 {
378     return props_.setTime;
379 }
380 
SetScreenStatus(ScreenEvent screenStatus)381 void PasteData::SetScreenStatus(ScreenEvent screenStatus)
382 {
383     props_.screenStatus = screenStatus;
384 }
385 
GetScreenStatus()386 ScreenEvent PasteData::GetScreenStatus()
387 {
388     return props_.screenStatus;
389 }
390 
SetTag(std::string & tag)391 void PasteData::SetTag(std::string &tag)
392 {
393     props_.tag = tag;
394 }
395 
GetTag()396 std::string PasteData::GetTag()
397 {
398     return props_.tag;
399 }
400 
SetAdditions(AAFwk::WantParams & additions)401 void PasteData::SetAdditions(AAFwk::WantParams &additions)
402 {
403     props_.additions = additions;
404 }
405 
SetAddition(const std::string & key,AAFwk::IInterface * value)406 void PasteData::SetAddition(const std::string &key, AAFwk::IInterface *value)
407 {
408     props_.additions.SetParam(key, value);
409 }
410 
SetLocalOnly(bool localOnly)411 void PasteData::SetLocalOnly(bool localOnly)
412 {
413     props_.localOnly = localOnly;
414 }
415 
GetLocalOnly()416 bool PasteData::GetLocalOnly()
417 {
418     return props_.localOnly;
419 }
420 
RefreshMimeProp()421 void PasteData::RefreshMimeProp()
422 {
423     std::vector<std::string> mimeTypes;
424     for (const auto &record : records_) {
425         if (record == nullptr) {
426             continue;
427         }
428         mimeTypes.insert(mimeTypes.end(), record->GetMimeType());
429     }
430     props_.mimeTypes = mimeTypes;
431 }
432 
Encode(std::vector<std::uint8_t> & buffer)433 bool PasteData::Encode(std::vector<std::uint8_t> &buffer)
434 {
435     Init(buffer);
436 
437     bool ret = Write(buffer, TAG_PROPS, props_);
438     ret = Write(buffer, TAG_RECORDS, records_) && ret;
439     ret = Write(buffer, TAG_DRAGGED_DATA_FLAG, isDraggedData_) && ret;
440     ret = Write(buffer, TAG_LOCAL_PASTE_FLAG, isLocalPaste_) && ret;
441     ret = Write(buffer, TAG_DELAY_DATA_FLAG, isDelayData_) && ret;
442     ret = Write(buffer, TAG_DEVICE_ID, deviceId_) && ret;
443     ret = Write(buffer, TAG_PASTE_ID, pasteId_) && ret;
444     ret = Write(buffer, TAG_DELAY_RECORD_FLAG, isDelayRecord_) && ret;
445     ret = Write(buffer, TAG_DATA_ID, dataId_) && ret;
446     return ret;
447 }
448 
InitDecodeMap()449 void PasteData::InitDecodeMap()
450 {
451     decodeMap_ = {
452         {TAG_PROPS, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
453             ret = ret && ReadValue(buffer, props_, head);}},
454         {TAG_RECORDS, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
455             ret = ret && ReadValue(buffer, records_, head);}},
456         {TAG_DRAGGED_DATA_FLAG, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
457             ret = ret && ReadValue(buffer, isDraggedData_, head);}},
458         {TAG_LOCAL_PASTE_FLAG, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
459             ret = ret && ReadValue(buffer, isLocalPaste_, head);}},
460         {TAG_DELAY_DATA_FLAG, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
461             ret = ret && ReadValue(buffer, isDelayData_, head);}},
462         {TAG_DEVICE_ID, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
463             ret = ret && ReadValue(buffer, deviceId_, head);}},
464         {TAG_PASTE_ID, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
465             ret = ret && ReadValue(buffer, pasteId_, head);}},
466         {TAG_DELAY_RECORD_FLAG, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
467             ret = ret && ReadValue(buffer, isDelayRecord_, head);}},
468         {TAG_DATA_ID, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
469             ret = ret && ReadValue(buffer, dataId_, head);}},
470     };
471 }
472 
Decode(const std::vector<std::uint8_t> & buffer)473 bool PasteData::Decode(const std::vector<std::uint8_t> &buffer)
474 {
475     total_ = buffer.size();
476     for (; IsEnough();) {
477         TLVHead head{};
478         bool ret = ReadHead(buffer, head);
479         auto it = decodeMap_.find(head.tag);
480         if (it == decodeMap_.end()) {
481             ret = ret && Skip(head.len, buffer.size());
482         } else {
483             auto func = it->second;
484             func(ret, buffer, head);
485         }
486         if (!ret) {
487             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "read value,tag:%{public}u, len:%{public}u",
488                 head.tag, head.len);
489             return false;
490         }
491     }
492     return true;
493 }
494 
Count()495 size_t PasteData::Count()
496 {
497     size_t expectSize = 0;
498     expectSize += props_.Count() + sizeof(TLVHead);
499     expectSize += TLVObject::Count(records_);
500     expectSize += TLVObject::Count(isDraggedData_);
501     expectSize += TLVObject::Count(isLocalPaste_);
502     expectSize += TLVObject::Count(isDelayData_);
503     expectSize += TLVObject::Count(deviceId_);
504     expectSize += TLVObject::Count(pasteId_);
505     expectSize += TLVObject::Count(isDelayRecord_);
506     expectSize += TLVObject::Count(dataId_);
507     return expectSize;
508 }
509 
IsValid() const510 bool PasteData::IsValid() const
511 {
512     return valid_;
513 }
514 
SetInvalid()515 void PasteData::SetInvalid()
516 {
517     valid_ = false;
518 }
519 
SetDelayData(bool isDelay)520 void PasteData::SetDelayData(bool isDelay)
521 {
522     isDelayData_ = isDelay;
523 }
524 
IsDelayData() const525 bool PasteData::IsDelayData() const
526 {
527     return isDelayData_;
528 }
529 
SetDelayRecord(bool isDelay)530 void PasteData::SetDelayRecord(bool isDelay)
531 {
532     isDelayRecord_ = isDelay;
533 }
534 
IsDelayRecord() const535 bool PasteData::IsDelayRecord() const
536 {
537     return isDelayRecord_;
538 }
539 
SetDataId(uint32_t dataId)540 void PasteData::SetDataId(uint32_t dataId)
541 {
542     dataId_ = dataId;
543 }
544 
GetDataId() const545 uint32_t PasteData::GetDataId() const
546 {
547     return dataId_;
548 }
549 
Marshalling(Parcel & parcel) const550 bool PasteData::Marshalling(Parcel &parcel) const
551 {
552     std::vector<uint8_t> pasteDataTlv(0);
553     if (!const_cast<PasteData*>(this)->Encode(pasteDataTlv)) {
554         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Encode failed");
555         return false;
556     }
557     if (!parcel.WriteUInt8Vector(pasteDataTlv)) {
558         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "WriteUInt8Vector failed");
559         return false;
560     }
561     return true;
562 }
563 
Unmarshalling(Parcel & parcel)564 PasteData* PasteData::Unmarshalling(Parcel& parcel)
565 {
566     PasteData* pasteData = new (std::nothrow) PasteData();
567     if (pasteData != nullptr && !pasteData->ReadFromParcel(parcel)) {
568         delete pasteData;
569         pasteData = nullptr;
570     }
571     return pasteData;
572 }
573 
ReadFromParcel(Parcel & parcel)574 bool PasteData::ReadFromParcel(Parcel &parcel)
575 {
576     std::vector<uint8_t> pasteDataTlv(0);
577     if (!parcel.ReadUInt8Vector(&pasteDataTlv)) {
578         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "ReadUInt8Vector failed");
579         return false;
580     }
581     if (pasteDataTlv.size() == 0) {
582         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "ReadFromParcel size  = 0 ");
583         return false;
584     }
585     if (!Decode(pasteDataTlv)) {
586         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Decode failed");
587         return false;
588     }
589     return true;
590 }
591 
PasteDataProperty(const PasteDataProperty & property)592 PasteDataProperty::PasteDataProperty(const PasteDataProperty &property)
593     : tag(property.tag), timestamp(property.timestamp), localOnly(property.localOnly),
594     shareOption(property.shareOption), tokenId(property.tokenId), isRemote(property.isRemote),
595     bundleName(property.bundleName), setTime(property.setTime), screenStatus(property.screenStatus)
596 {
597     this->additions = property.additions;
598     std::copy(property.mimeTypes.begin(), property.mimeTypes.end(), std::back_inserter(this->mimeTypes));
599 }
600 
~PasteDataProperty()601 PasteDataProperty::~PasteDataProperty()
602 {
603     mimeTypes.clear();
604 }
605 
operator =(const PasteDataProperty & property)606 PasteDataProperty& PasteDataProperty::operator=(const PasteDataProperty &property)
607 {
608     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "PasteDataProperty copy");
609     if (this == &property) {
610         return *this;
611     }
612     this->tag = property.tag;
613     this->timestamp = property.timestamp;
614     this->localOnly = property.localOnly;
615     this->shareOption = property.shareOption;
616     this->tokenId = property.tokenId;
617     this->isRemote = property.isRemote;
618     this->bundleName = property.bundleName;
619     this->setTime = property.setTime;
620     this->screenStatus = property.screenStatus;
621     this->additions = property.additions;
622     this->mimeTypes.clear();
623     std::copy(property.mimeTypes.begin(), property.mimeTypes.end(), std::back_inserter(this->mimeTypes));
624     return *this;
625 }
626 
627 
Encode(std::vector<std::uint8_t> & buffer)628 bool PasteDataProperty::Encode(std::vector<std::uint8_t> &buffer)
629 {
630     bool ret = Write(buffer, TAG_ADDITIONS, ParcelUtil::Parcelable2Raw(&additions));
631     ret = Write(buffer, TAG_MIMETYPES, mimeTypes) && ret;
632     ret = Write(buffer, TAG_TAG, tag) && ret;
633     ret = Write(buffer, TAG_LOCAL_ONLY, localOnly) && ret;
634     ret = Write(buffer, TAG_TIMESTAMP, timestamp) && ret;
635     ret = Write(buffer, TAG_SHAREOPTION, (int32_t &)shareOption) && ret;
636     ret = Write(buffer, TAG_TOKENID, tokenId) && ret;
637     ret = Write(buffer, TAG_ISREMOTE, isRemote) && ret;
638     ret = Write(buffer, TAG_BUNDLENAME, bundleName) && ret;
639     ret = Write(buffer, TAG_SETTIME, setTime) && ret;
640     ret = Write(buffer, TAG_SCREENSTATUS, (int32_t &)screenStatus) && ret;
641     return ret;
642 }
643 
Decode(const std::vector<std::uint8_t> & buffer)644 bool PasteDataProperty::Decode(const std::vector<std::uint8_t> &buffer)
645 {
646     for (; IsEnough();) {
647         if (!DecodeTag(buffer)) {
648             return false;
649         }
650     }
651     return true;
652 }
653 
DecodeTag(const std::vector<std::uint8_t> & buffer)654 bool PasteDataProperty::DecodeTag(const std::vector<std::uint8_t> &buffer)
655 {
656     TLVHead head{};
657     bool ret = ReadHead(buffer, head);
658     switch (head.tag) {
659         case TAG_ADDITIONS: {
660             RawMem rawMem{};
661             ret = ret && ReadValue(buffer, rawMem, head);
662             auto buff = ParcelUtil::Raw2Parcelable<AAFwk::WantParams>(rawMem);
663             if (buff != nullptr) {
664                 additions = *buff;
665             }
666             break;
667         }
668         case TAG_MIMETYPES:
669             ret = ret && ReadValue(buffer, mimeTypes, head);
670             break;
671         case TAG_TAG:
672             ret = ret && ReadValue(buffer, tag, head);
673             break;
674         case TAG_LOCAL_ONLY:
675             ret = ret && ReadValue(buffer, localOnly, head);
676             break;
677         case TAG_TIMESTAMP:
678             ret = ret && ReadValue(buffer, timestamp, head);
679             break;
680         case TAG_SHAREOPTION:
681             ret = ret && ReadValue(buffer, (int32_t &)shareOption, head);
682             break;
683         case TAG_TOKENID:
684             ret = ret && ReadValue(buffer, tokenId, head);
685             break;
686         case TAG_ISREMOTE:
687             ret = ret && ReadValue(buffer, isRemote, head);
688             break;
689         case TAG_BUNDLENAME:
690             ret = ret && ReadValue(buffer, bundleName, head);
691             break;
692         case TAG_SETTIME:
693             ret = ret && ReadValue(buffer, setTime, head);
694             break;
695         case TAG_SCREENSTATUS:
696             ret = ret && ReadValue(buffer, (int32_t &)screenStatus, head);
697             break;
698         default:
699             ret = ret && Skip(head.len, buffer.size());
700             break;
701     }
702     return ret;
703 }
704 
Count()705 size_t PasteDataProperty::Count()
706 {
707     size_t expectedSize = 0;
708     expectedSize += TLVObject::Count(ParcelUtil::Parcelable2Raw(&additions));
709     expectedSize += TLVObject::Count(mimeTypes);
710     expectedSize += TLVObject::Count(tag);
711     expectedSize += TLVObject::Count(localOnly);
712     expectedSize += TLVObject::Count(timestamp);
713     expectedSize += TLVObject::Count(shareOption);
714     expectedSize += TLVObject::Count(tokenId);
715     expectedSize += TLVObject::Count(isRemote);
716     expectedSize += TLVObject::Count(bundleName);
717     expectedSize += TLVObject::Count(setTime);
718     expectedSize += TLVObject::Count(screenStatus);
719     return expectedSize;
720 }
721 
WriteUriFd(MessageParcel & parcel,UriHandler & uriHandler,bool isClient)722 bool PasteData::WriteUriFd(MessageParcel &parcel, UriHandler &uriHandler, bool isClient)
723 {
724     std::vector<uint32_t> uriIndexList;
725     for (size_t i = 0; i < GetRecordCount(); ++i) {
726         auto record = GetRecordAt(i);
727         if (record == nullptr) {
728             PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "record null");
729             continue;
730         }
731         if (isLocalPaste_) {
732             PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "isLocalPaste");
733             continue;
734         }
735         if (record->NeedFd(uriHandler)) {
736             uriIndexList.push_back(i);
737         }
738     }
739     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "write fd vector size:%{public}zu", uriIndexList.size());
740     if (!parcel.WriteUInt32Vector(uriIndexList)) {
741         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Failed to write fd index vector");
742         return false;
743     }
744     for (auto index : uriIndexList) {
745         auto record = GetRecordAt(index);
746         if (record == nullptr || !record->WriteFd(parcel, uriHandler, isClient)) {
747             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Failed to write fd");
748             return false;
749         }
750     }
751     return true;
752 }
753 
ReadUriFd(MessageParcel & parcel,UriHandler & uriHandler)754 bool PasteData::ReadUriFd(MessageParcel &parcel, UriHandler &uriHandler)
755 {
756     std::vector<uint32_t> fdRecordMap;
757     if (!parcel.ReadUInt32Vector(&fdRecordMap)) {
758         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Failed to read fd index vector");
759         return false;
760     }
761     for (auto index : fdRecordMap) {
762         auto record = GetRecordAt(index);
763         if (record == nullptr || !record->ReadFd(parcel, uriHandler)) {
764             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Failed to read fd");
765             return false;
766         }
767     }
768     return true;
769 }
770 
ReplaceShareUri(int32_t userId)771 void PasteData::ReplaceShareUri(int32_t userId)
772 {
773     auto count = GetRecordCount();
774     for (size_t i = 0; i < count; ++i) {
775         auto record = GetRecordAt(i);
776         if (record == nullptr) {
777             continue;
778         }
779         record->ReplaceShareUri(userId);
780     }
781 }
782 
ShareOptionToString(ShareOption shareOption,std::string & out)783 void PasteData::ShareOptionToString(ShareOption shareOption, std::string &out)
784 {
785     if (shareOption == ShareOption::InApp) {
786         out = "InAPP";
787     } else if (shareOption == ShareOption::LocalDevice) {
788         out = "LocalDevice";
789     } else {
790         out = "CrossDevice";
791     }
792 }
793 
GetDeviceId() const794 std::string PasteData::GetDeviceId() const
795 {
796     return deviceId_;
797 }
798 
SetPasteId(const std::string & pasteId)799 void PasteData::SetPasteId(const std::string &pasteId)
800 {
801     pasteId_ = pasteId;
802 }
803 
GetPasteId() const804 std::string PasteData::GetPasteId() const
805 {
806     return pasteId_;
807 }
808 } // namespace MiscServices
809 } // namespace OHOS