• 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 "int_wrapper.h"
20 #include "ipc_skeleton.h"
21 #include "long_wrapper.h"
22 #include "pasteboard_common.h"
23 #include "pasteboard_hilog.h"
24 
25 using namespace std::chrono;
26 using namespace OHOS::Media;
27 
28 namespace OHOS {
29 namespace MiscServices {
30 enum TAG_PASTEBOARD : uint16_t {
31     TAG_PROPS = TAG_BUFF + 1,
32     TAG_RECORDS,
33     TAG_DRAGGED_DATA_FLAG,
34     TAG_LOCAL_PASTE_FLAG,
35     TAG_DELAY_DATA_FLAG,
36     TAG_DEVICE_ID,
37     TAG_PASTE_ID,
38     TAG_DELAY_RECORD_FLAG,
39     TAG_DATA_ID,
40     TAG_RECORD_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_SCREEN_STATUS,
54 };
55 
56 std::string PasteData::WEBVIEW_PASTEDATA_TAG = "WebviewPasteDataTag";
57 const char *REMOTE_FILE_SIZE = "remoteFileSize";
58 const char *REMOTE_FILE_SIZE_LONG = "remoteFileSizeLong";
59 constexpr int32_t SUB_PASTEID_NUM = 3;
60 constexpr int32_t PASTEID_MAX_SIZE = 1024;
61 
PasteData()62 PasteData::PasteData()
63 {
64     props_.timestamp = steady_clock::now().time_since_epoch().count();
65     props_.localOnly = false;
66     props_.shareOption = ShareOption::CrossDevice;
67 }
68 
~PasteData()69 PasteData::~PasteData() {}
70 
PasteData(const PasteData & data)71 PasteData::PasteData(const PasteData &data)
72     : valid_(data.valid_), isDraggedData_(data.isDraggedData_), isLocalPaste_(data.isLocalPaste_),
73       isDelayData_(data.isDelayData_), isDelayRecord_(data.isDelayRecord_), dataId_(data.dataId_),
74       recordId_(data.recordId_), originAuthority_(data.originAuthority_), pasteId_(data.pasteId_)
75 {
76     this->props_ = data.props_;
77     for (const auto &item : data.records_) {
78         this->records_.emplace_back(std::make_shared<PasteDataRecord>(*item));
79     }
80 }
81 
PasteData(std::vector<std::shared_ptr<PasteDataRecord>> records)82 PasteData::PasteData(std::vector<std::shared_ptr<PasteDataRecord>> records) : records_{ std::move(records) }
83 {
84     for (const auto &item : records_) {
85         PASTEBOARD_CHECK_AND_RETURN_LOGE(item != nullptr, PASTEBOARD_MODULE_CLIENT, "record is null");
86         item->SetRecordId(++recordId_);
87     }
88     props_.timestamp = steady_clock::now().time_since_epoch().count();
89     props_.localOnly = false;
90     props_.shareOption = ShareOption::CrossDevice;
91 }
92 
operator =(const PasteData & data)93 PasteData &PasteData::operator=(const PasteData &data)
94 {
95     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "PasteData copy");
96     if (this == &data) {
97         return *this;
98     }
99     this->originAuthority_ = data.originAuthority_;
100     this->valid_ = data.valid_;
101     this->isDraggedData_ = data.isDraggedData_;
102     this->isLocalPaste_ = data.isLocalPaste_;
103     this->isDelayData_ = data.isDelayData_;
104     this->isDelayRecord_ = data.isDelayRecord_;
105     this->dataId_ = data.dataId_;
106     this->props_ = data.props_;
107     this->records_.clear();
108     this->deviceId_ = data.deviceId_;
109     this->pasteId_ = data.pasteId_;
110     for (const auto &item : data.records_) {
111         this->records_.emplace_back(std::make_shared<PasteDataRecord>(*item));
112     }
113     this->recordId_ = data.GetRecordId();
114     return *this;
115 }
116 
GetProperty() const117 PasteDataProperty PasteData::GetProperty() const
118 {
119     return PasteDataProperty(props_);
120 }
121 
SetProperty(const PasteDataProperty & property)122 void PasteData::SetProperty(const PasteDataProperty &property)
123 {
124     this->props_ = property;
125 }
126 
AddHtmlRecord(const std::string & html)127 void PasteData::AddHtmlRecord(const std::string &html)
128 {
129     this->AddRecord(PasteDataRecord::NewHtmlRecord(html));
130 }
131 
AddPixelMapRecord(std::shared_ptr<PixelMap> pixelMap)132 void PasteData::AddPixelMapRecord(std::shared_ptr<PixelMap> pixelMap)
133 {
134     this->AddRecord(PasteDataRecord::NewPixelMapRecord(std::move(pixelMap)));
135 }
136 
AddWantRecord(std::shared_ptr<OHOS::AAFwk::Want> want)137 void PasteData::AddWantRecord(std::shared_ptr<OHOS::AAFwk::Want> want)
138 {
139     this->AddRecord(PasteDataRecord::NewWantRecord(std::move(want)));
140 }
141 
AddTextRecord(const std::string & text)142 void PasteData::AddTextRecord(const std::string &text)
143 {
144     this->AddRecord(PasteDataRecord::NewPlainTextRecord(text));
145 }
146 
AddUriRecord(const OHOS::Uri & uri)147 void PasteData::AddUriRecord(const OHOS::Uri &uri)
148 {
149     this->AddRecord(PasteDataRecord::NewUriRecord(uri));
150 }
151 
AddKvRecord(const std::string & mimeType,const std::vector<uint8_t> & arrayBuffer)152 void PasteData::AddKvRecord(const std::string &mimeType, const std::vector<uint8_t> &arrayBuffer)
153 {
154     AddRecord(PasteDataRecord::NewKvRecord(mimeType, arrayBuffer));
155 }
156 
AddRecord(std::shared_ptr<PasteDataRecord> record)157 void PasteData::AddRecord(std::shared_ptr<PasteDataRecord> record)
158 {
159     PASTEBOARD_CHECK_AND_RETURN_LOGE(record != nullptr, PASTEBOARD_MODULE_CLIENT, "record is null");
160     record->SetRecordId(++recordId_);
161 
162     if (PasteBoardCommon::IsPasteboardService()) {
163         props_.mimeTypes.emplace_back(record->GetMimeType());
164         records_.emplace_back(std::move(record));
165     } else {
166         props_.mimeTypes.insert(props_.mimeTypes.begin(), record->GetMimeType());
167         records_.insert(records_.begin(), std::move(record));
168     }
169 }
170 
AddRecord(const PasteDataRecord & record)171 void PasteData::AddRecord(const PasteDataRecord &record)
172 {
173     this->AddRecord(std::make_shared<PasteDataRecord>(record));
174 }
175 
GetMimeTypes()176 std::vector<std::string> PasteData::GetMimeTypes()
177 {
178     std::set<std::string> mimeTypes;
179     for (const auto &item : records_) {
180         if (item->GetFrom() > 0 && item->GetRecordId() != item->GetFrom()) {
181             continue;
182         }
183         auto itemTypes = item->GetMimeTypes();
184         mimeTypes.insert(itemTypes.begin(), itemTypes.end());
185     }
186     return std::vector<std::string>(mimeTypes.begin(), mimeTypes.end());
187 }
188 
GetReportMimeTypes()189 std::vector<std::string> PasteData::GetReportMimeTypes()
190 {
191     std::vector<std::string> mimeTypes;
192     uint32_t recordNum = records_.size();
193     uint32_t maxReportNum = recordNum > MAX_REPORT_RECORD_NUM ? MAX_REPORT_RECORD_NUM : recordNum;
194     for (uint32_t i = 0; i < maxReportNum; ++i) {
195         auto &item = records_[i];
196         if (item == nullptr) {
197             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "record is nullptr.");
198             mimeTypes.emplace_back("NULL");
199             continue;
200         }
201         if (item->GetFrom() > 0 && item->GetRecordId() != item->GetFrom()) {
202             mimeTypes.emplace_back("web/uri");
203             continue;
204         }
205         auto itemTypes = item->GetMimeTypes();
206         mimeTypes.insert(mimeTypes.end(), itemTypes.begin(), itemTypes.end());
207     }
208     return mimeTypes;
209 }
210 
GetReportDescription()211 DataDescription PasteData::GetReportDescription()
212 {
213     DataDescription description;
214     description.recordNum = records_.size();
215     description.mimeTypes = GetReportMimeTypes();
216     for (uint32_t i = 0; i < description.recordNum; i++) {
217         auto record = GetRecordAt(i);
218         if (record == nullptr) {
219             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "GetRecordAt(%{public}u) failed.", i);
220             description.entryNum.push_back(-1);
221             continue;
222         }
223         auto entries = record->GetEntries();
224         description.entryNum.push_back(entries.size());
225     }
226     return description;
227 }
228 
GetPrimaryHtml()229 std::shared_ptr<std::string> PasteData::GetPrimaryHtml()
230 {
231     for (const auto &item : records_) {
232         std::shared_ptr<std::string> primary = item->GetHtmlText();
233         if (primary) {
234             return primary;
235         }
236     }
237     return nullptr;
238 }
239 
GetPrimaryPixelMap()240 std::shared_ptr<PixelMap> PasteData::GetPrimaryPixelMap()
241 {
242     for (const auto &item : records_) {
243         std::shared_ptr<PixelMap> primary = item->GetPixelMap();
244         if (primary) {
245             return primary;
246         }
247     }
248     return nullptr;
249 }
250 
GetPrimaryWant()251 std::shared_ptr<OHOS::AAFwk::Want> PasteData::GetPrimaryWant()
252 {
253     for (const auto &item : records_) {
254         std::shared_ptr<OHOS::AAFwk::Want> primary = item->GetWant();
255         if (primary) {
256             return primary;
257         }
258     }
259     return nullptr;
260 }
261 
GetPrimaryText()262 std::shared_ptr<std::string> PasteData::GetPrimaryText()
263 {
264     for (const auto &item : records_) {
265         std::shared_ptr<std::string> primary = item->GetPlainText();
266         if (primary) {
267             return primary;
268         }
269     }
270     return nullptr;
271 }
272 
GetPrimaryUri()273 std::shared_ptr<OHOS::Uri> PasteData::GetPrimaryUri()
274 {
275     for (const auto &item : records_) {
276         std::shared_ptr<OHOS::Uri> primary = item->GetUri();
277         if (primary) {
278             return primary;
279         }
280     }
281     return nullptr;
282 }
283 
GetPrimaryMimeType()284 std::shared_ptr<std::string> PasteData::GetPrimaryMimeType()
285 {
286     if (records_.empty()) {
287         return nullptr;
288     }
289     return std::make_shared<std::string>(records_.front()->GetMimeType());
290 }
291 
GetRecordAt(std::size_t index) const292 std::shared_ptr<PasteDataRecord> PasteData::GetRecordAt(std::size_t index) const
293 {
294     if (records_.size() > index) {
295         return records_[index];
296     } else {
297         return nullptr;
298     }
299 }
300 
GetRecordById(uint32_t recordId) const301 std::shared_ptr<PasteDataRecord> PasteData::GetRecordById(uint32_t recordId) const
302 {
303     for (const auto &record : records_) {
304         if (record != nullptr && record->GetRecordId() == recordId) {
305             return record;
306         }
307     }
308     return nullptr;
309 }
310 
GetRecordCount() const311 std::size_t PasteData::GetRecordCount() const
312 {
313     return records_.size();
314 }
315 
GetShareOption()316 ShareOption PasteData::GetShareOption()
317 {
318     return props_.shareOption;
319 }
320 
SetShareOption(ShareOption shareOption)321 void PasteData::SetShareOption(ShareOption shareOption)
322 {
323     props_.shareOption = shareOption;
324     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "shareOption = %{public}d.", shareOption);
325 }
326 
GetTokenId()327 std::uint32_t PasteData::GetTokenId()
328 {
329     return props_.tokenId;
330 }
331 
SetTokenId(uint32_t tokenId)332 void PasteData::SetTokenId(uint32_t tokenId)
333 {
334     props_.tokenId = tokenId;
335 }
336 
RemoveRecordAt(std::size_t number)337 bool PasteData::RemoveRecordAt(std::size_t number)
338 {
339     if (records_.size() > number) {
340         records_.erase(records_.begin() + static_cast<std::int64_t>(number));
341         RefreshMimeProp();
342         return true;
343     } else {
344         return false;
345     }
346 }
347 
ReplaceRecordAt(std::size_t number,std::shared_ptr<PasteDataRecord> record)348 bool PasteData::ReplaceRecordAt(std::size_t number, std::shared_ptr<PasteDataRecord> record)
349 {
350     if (record == nullptr) {
351         return false;
352     }
353     if (records_.size() > number) {
354         records_[number] = std::move(record);
355         RefreshMimeProp();
356         return true;
357     } else {
358         return false;
359     }
360 }
361 
HasMimeType(const std::string & mimeType)362 bool PasteData::HasMimeType(const std::string &mimeType)
363 {
364     for (const auto &item : records_) {
365         auto itemTypes = item->GetMimeTypes();
366         if (itemTypes.find(mimeType) != itemTypes.end()) {
367             return true;
368         }
369     }
370     return false;
371 }
372 
AllRecords() const373 std::vector<std::shared_ptr<PasteDataRecord>> PasteData::AllRecords() const
374 {
375     return this->records_;
376 }
377 
IsDraggedData() const378 bool PasteData::IsDraggedData() const
379 {
380     return isDraggedData_;
381 }
382 
IsLocalPaste() const383 bool PasteData::IsLocalPaste() const
384 {
385     return isLocalPaste_;
386 }
387 
SetDraggedDataFlag(bool isDraggedData)388 void PasteData::SetDraggedDataFlag(bool isDraggedData)
389 {
390     isDraggedData_ = isDraggedData;
391 }
392 
SetLocalPasteFlag(bool isLocalPaste)393 void PasteData::SetLocalPasteFlag(bool isLocalPaste)
394 {
395     isLocalPaste_ = isLocalPaste;
396 }
397 
SetRemote(bool isRemote)398 void PasteData::SetRemote(bool isRemote)
399 {
400     props_.isRemote = isRemote;
401 }
402 
IsRemote() const403 bool PasteData::IsRemote() const
404 {
405     return props_.isRemote;
406 }
407 
SetBundleInfo(const std::string & bundleName,int32_t appIndex)408 void PasteData::SetBundleInfo(const std::string &bundleName, int32_t appIndex)
409 {
410     props_.bundleName = bundleName;
411     props_.appIndex = appIndex;
412 }
413 
GetBundleName() const414 std::string PasteData::GetBundleName() const
415 {
416     return props_.bundleName;
417 }
418 
GetAppIndex() const419 int32_t PasteData::GetAppIndex() const
420 {
421     return props_.appIndex;
422 }
423 
SetOriginAuthority(const std::pair<std::string,int32_t> & bundleIndex)424 void PasteData::SetOriginAuthority(const std::pair<std::string, int32_t> &bundleIndex)
425 {
426     originAuthority_ = bundleIndex;
427 }
428 
GetOriginAuthority() const429 std::pair<std::string, int32_t> PasteData::GetOriginAuthority() const
430 {
431     return originAuthority_;
432 }
433 
SetTime(const std::string & setTime)434 void PasteData::SetTime(const std::string &setTime)
435 {
436     props_.setTime = setTime;
437 }
438 
GetTime()439 std::string PasteData::GetTime()
440 {
441     return props_.setTime;
442 }
443 
SetScreenStatus(ScreenEvent screenStatus)444 void PasteData::SetScreenStatus(ScreenEvent screenStatus)
445 {
446     props_.screenStatus = screenStatus;
447 }
448 
GetScreenStatus()449 ScreenEvent PasteData::GetScreenStatus()
450 {
451     return props_.screenStatus;
452 }
453 
SetTag(const std::string & tag)454 void PasteData::SetTag(const std::string &tag)
455 {
456     props_.tag = tag;
457 }
458 
GetTag()459 std::string PasteData::GetTag()
460 {
461     return props_.tag;
462 }
463 
SetAdditions(const AAFwk::WantParams & additions)464 void PasteData::SetAdditions(const AAFwk::WantParams &additions)
465 {
466     props_.additions = additions;
467 }
468 
SetAddition(const std::string & key,AAFwk::IInterface * value)469 void PasteData::SetAddition(const std::string &key, AAFwk::IInterface *value)
470 {
471     PASTEBOARD_CHECK_AND_RETURN_LOGE(value != nullptr, PASTEBOARD_MODULE_CLIENT, "value is null");
472     props_.additions.SetParam(key, value);
473 }
474 
SetFileSize(int64_t fileSize)475 void PasteData::SetFileSize(int64_t fileSize)
476 {
477     int32_t fileIntSize = (fileSize > INT_MAX) ? INT_MAX : static_cast<int32_t>(fileSize);
478     SetAddition(REMOTE_FILE_SIZE, AAFwk::Integer::Box(fileIntSize));
479     SetAddition(REMOTE_FILE_SIZE_LONG, AAFwk::Long::Box(fileSize));
480 }
481 
GetFileSize() const482 int64_t PasteData::GetFileSize() const
483 {
484     int64_t fileSize = 0L;
485     auto value = props_.additions.GetParam(REMOTE_FILE_SIZE_LONG);
486     AAFwk::ILong *ao = AAFwk::ILong::Query(value);
487     if (ao != nullptr) {
488         fileSize = AAFwk::Long::Unbox(ao);
489     } else {
490         fileSize = props_.additions.GetIntParam(REMOTE_FILE_SIZE, -1);
491     }
492     return fileSize;
493 }
494 
SetLocalOnly(bool localOnly)495 void PasteData::SetLocalOnly(bool localOnly)
496 {
497     props_.localOnly = localOnly;
498 }
499 
GetLocalOnly()500 bool PasteData::GetLocalOnly()
501 {
502     return props_.localOnly;
503 }
504 
RefreshMimeProp()505 void PasteData::RefreshMimeProp()
506 {
507     std::vector<std::string> mimeTypes;
508     for (const auto &record : records_) {
509         if (record == nullptr) {
510             continue;
511         }
512         mimeTypes.emplace_back(record->GetMimeType());
513     }
514     props_.mimeTypes = mimeTypes;
515 }
516 
EncodeTLV(WriteOnlyBuffer & buffer) const517 bool PasteData::EncodeTLV(WriteOnlyBuffer &buffer) const
518 {
519     bool ret = buffer.Write(TAG_PROPS, props_);
520     ret = ret && buffer.Write(TAG_RECORDS, records_);
521     ret = ret && buffer.Write(TAG_DRAGGED_DATA_FLAG, isDraggedData_);
522     ret = ret && buffer.Write(TAG_LOCAL_PASTE_FLAG, isLocalPaste_);
523     ret = ret && buffer.Write(TAG_DELAY_DATA_FLAG, isDelayData_);
524     ret = ret && buffer.Write(TAG_DEVICE_ID, deviceId_);
525     ret = ret && buffer.Write(TAG_PASTE_ID, pasteId_);
526     ret = ret && buffer.Write(TAG_DELAY_RECORD_FLAG, isDelayRecord_);
527     ret = ret && buffer.Write(TAG_DATA_ID, dataId_);
528     ret = ret && buffer.Write(TAG_RECORD_ID, recordId_);
529     return ret;
530 }
531 
DecodeTLV(ReadOnlyBuffer & buffer)532 bool PasteData::DecodeTLV(ReadOnlyBuffer &buffer)
533 {
534     for (; buffer.IsEnough();) {
535         TLVHead head{};
536         bool ret = buffer.ReadHead(head);
537         PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret, false, PASTEBOARD_MODULE_COMMON, "read head failed");
538         if (head.tag == TAG_PROPS) {
539             ret = buffer.ReadValue(props_, head);
540         } else if (head.tag == TAG_RECORDS) {
541             ret = buffer.ReadValue(records_, head);
542         } else if (head.tag == TAG_DRAGGED_DATA_FLAG) {
543             ret = buffer.ReadValue(isDraggedData_, head);
544         } else if (head.tag == TAG_LOCAL_PASTE_FLAG) {
545             ret = buffer.ReadValue(isLocalPaste_, head);
546         } else if (head.tag == TAG_DELAY_DATA_FLAG) {
547             ret = buffer.ReadValue(isDelayData_, head);
548         } else if (head.tag == TAG_DEVICE_ID) {
549             ret = buffer.ReadValue(deviceId_, head);
550         } else if (head.tag == TAG_PASTE_ID) {
551             ret = buffer.ReadValue(pasteId_, head);
552         } else if (head.tag == TAG_DELAY_RECORD_FLAG) {
553             ret = buffer.ReadValue(isDelayRecord_, head);
554         } else if (head.tag == TAG_DATA_ID) {
555             ret = buffer.ReadValue(dataId_, head);
556         } else if (head.tag == TAG_RECORD_ID) {
557             ret = buffer.ReadValue(recordId_, head);
558         } else {
559             ret = buffer.Skip(head.len);
560         }
561         PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret, false, PASTEBOARD_MODULE_COMMON,
562             "read value failed, tag=%{public}hu, len=%{public}u", head.tag, head.len);
563     }
564     return true;
565 }
566 
CountTLV() const567 size_t PasteData::CountTLV() const
568 {
569     size_t expectSize = 0;
570     expectSize += TLVCountable::Count(props_);
571     expectSize += TLVCountable::Count(records_);
572     expectSize += TLVCountable::Count(isDraggedData_);
573     expectSize += TLVCountable::Count(isLocalPaste_);
574     expectSize += TLVCountable::Count(isDelayData_);
575     expectSize += TLVCountable::Count(deviceId_);
576     expectSize += TLVCountable::Count(pasteId_);
577     expectSize += TLVCountable::Count(isDelayRecord_);
578     expectSize += TLVCountable::Count(dataId_);
579     expectSize += TLVCountable::Count(recordId_);
580     return expectSize;
581 }
582 
IsValid() const583 bool PasteData::IsValid() const
584 {
585     return valid_;
586 }
587 
SetInvalid()588 void PasteData::SetInvalid()
589 {
590     valid_ = false;
591 }
592 
SetDelayData(bool isDelay)593 void PasteData::SetDelayData(bool isDelay)
594 {
595     isDelayData_ = isDelay;
596 }
597 
IsDelayData() const598 bool PasteData::IsDelayData() const
599 {
600     return isDelayData_;
601 }
602 
SetDelayRecord(bool isDelay)603 void PasteData::SetDelayRecord(bool isDelay)
604 {
605     isDelayRecord_ = isDelay;
606 }
607 
IsDelayRecord() const608 bool PasteData::IsDelayRecord() const
609 {
610     return isDelayRecord_;
611 }
612 
SetDataId(uint32_t dataId)613 void PasteData::SetDataId(uint32_t dataId)
614 {
615     dataId_ = dataId;
616 }
617 
GetDataId() const618 uint32_t PasteData::GetDataId() const
619 {
620     return dataId_;
621 }
622 
GetRecordId() const623 uint32_t PasteData::GetRecordId() const
624 {
625     return recordId_;
626 }
627 
Marshalling(Parcel & parcel) const628 bool PasteData::Marshalling(Parcel &parcel) const
629 {
630     std::vector<uint8_t> pasteDataTlv(0);
631     bool ret = Encode(pasteDataTlv);
632     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret, false, PASTEBOARD_MODULE_COMMON, "encode failed");
633 
634     ret = parcel.WriteUInt8Vector(pasteDataTlv);
635     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret, false, PASTEBOARD_MODULE_COMMON, "write vector failed");
636     return true;
637 }
638 
Unmarshalling(Parcel & parcel)639 PasteData *PasteData::Unmarshalling(Parcel &parcel)
640 {
641     std::vector<uint8_t> pasteDataTlv(0);
642     bool ret = parcel.ReadUInt8Vector(&pasteDataTlv);
643     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret, nullptr, PASTEBOARD_MODULE_COMMON, "read vector failed");
644     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(!pasteDataTlv.empty(), nullptr, PASTEBOARD_MODULE_COMMON, "vector empty");
645 
646     PasteData *pasteData = new (std::nothrow) PasteData();
647     if (!pasteData->Decode(pasteDataTlv)) {
648         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_COMMON, "decode failed");
649         delete pasteData;
650         pasteData = nullptr;
651     }
652     return pasteData;
653 }
654 
PasteDataProperty(const PasteDataProperty & property)655 PasteDataProperty::PasteDataProperty(const PasteDataProperty &property)
656     : tag(property.tag), timestamp(property.timestamp), localOnly(property.localOnly),
657       shareOption(property.shareOption), tokenId(property.tokenId), isRemote(property.isRemote),
658       bundleName(property.bundleName), setTime(property.setTime), screenStatus(property.screenStatus)
659 {
660     this->additions = property.additions;
661     std::copy(property.mimeTypes.begin(), property.mimeTypes.end(), std::back_inserter(this->mimeTypes));
662 }
663 
~PasteDataProperty()664 PasteDataProperty::~PasteDataProperty()
665 {
666     std::vector<std::string>().swap(mimeTypes);
667 }
668 
operator =(const PasteDataProperty & property)669 PasteDataProperty &PasteDataProperty::operator=(const PasteDataProperty &property)
670 {
671     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "PasteDataProperty copy");
672     if (this == &property) {
673         return *this;
674     }
675     this->tag = property.tag;
676     this->timestamp = property.timestamp;
677     this->localOnly = property.localOnly;
678     this->shareOption = property.shareOption;
679     this->tokenId = property.tokenId;
680     this->isRemote = property.isRemote;
681     this->bundleName = property.bundleName;
682     this->setTime = property.setTime;
683     this->screenStatus = property.screenStatus;
684     this->additions = property.additions;
685     std::vector<std::string>().swap(this->mimeTypes);
686     std::copy(property.mimeTypes.begin(), property.mimeTypes.end(), std::back_inserter(this->mimeTypes));
687     return *this;
688 }
689 
EncodeTLV(WriteOnlyBuffer & buffer) const690 bool PasteDataProperty::EncodeTLV(WriteOnlyBuffer &buffer) const
691 {
692     bool ret = buffer.Write(TAG_ADDITIONS, TLVUtils::Parcelable2Raw(&additions));
693     ret = ret && buffer.Write(TAG_MIMETYPES, mimeTypes);
694     ret = ret && buffer.Write(TAG_TAG, tag);
695     ret = ret && buffer.Write(TAG_LOCAL_ONLY, localOnly);
696     ret = ret && buffer.Write(TAG_TIMESTAMP, timestamp);
697     ret = ret && buffer.Write(TAG_SHAREOPTION, static_cast<int32_t>(shareOption));
698     ret = ret && buffer.Write(TAG_TOKENID, tokenId);
699     ret = ret && buffer.Write(TAG_ISREMOTE, isRemote);
700     ret = ret && buffer.Write(TAG_BUNDLENAME, bundleName);
701     ret = ret && buffer.Write(TAG_SETTIME, setTime);
702     ret = ret && buffer.Write(TAG_SCREEN_STATUS, static_cast<int32_t>(screenStatus));
703     return ret;
704 }
705 
DecodeTLV(ReadOnlyBuffer & buffer)706 bool PasteDataProperty::DecodeTLV(ReadOnlyBuffer &buffer)
707 {
708     for (; buffer.IsEnough();) {
709         TLVHead head{};
710         bool ret = buffer.ReadHead(head);
711         PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret, false, PASTEBOARD_MODULE_COMMON, "read head failed");
712         if (head.tag == TAG_ADDITIONS) {
713             RawMem rawMem{};
714             ret = buffer.ReadValue(rawMem, head);
715             auto buff = TLVUtils::Raw2Parcelable<AAFwk::WantParams>(rawMem);
716             additions = (buff != nullptr) ? *buff : additions;
717         } else if (head.tag == TAG_MIMETYPES) {
718             ret = buffer.ReadValue(mimeTypes, head);
719         } else if (head.tag == TAG_TAG) {
720             ret = buffer.ReadValue(tag, head);
721         } else if (head.tag == TAG_LOCAL_ONLY) {
722             ret = buffer.ReadValue(localOnly, head);
723         } else if (head.tag == TAG_TIMESTAMP) {
724             ret = buffer.ReadValue(timestamp, head);
725         } else if (head.tag == TAG_SHAREOPTION) {
726             ret = buffer.ReadValue((int32_t &)shareOption, head);
727         } else if (head.tag == TAG_TOKENID) {
728             ret = buffer.ReadValue(tokenId, head);
729         } else if (head.tag == TAG_ISREMOTE) {
730             ret = buffer.ReadValue(isRemote, head);
731         } else if (head.tag == TAG_BUNDLENAME) {
732             ret = buffer.ReadValue(bundleName, head);
733         } else if (head.tag == TAG_SETTIME) {
734             ret = buffer.ReadValue(setTime, head);
735         } else if (head.tag == TAG_SCREEN_STATUS) {
736             ret = buffer.ReadValue((int32_t &)screenStatus, head);
737         } else {
738             ret = buffer.Skip(head.len);
739         }
740         PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret, false, PASTEBOARD_MODULE_COMMON,
741             "read value failed, tag=%{public}hu, len=%{public}u", head.tag, head.len);
742     }
743     return true;
744 }
745 
CountTLV() const746 size_t PasteDataProperty::CountTLV() const
747 {
748     size_t expectedSize = 0;
749     expectedSize += TLVCountable::Count(TLVUtils::Parcelable2Raw(&additions));
750     expectedSize += TLVCountable::Count(mimeTypes);
751     expectedSize += TLVCountable::Count(tag);
752     expectedSize += TLVCountable::Count(localOnly);
753     expectedSize += TLVCountable::Count(timestamp);
754     expectedSize += TLVCountable::Count(shareOption);
755     expectedSize += TLVCountable::Count(tokenId);
756     expectedSize += TLVCountable::Count(isRemote);
757     expectedSize += TLVCountable::Count(bundleName);
758     expectedSize += TLVCountable::Count(setTime);
759     expectedSize += TLVCountable::Count(screenStatus);
760     return expectedSize;
761 }
762 
ShareOptionToString(ShareOption shareOption,std::string & out)763 void PasteData::ShareOptionToString(ShareOption shareOption, std::string &out)
764 {
765     if (shareOption == ShareOption::InApp) {
766         out = "InAPP";
767     } else if (shareOption == ShareOption::LocalDevice) {
768         out = "LocalDevice";
769     } else {
770         out = "CrossDevice";
771     }
772 }
773 
CreatePasteId(const std::string & name,uint32_t sequence)774 std::string PasteData::CreatePasteId(const std::string &name, uint32_t sequence)
775 {
776     std::string currentId = name + "_" + std::to_string(getpid()) + "_" + std::to_string(sequence);
777     return currentId;
778 }
779 
IsValidShareOption(int32_t shareOption)780 bool PasteData::IsValidShareOption(int32_t shareOption)
781 {
782     switch (static_cast<ShareOption>(shareOption)) {
783         case ShareOption::InApp:
784             [[fallthrough]];
785         case ShareOption::LocalDevice:
786             [[fallthrough]];
787         case ShareOption::CrossDevice:
788             return true;
789         default:
790             return false;
791     }
792 }
793 
IsValidPasteId(const std::string & pasteId)794 bool PasteData::IsValidPasteId(const std::string &pasteId)
795 {
796     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(!pasteId.empty() && pasteId.size() < PASTEID_MAX_SIZE, false,
797         PASTEBOARD_MODULE_SERVICE, "calling pid mismatch");
798     std::vector<std::string> subStrs;
799     size_t pos = 0;
800     size_t delimiterPos;
801     while ((delimiterPos = pasteId.find('_', pos)) != std::string::npos) {
802         subStrs.push_back(pasteId.substr(pos, delimiterPos - pos));
803         pos = delimiterPos + 1;
804     }
805     subStrs.push_back(pasteId.substr(pos));
806     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(subStrs.size() == SUB_PASTEID_NUM, false, PASTEBOARD_MODULE_SERVICE,
807         "pasteId pattern mismatch, pasteId=%{public}s", pasteId.c_str());
808     std::string callPid = std::to_string(IPCSkeleton::GetCallingPid());
809     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(
810         callPid == subStrs[1], false, PASTEBOARD_MODULE_SERVICE, "calling pid mismatch");
811     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(
812         !subStrs[SUB_PASTEID_NUM - 1].empty(), false, PASTEBOARD_MODULE_SERVICE, "suffix is empty");
813     for (const char &character : subStrs[SUB_PASTEID_NUM - 1]) {
814         PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(character >= '0' && character <= '9', false, PASTEBOARD_MODULE_SERVICE,
815             "pasteId pattern mismatch, pasteId=%{public}s", pasteId.c_str());
816     }
817     return true;
818 }
819 
GetDeviceId() const820 std::string PasteData::GetDeviceId() const
821 {
822     return deviceId_;
823 }
824 
SetPasteId(const std::string & pasteId)825 void PasteData::SetPasteId(const std::string &pasteId)
826 {
827     pasteId_ = pasteId;
828 }
829 
GetPasteId() const830 std::string PasteData::GetPasteId() const
831 {
832     return pasteId_;
833 }
834 } // namespace MiscServices
835 } // namespace OHOS