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