• 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 { TAG_PROPS = TAG_BUFF + 1, TAG_RECORDS, TAG_DRAGGED_DATA_FLAG, TAG_LOCAL_PASTE_FLAG };
32 enum TAG_PROPERTY : uint16_t {
33     TAG_ADDITIONS = TAG_BUFF + 1,
34     TAG_MIMETYPES,
35     TAG_TAG,
36     TAG_LOCAL_ONLY,
37     TAG_TIMESTAMP,
38     TAG_SHAREOPTION,
39     TAG_TOKENID,
40     TAG_ISREMOTE,
41     TAG_BUNDLENAME,
42     TAG_SETTIME,
43 };
44 
45 std::string PasteData::sharePath = "";
46 std::string PasteData::WEBVIEW_PASTEDATA_TAG = "WebviewPasteDataTag";
47 const std::string PasteData::DISTRIBUTEDFILES_TAG = "distributedfiles";
48 const std::string PasteData::PATH_SHARE = "/data/storage/el2/share/r/";
49 const std::string PasteData::FILE_SCHEME_PREFIX = "file://";
50 const std::string PasteData::IMG_LOCAL_URI = "file:///";
51 const std::string PasteData::SHARE_PATH_PREFIX = "/mnt/hmdfs/";
52 const std::string PasteData::SHARE_PATH_PREFIX_ACCOUNT = "/account/merge_view/services/";
53 const std::string PasteData::REMOTE_FILE_SIZE = "remoteFileSize";
54 
PasteData()55 PasteData::PasteData()
56 {
57     props_.timestamp = steady_clock::now().time_since_epoch().count();
58     props_.localOnly = false;
59     props_.shareOption = ShareOption::CrossDevice;
60 }
61 
PasteData(const PasteData & data)62 PasteData::PasteData(const PasteData &data) : orginAuthority_(data.orginAuthority_), valid_(data.valid_),
63     isDraggedData_(data.isDraggedData_), isLocalPaste_(data.isLocalPaste_)
64 {
65     this->props_ = data.props_;
66     for (const auto &item : data.records_) {
67         this->records_.emplace_back(std::make_shared<PasteDataRecord>(*item));
68     }
69 }
70 
PasteData(std::vector<std::shared_ptr<PasteDataRecord>> records)71 PasteData::PasteData(std::vector<std::shared_ptr<PasteDataRecord>> records) : records_{ std::move(records) }
72 {
73     props_.timestamp = steady_clock::now().time_since_epoch().count();
74     props_.localOnly = false;
75     props_.shareOption = ShareOption::CrossDevice;
76 }
77 
GetProperty() const78 PasteDataProperty PasteData::GetProperty() const
79 {
80     return props_;
81 }
82 
AddHtmlRecord(const std::string & html)83 void PasteData::AddHtmlRecord(const std::string &html)
84 {
85     this->AddRecord(PasteDataRecord::NewHtmlRecord(html));
86 }
87 
AddPixelMapRecord(std::shared_ptr<PixelMap> pixelMap)88 void PasteData::AddPixelMapRecord(std::shared_ptr<PixelMap> pixelMap)
89 {
90     this->AddRecord(PasteDataRecord::NewPixelMapRecord(std::move(pixelMap)));
91 }
92 
AddWantRecord(std::shared_ptr<OHOS::AAFwk::Want> want)93 void PasteData::AddWantRecord(std::shared_ptr<OHOS::AAFwk::Want> want)
94 {
95     this->AddRecord(PasteDataRecord::NewWantRecord(std::move(want)));
96 }
97 
AddTextRecord(const std::string & text)98 void PasteData::AddTextRecord(const std::string &text)
99 {
100     this->AddRecord(PasteDataRecord::NewPlaintTextRecord(text));
101 }
102 
AddUriRecord(const OHOS::Uri & uri)103 void PasteData::AddUriRecord(const OHOS::Uri &uri)
104 {
105     this->AddRecord(PasteDataRecord::NewUriRecord(uri));
106 }
107 
AddKvRecord(const std::string & mimeType,const std::vector<uint8_t> & arrayBuffer)108 void PasteData::AddKvRecord(const std::string &mimeType, const std::vector<uint8_t> &arrayBuffer)
109 {
110     AddRecord(PasteDataRecord::NewKvRecord(mimeType, arrayBuffer));
111 }
112 
AddRecord(std::shared_ptr<PasteDataRecord> record)113 void PasteData::AddRecord(std::shared_ptr<PasteDataRecord> record)
114 {
115     if (record == nullptr) {
116         return;
117     }
118     records_.insert(records_.begin(), std::move(record));
119     RefreshMimeProp();
120 }
121 
AddRecord(PasteDataRecord & record)122 void PasteData::AddRecord(PasteDataRecord &record)
123 {
124     this->AddRecord(std::make_shared<PasteDataRecord>(record));
125     RefreshMimeProp();
126 }
127 
GetMimeTypes()128 std::vector<std::string> PasteData::GetMimeTypes()
129 {
130     std::vector<std::string> mimeType;
131     for (const auto &item : records_) {
132         mimeType.push_back(item->GetMimeType());
133     }
134     return mimeType;
135 }
136 
GetPrimaryHtml()137 std::shared_ptr<std::string> PasteData::GetPrimaryHtml()
138 {
139     for (const auto &item : records_) {
140         if (item->GetHtmlText() != nullptr) {
141             return item->GetHtmlText();
142         }
143     }
144     return nullptr;
145 }
146 
GetPrimaryPixelMap()147 std::shared_ptr<PixelMap> PasteData::GetPrimaryPixelMap()
148 {
149     for (const auto &item : records_) {
150         if (item->GetPixelMap() != nullptr) {
151             return item->GetPixelMap();
152         }
153     }
154     return nullptr;
155 }
156 
GetPrimaryWant()157 std::shared_ptr<OHOS::AAFwk::Want> PasteData::GetPrimaryWant()
158 {
159     for (const auto &item : records_) {
160         if (item->GetWant() != nullptr) {
161             return item->GetWant();
162         }
163     }
164     return nullptr;
165 }
166 
GetPrimaryText()167 std::shared_ptr<std::string> PasteData::GetPrimaryText()
168 {
169     for (const auto &item : records_) {
170         if (item->GetPlainText() != nullptr) {
171             return item->GetPlainText();
172         }
173     }
174     return nullptr;
175 }
176 
GetPrimaryUri()177 std::shared_ptr<OHOS::Uri> PasteData::GetPrimaryUri()
178 {
179     for (const auto &item : records_) {
180         if (item->GetUri() != nullptr) {
181             return item->GetUri();
182         }
183     }
184     return nullptr;
185 }
186 
GetPrimaryMimeType()187 std::shared_ptr<std::string> PasteData::GetPrimaryMimeType()
188 {
189     if (!records_.empty()) {
190         return std::make_shared<std::string>(records_.front()->GetMimeType());
191     } else {
192         return nullptr;
193     }
194 }
195 
GetRecordAt(std::size_t index)196 std::shared_ptr<PasteDataRecord> PasteData::GetRecordAt(std::size_t index)
197 {
198     if (records_.size() > index) {
199         return records_[index];
200     } else {
201         return nullptr;
202     }
203 }
204 
GetRecordCount()205 std::size_t PasteData::GetRecordCount()
206 {
207     return records_.size();
208 }
209 
GetShareOption()210 ShareOption PasteData::GetShareOption()
211 {
212     return props_.shareOption;
213 }
214 
SetShareOption(ShareOption shareOption)215 void PasteData::SetShareOption(ShareOption shareOption)
216 {
217     props_.shareOption = shareOption;
218     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "shareOption = %{public}d.", shareOption);
219 }
220 
GetTokenId()221 std::uint32_t PasteData::GetTokenId()
222 {
223     return props_.tokenId;
224 }
225 
SetTokenId(uint32_t tokenId)226 void PasteData::SetTokenId(uint32_t tokenId)
227 {
228     props_.tokenId = tokenId;
229 }
230 
RemoveRecordAt(std::size_t number)231 bool PasteData::RemoveRecordAt(std::size_t number)
232 {
233     if (records_.size() > number) {
234         records_.erase(records_.begin() + static_cast<std::int64_t>(number));
235         RefreshMimeProp();
236         return true;
237     } else {
238         return false;
239     }
240 }
241 
ReplaceRecordAt(std::size_t number,std::shared_ptr<PasteDataRecord> record)242 bool PasteData::ReplaceRecordAt(std::size_t number, std::shared_ptr<PasteDataRecord> record)
243 {
244     if (records_.size() > number) {
245         records_[number] = std::move(record);
246         RefreshMimeProp();
247         return true;
248     } else {
249         return false;
250     }
251 }
252 
HasMimeType(const std::string & mimeType)253 bool PasteData::HasMimeType(const std::string &mimeType)
254 {
255     for (auto &item : records_) {
256         if (item->GetMimeType() == mimeType) {
257             return true;
258         }
259     }
260     return false;
261 }
262 
AllRecords() const263 std::vector<std::shared_ptr<PasteDataRecord>> PasteData::AllRecords() const
264 {
265     return this->records_;
266 }
267 
IsDraggedData() const268 bool PasteData::IsDraggedData() const
269 {
270     return isDraggedData_;
271 }
272 
IsLocalPaste() const273 bool PasteData::IsLocalPaste() const
274 {
275     return isLocalPaste_;
276 }
277 
SetDraggedDataFlag(bool isDraggedData)278 void PasteData::SetDraggedDataFlag(bool isDraggedData)
279 {
280     isDraggedData_ = isDraggedData;
281 }
282 
SetLocalPasteFlag(bool isLocalPaste)283 void PasteData::SetLocalPasteFlag(bool isLocalPaste)
284 {
285     isLocalPaste_ = isLocalPaste;
286 }
287 
SetRemote(bool isRemote)288 void PasteData::SetRemote(bool isRemote)
289 {
290     props_.isRemote = isRemote;
291 }
292 
IsRemote()293 bool PasteData::IsRemote()
294 {
295     return props_.isRemote;
296 }
297 
SetBundleName(const std::string & bundleName)298 void PasteData::SetBundleName(const std::string &bundleName)
299 {
300     props_.bundleName = bundleName;
301 }
302 
GetBundleName() const303 std::string PasteData::GetBundleName() const
304 {
305     return props_.bundleName;
306 }
307 
SetOrginAuthority(const std::string & bundleName)308 void PasteData::SetOrginAuthority(const std::string &bundleName)
309 {
310     orginAuthority_ = bundleName;
311 }
312 
GetOrginAuthority() const313 std::string PasteData::GetOrginAuthority() const
314 {
315     return orginAuthority_;
316 }
317 
SetTime(const std::string & setTime)318 void PasteData::SetTime(const std::string &setTime)
319 {
320     props_.setTime = setTime;
321 }
322 
GetTime()323 std::string PasteData::GetTime()
324 {
325     return props_.setTime;
326 }
327 
SetTag(std::string & tag)328 void PasteData::SetTag(std::string &tag)
329 {
330     props_.tag = tag;
331 }
332 
GetTag()333 std::string PasteData::GetTag()
334 {
335     return props_.tag;
336 }
337 
SetAdditions(AAFwk::WantParams & additions)338 void PasteData::SetAdditions(AAFwk::WantParams &additions)
339 {
340     props_.additions = additions;
341 }
342 
SetAddition(const std::string & key,AAFwk::IInterface * value)343 void PasteData::SetAddition(const std::string &key, AAFwk::IInterface *value)
344 {
345     props_.additions.SetParam(key, value);
346 }
347 
SetLocalOnly(bool localOnly)348 void PasteData::SetLocalOnly(bool localOnly)
349 {
350     props_.localOnly = localOnly;
351 }
352 
GetLocalOnly()353 bool PasteData::GetLocalOnly()
354 {
355     return props_.localOnly;
356 }
357 
RefreshMimeProp()358 void PasteData::RefreshMimeProp()
359 {
360     std::vector<std::string> mimeTypes;
361     for (const auto &record : records_) {
362         if (record == nullptr) {
363             continue;
364         }
365         mimeTypes.insert(mimeTypes.end(), record->GetMimeType());
366     }
367     props_.mimeTypes = mimeTypes;
368 }
369 
Encode(std::vector<std::uint8_t> & buffer)370 bool PasteData::Encode(std::vector<std::uint8_t> &buffer)
371 {
372     Init(buffer);
373 
374     bool ret = Write(buffer, TAG_PROPS, props_);
375     ret = Write(buffer, TAG_RECORDS, records_) && ret;
376     ret = Write(buffer, TAG_DRAGGED_DATA_FLAG, isDraggedData_) && ret;
377     ret = Write(buffer, TAG_LOCAL_PASTE_FLAG, isLocalPaste_) && ret;
378     return ret;
379 }
380 
Decode(const std::vector<std::uint8_t> & buffer)381 bool PasteData::Decode(const std::vector<std::uint8_t> &buffer)
382 {
383     total_ = buffer.size();
384     for (; IsEnough();) {
385         TLVHead head{};
386         bool ret = ReadHead(buffer, head);
387         switch (head.tag) {
388             case TAG_PROPS:
389                 ret = ret && ReadValue(buffer, props_, head);
390                 break;
391             case TAG_RECORDS: {
392                 ret = ret && ReadValue(buffer, records_, head);
393                 break;
394             }
395             case TAG_DRAGGED_DATA_FLAG: {
396                 ret = ret && ReadValue(buffer, isDraggedData_, head);
397                 break;
398             }
399             case TAG_LOCAL_PASTE_FLAG: {
400                 ret = ret && ReadValue(buffer, isLocalPaste_, head);
401                 break;
402             }
403             default:
404                 ret = ret && Skip(head.len, buffer.size());
405                 break;
406         }
407         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "read value,tag:%{public}u, len:%{public}u, ret:%{public}d",
408             head.tag, head.len, ret);
409         if (!ret) {
410             return false;
411         }
412     }
413     return true;
414 }
Count()415 size_t PasteData::Count()
416 {
417     size_t expectSize = 0;
418     expectSize += props_.Count() + sizeof(TLVHead);
419     expectSize += TLVObject::Count(records_);
420     expectSize += TLVObject::Count(isDraggedData_);
421     expectSize += TLVObject::Count(isLocalPaste_);
422     return expectSize;
423 }
424 
IsValid() const425 bool PasteData::IsValid() const
426 {
427     return valid_;
428 }
429 
SetInvalid()430 void PasteData::SetInvalid()
431 {
432     valid_ = false;
433 }
434 
PasteDataProperty(const PasteDataProperty & property)435 PasteDataProperty::PasteDataProperty(const PasteDataProperty &property)
436     : tag(property.tag), timestamp(property.timestamp), localOnly(property.localOnly),
437     shareOption(property.shareOption), tokenId(property.tokenId), isRemote(property.isRemote),
438     bundleName(property.bundleName), setTime(property.setTime)
439 {
440     this->additions = property.additions;
441     std::copy(property.mimeTypes.begin(), property.mimeTypes.end(), std::back_inserter(this->mimeTypes));
442 }
443 
Encode(std::vector<std::uint8_t> & buffer)444 bool PasteDataProperty::Encode(std::vector<std::uint8_t> &buffer)
445 {
446     bool ret = Write(buffer, TAG_ADDITIONS, ParcelUtil::Parcelable2Raw(&additions));
447     ret = Write(buffer, TAG_MIMETYPES, mimeTypes) && ret;
448     ret = Write(buffer, TAG_TAG, tag) && ret;
449     ret = Write(buffer, TAG_LOCAL_ONLY, localOnly) && ret;
450     ret = Write(buffer, TAG_TIMESTAMP, timestamp) && ret;
451     ret = Write(buffer, TAG_SHAREOPTION, (int32_t &)shareOption) && ret;
452     ret = Write(buffer, TAG_TOKENID, tokenId) && ret;
453     ret = Write(buffer, TAG_ISREMOTE, isRemote) && ret;
454     ret = Write(buffer, TAG_BUNDLENAME, bundleName) && ret;
455     ret = Write(buffer, TAG_SETTIME, setTime) && ret;
456     return ret;
457 }
458 
Decode(const std::vector<std::uint8_t> & buffer)459 bool PasteDataProperty::Decode(const std::vector<std::uint8_t> &buffer)
460 {
461     for (; IsEnough();) {
462         if (!DecodeTag(buffer)) {
463             return false;
464         }
465     }
466     return true;
467 }
468 
DecodeTag(const std::vector<std::uint8_t> & buffer)469 bool PasteDataProperty::DecodeTag(const std::vector<std::uint8_t> &buffer)
470 {
471     TLVHead head{};
472     bool ret = ReadHead(buffer, head);
473     switch (head.tag) {
474         case TAG_ADDITIONS: {
475             RawMem rawMem{};
476             ret = ret && ReadValue(buffer, rawMem, head);
477             auto buff = ParcelUtil::Raw2Parcelable<AAFwk::WantParams>(rawMem);
478             if (buff != nullptr) {
479                 additions = *buff;
480             }
481             break;
482         }
483         case TAG_MIMETYPES:
484             ret = ret && ReadValue(buffer, mimeTypes, head);
485             break;
486         case TAG_TAG:
487             ret = ret && ReadValue(buffer, tag, head);
488             break;
489         case TAG_LOCAL_ONLY:
490             ret = ret && ReadValue(buffer, localOnly, head);
491             break;
492         case TAG_TIMESTAMP:
493             ret = ret && ReadValue(buffer, timestamp, head);
494             break;
495         case TAG_SHAREOPTION:
496             ret = ret && ReadValue(buffer, (int32_t &)shareOption, head);
497             break;
498         case TAG_TOKENID:
499             ret = ret && ReadValue(buffer, tokenId, head);
500             break;
501         case TAG_ISREMOTE:
502             ret = ret && ReadValue(buffer, isRemote, head);
503             break;
504         case TAG_BUNDLENAME:
505             ret = ret && ReadValue(buffer, bundleName, head);
506             break;
507         case TAG_SETTIME:
508             ret = ret && ReadValue(buffer, setTime, head);
509             break;
510         default:
511             ret = ret && Skip(head.len, buffer.size());
512             break;
513     }
514     return ret;
515 }
516 
Count()517 size_t PasteDataProperty::Count()
518 {
519     size_t expectedSize = 0;
520     expectedSize += TLVObject::Count(ParcelUtil::Parcelable2Raw(&additions));
521     expectedSize += TLVObject::Count(mimeTypes);
522     expectedSize += TLVObject::Count(tag);
523     expectedSize += TLVObject::Count(localOnly);
524     expectedSize += TLVObject::Count(timestamp);
525     expectedSize += TLVObject::Count(shareOption);
526     expectedSize += TLVObject::Count(tokenId);
527     expectedSize += TLVObject::Count(isRemote);
528     expectedSize += TLVObject::Count(bundleName);
529     expectedSize += TLVObject::Count(setTime);
530     return expectedSize;
531 }
532 
WriteUriFd(MessageParcel & parcel,UriHandler & uriHandler,bool isClient)533 bool PasteData::WriteUriFd(MessageParcel &parcel, UriHandler &uriHandler, bool isClient)
534 {
535     std::vector<uint32_t> uriIndexList;
536     for (size_t i = 0; i < GetRecordCount(); ++i) {
537         auto record = GetRecordAt(i);
538         if (record == nullptr) {
539             PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "record null");
540             continue;
541         }
542         if (isLocalPaste_) {
543             PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "isLocalPaste");
544             continue;
545         }
546         if (record->NeedFd(uriHandler)) {
547             uriIndexList.push_back(i);
548         }
549     }
550     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "write fd vector size:%{public}zu", uriIndexList.size());
551     if (!parcel.WriteUInt32Vector(uriIndexList)) {
552         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Failed to write fd index vector");
553         return false;
554     }
555     for (auto index : uriIndexList) {
556         auto record = GetRecordAt(index);
557         if (record == nullptr || !record->WriteFd(parcel, uriHandler, isClient)) {
558             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Failed to write fd");
559             return false;
560         }
561     }
562     return true;
563 }
ReadUriFd(MessageParcel & parcel,UriHandler & uriHandler)564 bool PasteData::ReadUriFd(MessageParcel &parcel, UriHandler &uriHandler)
565 {
566     std::vector<uint32_t> fdRecordMap;
567     if (!parcel.ReadUInt32Vector(&fdRecordMap)) {
568         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Failed to read fd index vector");
569         return false;
570     }
571     for (auto index : fdRecordMap) {
572         auto record = GetRecordAt(index);
573         if (record == nullptr || !record->ReadFd(parcel, uriHandler)) {
574             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Failed to read fd");
575             return false;
576         }
577     }
578     return true;
579 }
ReplaceShareUri(int32_t userId)580 void PasteData::ReplaceShareUri(int32_t userId)
581 {
582     auto count = GetRecordCount();
583     for (size_t i = 0; i < count; ++i) {
584         auto record = GetRecordAt(i);
585         if (record == nullptr) {
586             continue;
587         }
588         record->ReplaceShareUri(userId);
589     }
590 }
591 
ShareOptionToString(ShareOption shareOption,std::string & out)592 void PasteData::ShareOptionToString(ShareOption shareOption, std::string &out)
593 {
594     if (shareOption == ShareOption::InApp) {
595         out = "InAPP";
596     } else if (shareOption == ShareOption::LocalDevice) {
597         out = "LocalDevice";
598     } else {
599         out = "CrossDevice";
600     }
601 }
602 } // namespace MiscServices
603 } // namespace OHOS