• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "paste_data_record.h"
16 
17 #include <sys/stat.h>
18 #include <unistd.h>
19 
20 #include "copy_uri_handler.h"
21 #include "parcel_util.h"
22 #include "paste_uri_handler.h"
23 #include "pasteboard_error.h"
24 #include "pixel_map_parcel.h"
25 #include "pasteboard_hilog.h"
26 
27 using namespace OHOS::Media;
28 
29 namespace OHOS {
30 namespace MiscServices {
31 namespace {
32 constexpr int MAX_TEXT_LEN = 20 * 1024 * 1024;
33 }
34 
SetMimeType(std::string mimeType)35 PasteDataRecord::Builder &PasteDataRecord::Builder::SetMimeType(std::string mimeType)
36 {
37     record_->mimeType_ = std::move(mimeType);
38     return *this;
39 }
40 enum TAG_PASTEBOARD_RECORD : uint16_t {
41     TAG_MIMETYPE = TAG_BUFF + 1,
42     TAG_HTMLTEXT,
43     TAG_WANT,
44     TAG_PLAINTEXT,
45     TAG_URI,
46     TAG_PIXELMAP,
47     TAG_CUSTOM_DATA,
48     TAG_CONVERT_URI,
49 };
50 
51 enum TAG_CUSTOMDATA : uint16_t {
52     TAG_ITEM_DATA = TAG_BUFF + 1,
53 };
54 
SetHtmlText(std::shared_ptr<std::string> htmlText)55 PasteDataRecord::Builder &PasteDataRecord::Builder::SetHtmlText(std::shared_ptr<std::string> htmlText)
56 {
57     record_->htmlText_ = std::move(htmlText);
58     return *this;
59 }
SetWant(std::shared_ptr<OHOS::AAFwk::Want> want)60 PasteDataRecord::Builder &PasteDataRecord::Builder::SetWant(std::shared_ptr<OHOS::AAFwk::Want> want)
61 {
62     record_->want_ = std::move(want);
63     return *this;
64 }
SetPlainText(std::shared_ptr<std::string> plainText)65 PasteDataRecord::Builder &PasteDataRecord::Builder::SetPlainText(std::shared_ptr<std::string> plainText)
66 {
67     record_->plainText_ = std::move(plainText);
68     return *this;
69 }
SetUri(std::shared_ptr<OHOS::Uri> uri)70 PasteDataRecord::Builder &PasteDataRecord::Builder::SetUri(std::shared_ptr<OHOS::Uri> uri)
71 {
72     record_->uri_ = std::move(uri);
73     return *this;
74 }
SetPixelMap(std::shared_ptr<OHOS::Media::PixelMap> pixelMap)75 PasteDataRecord::Builder &PasteDataRecord::Builder::SetPixelMap(std::shared_ptr<OHOS::Media::PixelMap> pixelMap)
76 {
77     record_->pixelMap_ = std::move(pixelMap);
78     return *this;
79 }
80 
SetCustomData(std::shared_ptr<MineCustomData> customData)81 PasteDataRecord::Builder &PasteDataRecord::Builder::SetCustomData(std::shared_ptr<MineCustomData> customData)
82 {
83     record_->customData_ = std::move(customData);
84     return *this;
85 }
86 
Build()87 std::shared_ptr<PasteDataRecord> PasteDataRecord::Builder::Build()
88 {
89     return record_;
90 }
Builder(const std::string & mimeType)91 PasteDataRecord::Builder::Builder(const std::string &mimeType)
92 {
93     record_ = std::make_shared<PasteDataRecord>();
94     if (record_ != nullptr) {
95         record_->mimeType_ = mimeType;
96         record_->htmlText_ = nullptr;
97         record_->want_ = nullptr;
98         record_->plainText_ = nullptr;
99         record_->uri_ = nullptr;
100         record_->pixelMap_ = nullptr;
101         record_->customData_ = nullptr;
102     }
103 }
104 
NewHtmlRecord(const std::string & htmlText)105 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewHtmlRecord(const std::string &htmlText)
106 {
107     if (htmlText.length() >= MAX_TEXT_LEN) {
108         return nullptr;
109     }
110     return Builder(MIMETYPE_TEXT_HTML).SetHtmlText(std::make_shared<std::string>(htmlText)).Build();
111 }
112 
NewWantRecord(std::shared_ptr<OHOS::AAFwk::Want> want)113 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewWantRecord(std::shared_ptr<OHOS::AAFwk::Want> want)
114 {
115     return Builder(MIMETYPE_TEXT_WANT).SetWant(std::move(want)).Build();
116 }
117 
NewPlaintTextRecord(const std::string & text)118 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewPlaintTextRecord(const std::string &text)
119 {
120     if (text.length() >= MAX_TEXT_LEN) {
121         return nullptr;
122     }
123     return Builder(MIMETYPE_TEXT_PLAIN).SetPlainText(std::make_shared<std::string>(text)).Build();
124 }
125 
NewPixelMapRecord(std::shared_ptr<PixelMap> pixelMap)126 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewPixelMapRecord(std::shared_ptr<PixelMap> pixelMap)
127 {
128     return Builder(MIMETYPE_PIXELMAP).SetPixelMap(std::move(pixelMap)).Build();
129 }
130 
NewUriRecord(const OHOS::Uri & uri)131 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewUriRecord(const OHOS::Uri &uri)
132 {
133     return Builder(MIMETYPE_TEXT_URI).SetUri(std::make_shared<OHOS::Uri>(uri)).Build();
134 }
135 
NewKvRecord(const std::string & mimeType,const std::vector<uint8_t> & arrayBuffer)136 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewKvRecord(const std::string &mimeType,
137     const std::vector<uint8_t> &arrayBuffer)
138 {
139     std::shared_ptr<MineCustomData> customData = std::make_shared<MineCustomData>();
140     customData->AddItemData(mimeType, arrayBuffer);
141     return Builder(mimeType).SetCustomData(std::move(customData)).Build();
142 }
143 
PasteDataRecord(std::string mimeType,std::shared_ptr<std::string> htmlText,std::shared_ptr<OHOS::AAFwk::Want> want,std::shared_ptr<std::string> plainText,std::shared_ptr<OHOS::Uri> uri)144 PasteDataRecord::PasteDataRecord(std::string mimeType, std::shared_ptr<std::string> htmlText,
145     std::shared_ptr<OHOS::AAFwk::Want> want, std::shared_ptr<std::string> plainText, std::shared_ptr<OHOS::Uri> uri)
146     : mimeType_{ std::move(mimeType) }, htmlText_{ std::move(htmlText) }, want_{ std::move(want) },
147       plainText_{ std::move(plainText) }, uri_{ std::move(uri) }
148 {
149 }
150 
PasteDataRecord()151 PasteDataRecord::PasteDataRecord()
152 {
153     fd_ = std::make_shared<FileDescriptor>();
154 }
155 
GetHtmlText() const156 std::shared_ptr<std::string> PasteDataRecord::GetHtmlText() const
157 {
158     return this->htmlText_;
159 }
160 
GetMimeType() const161 std::string PasteDataRecord::GetMimeType() const
162 {
163     return this->mimeType_;
164 }
165 
GetPlainText() const166 std::shared_ptr<std::string> PasteDataRecord::GetPlainText() const
167 {
168     return this->plainText_;
169 }
170 
GetPixelMap() const171 std::shared_ptr<PixelMap> PasteDataRecord::GetPixelMap() const
172 {
173     return this->pixelMap_;
174 }
175 
GetUri() const176 std::shared_ptr<OHOS::Uri> PasteDataRecord::GetUri() const
177 {
178     if (convertUri_.empty()) {
179         return uri_;
180     }
181     return std::make_shared<OHOS::Uri>(convertUri_);
182 }
183 
GetWant() const184 std::shared_ptr<OHOS::AAFwk::Want> PasteDataRecord::GetWant() const
185 {
186     return this->want_;
187 }
188 
GetCustomData() const189 std::shared_ptr<MineCustomData> PasteDataRecord::GetCustomData() const
190 {
191     return this->customData_;
192 }
193 
GetItemData()194 std::map<std::string, std::vector<uint8_t>> MineCustomData::GetItemData()
195 {
196     return this->itemData_;
197 }
198 
AddItemData(const std::string & mimeType,const std::vector<uint8_t> & arrayBuffer)199 void MineCustomData::AddItemData(const std::string &mimeType, const std::vector<uint8_t> &arrayBuffer)
200 {
201     itemData_.insert(std::make_pair(mimeType, arrayBuffer));
202     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "itemData_.size = %{public}zu", itemData_.size());
203 }
204 
ConvertToText() const205 std::string PasteDataRecord::ConvertToText() const
206 {
207     if (this->htmlText_) {
208         return *this->htmlText_;
209     } else if (this->plainText_) {
210         return *this->plainText_;
211     } else if (this->uri_) {
212         return this->uri_->ToString();
213     } else {
214         return "";
215     }
216 }
217 
Marshalling(Parcel & parcel,std::shared_ptr<std::string> item)218 bool PasteDataRecord::Marshalling(Parcel &parcel, std::shared_ptr<std::string> item)
219 {
220     if (!parcel.WriteBool(item != nullptr)) {
221         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "WriteBool failed.");
222         return false;
223     }
224     if (item == nullptr) {
225         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "no data provide.");
226         return true;
227     }
228     return parcel.WriteString16(Str8ToStr16(*item));
229 }
230 
Marshalling(Parcel & parcel,std::shared_ptr<Parcelable> item)231 bool PasteDataRecord::Marshalling(Parcel &parcel, std::shared_ptr<Parcelable> item)
232 {
233     if (!parcel.WriteBool(item != nullptr)) {
234         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "WriteBool failed.");
235         return false;
236     }
237     if (item == nullptr) {
238         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "no data provide.");
239         return true;
240     }
241     return parcel.WriteParcelable(item.get());
242 }
243 
Marshalling(Parcel & parcel) const244 bool PasteDataRecord::Marshalling(Parcel &parcel) const
245 {
246     if (!parcel.WriteString16(Str8ToStr16(mimeType_))) {
247         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "write mimeType failed, mimeType = %{public}s.", mimeType_.c_str());
248         return false;
249     }
250     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "mimeType = %{public}s,", mimeType_.c_str());
251     bool ret = Marshalling(parcel, htmlText_);
252     ret = Marshalling(parcel, want_) && ret;
253     ret = Marshalling(parcel, plainText_) && ret;
254     ret = Marshalling(parcel, uri_) && ret;
255     ret = Marshalling(parcel, pixelMap_) && ret;
256     ret = Marshalling(parcel, customData_) && ret;
257     return ret;
258 }
259 
UnMarshalling(Parcel & parcel,std::shared_ptr<T> & item)260 template<typename T> ResultCode PasteDataRecord::UnMarshalling(Parcel &parcel, std::shared_ptr<T> &item)
261 {
262     if (!parcel.ReadBool()) {
263         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "no data provide.");
264         return ResultCode::IPC_NO_DATA;
265     }
266     std::shared_ptr<T> parcelAble(parcel.ReadParcelable<T>());
267     if (!parcelAble) {
268         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "ReadParcelable failed.");
269         return ResultCode::IPC_ERROR;
270     }
271     item = move(parcelAble);
272     return ResultCode::OK;
273 }
274 
UnMarshalling(Parcel & parcel,std::shared_ptr<std::string> & item)275 ResultCode PasteDataRecord::UnMarshalling(Parcel &parcel, std::shared_ptr<std::string> &item)
276 {
277     if (!parcel.ReadBool()) {
278         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "no data provide.");
279         return ResultCode::IPC_NO_DATA;
280     }
281     item = std::make_shared<std::string>(Str16ToStr8(parcel.ReadString16()));
282     if (!item) {
283         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "ReadString16 failed.");
284         return ResultCode::IPC_ERROR;
285     }
286     return ResultCode::OK;
287 }
288 
Unmarshalling(Parcel & parcel)289 PasteDataRecord *PasteDataRecord::Unmarshalling(Parcel &parcel)
290 {
291     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "start.");
292     auto pasteDataRecord = new (std::nothrow) PasteDataRecord();
293 
294     if (pasteDataRecord == nullptr) {
295         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "pasteDataRecord is nullptr.");
296         return pasteDataRecord;
297     }
298 
299     pasteDataRecord->mimeType_ = Str16ToStr8(parcel.ReadString16());
300     if (pasteDataRecord->mimeType_.empty()) {
301         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "ReadString16 failed.");
302         delete pasteDataRecord;
303         pasteDataRecord = nullptr;
304         return pasteDataRecord;
305     }
306     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "mimeType = %{public}s,", pasteDataRecord->mimeType_.c_str());
307 
308     ResultCode resultCode = UnMarshalling(parcel, pasteDataRecord->htmlText_);
309     auto ret = CheckResult(resultCode);
310     resultCode = UnMarshalling(parcel, pasteDataRecord->want_);
311     ret = CheckResult(resultCode) || ret;
312     resultCode = UnMarshalling(parcel, pasteDataRecord->plainText_);
313     ret = CheckResult(resultCode) || ret;
314     resultCode = UnMarshalling(parcel, pasteDataRecord->uri_);
315     ret = CheckResult(resultCode) || ret;
316     resultCode = UnMarshalling(parcel, pasteDataRecord->pixelMap_);
317     ret = CheckResult(resultCode) || ret;
318     resultCode = UnMarshalling(parcel, pasteDataRecord->customData_);
319     ret = CheckResult(resultCode) || ret;
320     if (!ret) {
321         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "UnMarshalling failed.");
322         delete pasteDataRecord;
323         pasteDataRecord = nullptr;
324     }
325     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "end.");
326     return pasteDataRecord;
327 }
328 
Marshalling(Parcel & parcel) const329 bool MineCustomData::Marshalling(Parcel &parcel) const
330 {
331     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "begin.");
332     auto len = itemData_.size();
333     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "itemData_len = %{public}zu,", len);
334     if (!parcel.WriteUint32(static_cast<uint32_t>(len))) {
335         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "len Marshalling failed.");
336         return false;
337     }
338     for (const auto &item : itemData_) {
339         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "dataLen = %{public}zu!", item.second.size());
340         if (!parcel.WriteString(item.first) || !parcel.WriteUInt8Vector(item.second)) {
341             PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "write failed.");
342             return false;
343         }
344     }
345 
346     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "end.");
347     return true;
348 }
349 
Unmarshalling(Parcel & parcel)350 MineCustomData *MineCustomData::Unmarshalling(Parcel &parcel)
351 {
352     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "begin.");
353     auto *mineCustomData = new (std::nothrow) MineCustomData();
354 
355     if (mineCustomData == nullptr) {
356         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "mineCustomData is nullptr.");
357         return mineCustomData;
358     }
359 
360     uint32_t failedNums = 0;
361     auto len = parcel.ReadUint32();
362     if (len <= 0) {
363         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "length error");
364         delete mineCustomData;
365         mineCustomData = nullptr;
366         return mineCustomData;
367     }
368     for (uint32_t i = 0; i < len; i++) {
369         std::string mimeType = parcel.ReadString();
370         std::vector<uint8_t> arrayBuffer;
371         if (!parcel.ReadUInt8Vector(&arrayBuffer) || arrayBuffer.empty()) {
372             failedNums++;
373             continue;
374         }
375         mineCustomData->AddItemData(mimeType, arrayBuffer);
376         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "dataLen = %{public}zu.", arrayBuffer.size());
377     }
378 
379     if (failedNums == len) {
380         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "mineCustomData is nullptr.");
381         delete mineCustomData;
382         mineCustomData = nullptr;
383     }
384     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "end.");
385     return mineCustomData;
386 }
387 
Encode(std::vector<std::uint8_t> & buffer)388 bool MineCustomData::Encode(std::vector<std::uint8_t> &buffer)
389 {
390     return TLVObject::Write(buffer, TAG_ITEM_DATA, itemData_);
391 }
392 
Decode(const std::vector<std::uint8_t> & buffer)393 bool MineCustomData::Decode(const std::vector<std::uint8_t> &buffer)
394 {
395     for (; IsEnough();) {
396         TLVHead head{};
397         bool ret = ReadHead(buffer, head);
398         switch (head.tag) {
399             case TAG_ITEM_DATA:
400                 ret = ret && ReadValue(buffer, itemData_, head);
401                 break;
402             default:
403                 ret = ret && Skip(head.len, buffer.size());
404                 break;
405         }
406         if (!ret) {
407             return false;
408         }
409     }
410     return true;
411 }
412 
Count()413 size_t MineCustomData::Count()
414 {
415     return TLVObject::Count(itemData_);
416 }
417 
Encode(std::vector<std::uint8_t> & buffer)418 bool PasteDataRecord::Encode(std::vector<std::uint8_t> &buffer)
419 {
420     bool ret = Write(buffer, TAG_MIMETYPE, mimeType_);
421     ret = Write(buffer, TAG_HTMLTEXT, htmlText_) && ret;
422     ret = Write(buffer, TAG_WANT, ParcelUtil::Parcelable2Raw(want_.get())) && ret;
423     ret = Write(buffer, TAG_PLAINTEXT, plainText_) && ret;
424     ret = Write(buffer, TAG_URI, ParcelUtil::Parcelable2Raw(uri_.get())) && ret;
425     ret = Write(buffer, TAG_CONVERT_URI, convertUri_) && ret;
426     ret = Write(buffer, TAG_PIXELMAP, PixelMap2Raw(pixelMap_)) && ret;
427     ret = Write(buffer, TAG_CUSTOM_DATA, customData_) && ret;
428     return ret;
429 }
430 
Decode(const std::vector<std::uint8_t> & buffer)431 bool PasteDataRecord::Decode(const std::vector<std::uint8_t> &buffer)
432 {
433     for (; IsEnough();) {
434         TLVHead head{};
435         bool ret = ReadHead(buffer, head);
436         switch (head.tag) {
437             case TAG_MIMETYPE:
438                 ret = ret && ReadValue(buffer, mimeType_, head);
439                 break;
440             case TAG_HTMLTEXT:
441                 ret = ret && ReadValue(buffer, htmlText_, head);
442                 break;
443             case TAG_WANT: {
444                 RawMem rawMem{};
445                 ret = ret && ReadValue(buffer, rawMem, head);
446                 want_ = ParcelUtil::Raw2Parcelable<AAFwk::Want>(rawMem);
447                 break;
448             }
449             case TAG_PLAINTEXT:
450                 ret = ret && ReadValue(buffer, plainText_, head);
451                 break;
452             case TAG_URI: {
453                 RawMem rawMem{};
454                 ret = ret && ReadValue(buffer, rawMem, head);
455                 uri_ = ParcelUtil::Raw2Parcelable<OHOS::Uri>(rawMem);
456                 break;
457             }
458             case TAG_CONVERT_URI: {
459                 ret = ret && ReadValue(buffer, convertUri_, head);
460                 break;
461             }
462             case TAG_PIXELMAP: {
463                 RawMem rawMem{};
464                 ret = ret && ReadValue(buffer, rawMem, head);
465                 pixelMap_ = Raw2PixelMap(rawMem);
466                 break;
467             }
468             case TAG_CUSTOM_DATA:
469                 ret = ret && ReadValue(buffer, customData_, head);
470                 break;
471             default:
472                 ret = ret && Skip(head.len, buffer.size());
473                 break;
474         }
475         if (!ret) {
476             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "read value,tag:%{public}u, len:%{public}u",
477                 head.tag, head.len);
478             return false;
479         }
480     }
481     return true;
482 }
Count()483 size_t PasteDataRecord::Count()
484 {
485     size_t expectedSize = 0;
486     expectedSize += TLVObject::Count(mimeType_);
487     expectedSize += TLVObject::Count(htmlText_);
488     expectedSize += TLVObject::Count(ParcelUtil::Parcelable2Raw(want_.get()));
489     expectedSize += TLVObject::Count(plainText_);
490     expectedSize += TLVObject::Count(ParcelUtil::Parcelable2Raw(uri_.get()));
491     expectedSize += TLVObject::Count(convertUri_);
492     expectedSize += TLVObject::Count(PixelMap2Raw(pixelMap_));
493     expectedSize += TLVObject::Count(customData_);
494     return expectedSize;
495 }
496 
Raw2PixelMap(const RawMem & rawMem)497 std::shared_ptr<PixelMap> PasteDataRecord::Raw2PixelMap(const RawMem &rawMem)
498 {
499     if (rawMem.buffer == 0 || rawMem.bufferLen == 0) {
500         return nullptr;
501     }
502     MessageParcel data;
503     if (!ParcelUtil::Raw2Parcel(rawMem, data)) {
504         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "raw to parcel failed");
505         return nullptr;
506     }
507     return PixelMapParcel::CreateFromParcel(data);
508 }
509 
PixelMap2Raw(const std::shared_ptr<PixelMap> & pixelMap)510 RawMem PasteDataRecord::PixelMap2Raw(const std::shared_ptr<PixelMap> &pixelMap)
511 {
512     RawMem rawMem{ 0 };
513     if (pixelMap == nullptr) {
514         return rawMem;
515     }
516     auto data = std::make_shared<MessageParcel>();
517     if (!PixelMapParcel::WriteToParcel(pixelMap.get(), *data)) {
518         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "parcel to raw failed");
519         return rawMem;
520     }
521     rawMem.parcel = data;
522     rawMem.buffer = data->GetData();
523     rawMem.bufferLen = data->GetDataSize();
524     return rawMem;
525 }
526 
WriteFd(MessageParcel & parcel,UriHandler & uriHandler,bool isClient)527 bool PasteDataRecord::WriteFd(MessageParcel &parcel, UriHandler &uriHandler, bool isClient)
528 {
529     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "isClient: %{public}d", isClient);
530     if (fd_->GetFd() >= 0) {
531         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "write fd_, fd_ is %{public}d", fd_->GetFd());
532         return parcel.WriteFileDescriptor(fd_->GetFd());
533     }
534     std::string tempUri = GetPassUri();
535     if (tempUri.empty()) {
536         return false;
537     }
538     int32_t fd = uriHandler.ToFd(tempUri, isClient);
539     bool ret = parcel.WriteFileDescriptor(fd);
540     uriHandler.ReleaseFd(fd);
541 
542     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "ret is %{public}d", ret);
543     return ret;
544 }
ReadFd(MessageParcel & parcel,UriHandler & uriHandler)545 bool PasteDataRecord::ReadFd(MessageParcel &parcel, UriHandler &uriHandler)
546 {
547     int32_t fd = parcel.ReadFileDescriptor();
548     if (fd >= 0) {
549         convertUri_ = uriHandler.ToUri(fd);
550         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "convertUri_:%{public}s", convertUri_.c_str());
551     }
552     if (!uriHandler.IsPaste()) {
553         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "Set fd, fd is %{public}d", fd);
554         fd_->SetFd(fd);
555     }
556     return true;
557 }
NeedFd(const UriHandler & uriHandler)558 bool PasteDataRecord::NeedFd(const UriHandler &uriHandler)
559 {
560     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "start");
561     std::string tempUri = GetPassUri();
562     if (tempUri.empty()) {
563         return false;
564     }
565     if (!uriHandler.IsFile(tempUri) && fd_->GetFd() < 0) {
566         PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "invalid file uri, fd:%{public}d", fd_->GetFd());
567         return false;
568     }
569     return true;
570 }
GetPassUri()571 std::string PasteDataRecord::GetPassUri()
572 {
573     std::string tempUri;
574     if (uri_ != nullptr) {
575         tempUri = uri_->ToString();
576     }
577     if (!convertUri_.empty()) {
578         tempUri = convertUri_;
579     }
580     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "tempUri:%{public}s", tempUri.c_str());
581     return tempUri;
582 }
ReplaceShareUri(int32_t userId)583 void PasteDataRecord::ReplaceShareUri(int32_t userId)
584 {
585     if (convertUri_.empty()) {
586         return;
587     }
588 
589     // convert uri format: /mnt/hmdfs/100/account/merge_view/services/psteboard_service/.share/xxx.txt
590     constexpr const char *SHARE_PATH_PREFIX = "/mnt/hmdfs/";
591     auto frontPos = convertUri_.find(SHARE_PATH_PREFIX);
592     auto rearPos = convertUri_.find("/account/");
593     if (frontPos == 0 && rearPos != std::string::npos) {
594         convertUri_ = SHARE_PATH_PREFIX + std::to_string(userId) + convertUri_.substr(rearPos);
595         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "replace uri:%{public}s", convertUri_.c_str());
596     }
597 }
SetConvertUri(const std::string & value)598 void PasteDataRecord::SetConvertUri(const std::string &value)
599 {
600     convertUri_ = value;
601 }
~FileDescriptor()602 FileDescriptor::~FileDescriptor()
603 {
604     if (fd_ >= 0) {
605         close(fd_);
606         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "close fd_: %{public}d", fd_);
607     }
608 }
SetFd(int32_t fd)609 void FileDescriptor::SetFd(int32_t fd)
610 {
611     fd_ = fd;
612 }
GetFd() const613 int32_t FileDescriptor::GetFd() const
614 {
615     return fd_;
616 }
617 } // namespace MiscServices
618 } // namespace OHOS