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