• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2023 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 "convert_utils.h"
21 #include "copy_uri_handler.h"
22 #include "parcel_util.h"
23 #include "pasteboard_hilog.h"
24 #include "pixel_map_parcel.h"
25 
26 using namespace OHOS::Media;
27 
28 namespace OHOS {
29 namespace MiscServices {
30 namespace {
31 constexpr int MAX_TEXT_LEN = 20 * 1024 * 1024;
32 }
SetMimeType(std::string mimeType)33 PasteDataRecord::Builder &PasteDataRecord::Builder::SetMimeType(std::string mimeType)
34 {
35     record_->mimeType_ = std::move(mimeType);
36     return *this;
37 }
38 enum TAG_PASTEBOARD_RECORD : uint16_t {
39     TAG_MIMETYPE = TAG_BUFF + 1,
40     TAG_HTMLTEXT,
41     TAG_WANT,
42     TAG_PLAINTEXT,
43     TAG_URI,
44     TAG_PIXELMAP,
45     TAG_CUSTOM_DATA,
46     TAG_CONVERT_URI,
47     TAG_URI_PERMISSION,
48     TAG_UDC_UDTYPE,
49     TAG_UDC_DETAILS,
50     TAG_UDC_TEXTCONTENT,
51     TAG_UDC_SYSTEMCONTENTS,
52 	TAG_UDC_UDMFVALUE,
53     TAG_UDC_ENTYIES,
54     TAG_DATA_ID,
55     TAG_RECORD_ID,
56     TAG_DELAY_RECORD_FLAG,
57 };
58 
SetHtmlText(std::shared_ptr<std::string> htmlText)59 PasteDataRecord::Builder &PasteDataRecord::Builder::SetHtmlText(std::shared_ptr<std::string> htmlText)
60 {
61     record_->htmlText_ = std::move(htmlText);
62     return *this;
63 }
64 
SetWant(std::shared_ptr<OHOS::AAFwk::Want> want)65 PasteDataRecord::Builder &PasteDataRecord::Builder::SetWant(std::shared_ptr<OHOS::AAFwk::Want> want)
66 {
67     record_->want_ = std::move(want);
68     return *this;
69 }
70 
SetPlainText(std::shared_ptr<std::string> plainText)71 PasteDataRecord::Builder &PasteDataRecord::Builder::SetPlainText(std::shared_ptr<std::string> plainText)
72 {
73     record_->plainText_ = std::move(plainText);
74     return *this;
75 }
SetUri(std::shared_ptr<OHOS::Uri> uri)76 PasteDataRecord::Builder &PasteDataRecord::Builder::SetUri(std::shared_ptr<OHOS::Uri> uri)
77 {
78     record_->uri_ = std::move(uri);
79     return *this;
80 }
81 
SetPixelMap(std::shared_ptr<OHOS::Media::PixelMap> pixelMap)82 PasteDataRecord::Builder &PasteDataRecord::Builder::SetPixelMap(std::shared_ptr<OHOS::Media::PixelMap> pixelMap)
83 {
84     record_->pixelMap_ = std::move(pixelMap);
85     return *this;
86 }
87 
SetCustomData(std::shared_ptr<MineCustomData> customData)88 PasteDataRecord::Builder &PasteDataRecord::Builder::SetCustomData(std::shared_ptr<MineCustomData> customData)
89 {
90     record_->customData_ = std::move(customData);
91     return *this;
92 }
93 
Build()94 std::shared_ptr<PasteDataRecord> PasteDataRecord::Builder::Build()
95 {
96     return record_;
97 }
98 
Builder(const std::string & mimeType)99 PasteDataRecord::Builder::Builder(const std::string &mimeType)
100 {
101     record_ = std::make_shared<PasteDataRecord>();
102     if (record_ != nullptr) {
103         record_->mimeType_ = mimeType;
104         record_->htmlText_ = nullptr;
105         record_->want_ = nullptr;
106         record_->plainText_ = nullptr;
107         record_->uri_ = nullptr;
108         record_->convertUri_ = "";
109         record_->pixelMap_ = nullptr;
110         record_->customData_ = nullptr;
111     }
112 }
113 
AddUriEntry()114 void PasteDataRecord::AddUriEntry()
115 {
116     auto object = std::make_shared<Object>();
117     object->value_[UDMF::UNIFORM_DATA_TYPE] = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::FILE_URI);
118     if (uri_ != nullptr) {
119         object->value_[UDMF::FILE_URI_PARAM] = uri_->ToString();
120     }
121     auto utdId = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::FILE_URI);
122     AddEntry(utdId, std::make_shared<PasteDataEntry>(utdId, object));
123 }
124 
NewHtmlRecord(const std::string & htmlText)125 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewHtmlRecord(const std::string &htmlText)
126 {
127     if (htmlText.length() >= MAX_TEXT_LEN) {
128         return nullptr;
129     }
130     return Builder(MIMETYPE_TEXT_HTML).SetHtmlText(std::make_shared<std::string>(htmlText)).Build();
131 }
132 
NewWantRecord(std::shared_ptr<OHOS::AAFwk::Want> want)133 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewWantRecord(std::shared_ptr<OHOS::AAFwk::Want> want)
134 {
135     return Builder(MIMETYPE_TEXT_WANT).SetWant(std::move(want)).Build();
136 }
137 
NewPlaintTextRecord(const std::string & text)138 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewPlaintTextRecord(const std::string &text)
139 {
140     if (text.length() >= MAX_TEXT_LEN) {
141         return nullptr;
142     }
143     return Builder(MIMETYPE_TEXT_PLAIN).SetPlainText(std::make_shared<std::string>(text)).Build();
144 }
145 
NewPixelMapRecord(std::shared_ptr<PixelMap> pixelMap)146 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewPixelMapRecord(std::shared_ptr<PixelMap> pixelMap)
147 {
148     return Builder(MIMETYPE_PIXELMAP).SetPixelMap(std::move(pixelMap)).Build();
149 }
150 
NewUriRecord(const OHOS::Uri & uri)151 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewUriRecord(const OHOS::Uri &uri)
152 {
153     return Builder(MIMETYPE_TEXT_URI).SetUri(std::make_shared<OHOS::Uri>(uri)).Build();
154 }
155 
NewKvRecord(const std::string & mimeType,const std::vector<uint8_t> & arrayBuffer)156 std::shared_ptr<PasteDataRecord> PasteDataRecord::NewKvRecord(
157     const std::string &mimeType, const std::vector<uint8_t> &arrayBuffer)
158 {
159     std::shared_ptr<MineCustomData> customData = std::make_shared<MineCustomData>();
160     customData->AddItemData(mimeType, arrayBuffer);
161     return Builder(mimeType).SetCustomData(std::move(customData)).Build();
162 }
163 
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)164 PasteDataRecord::PasteDataRecord(std::string mimeType, std::shared_ptr<std::string> htmlText,
165     std::shared_ptr<OHOS::AAFwk::Want> want, std::shared_ptr<std::string> plainText, std::shared_ptr<OHOS::Uri> uri)
166     : mimeType_{ std::move(mimeType) }, htmlText_{ std::move(htmlText) }, want_{ std::move(want) },
167       plainText_{ std::move(plainText) }, uri_{ std::move(uri) }
168 {
169 }
170 
PasteDataRecord()171 PasteDataRecord::PasteDataRecord()
172 {
173     fd_ = std::make_shared<FileDescriptor>();
174     InitDecodeMap();
175 }
176 
~PasteDataRecord()177 PasteDataRecord::~PasteDataRecord()
178 {
179     decodeMap.clear();
180 }
181 
PasteDataRecord(const PasteDataRecord & record)182 PasteDataRecord::PasteDataRecord(const PasteDataRecord& record)
183     : mimeType_(record.mimeType_), htmlText_(record.htmlText_), want_(record.want_), plainText_(record.plainText_),
184       uri_(record.uri_), convertUri_(record.convertUri_), pixelMap_(record.pixelMap_), customData_(record.customData_),
185       hasGrantUriPermission_(record.hasGrantUriPermission_), fd_(record.fd_), udType_(record.udType_),
186       details_(record.details_), textContent_(record.textContent_),
187       systemDefinedContents_(record.systemDefinedContents_), udmfValue_(record.udmfValue_), entries_(record.entries_),
188       dataId_(record.dataId_), recordId_(record.recordId_), isDelay_(record.isDelay_)
189 {
190     this->isConvertUriFromRemote = record.isConvertUriFromRemote;
191     InitDecodeMap();
192 }
193 
InitDecodeMap()194 void PasteDataRecord::InitDecodeMap()
195 {
196     decodeMap = {
197         {TAG_MIMETYPE, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
198             ret = ret && ReadValue(buffer, mimeType_, head);}},
199         {TAG_HTMLTEXT, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
200             ret = ret && ReadValue(buffer, htmlText_, head);}},
201         {TAG_WANT, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
202             RawMem rawMem{};
203             ret = ret && ReadValue(buffer, rawMem, head);
204             want_ = ParcelUtil::Raw2Parcelable<AAFwk::Want>(rawMem);}},
205         {TAG_PLAINTEXT, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
206             ret = ret && ReadValue(buffer, plainText_, head); }},
207         {TAG_URI, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
208             RawMem rawMem{};
209             ret = ret && ReadValue(buffer, rawMem, head);
210             uri_ = ParcelUtil::Raw2Parcelable<OHOS::Uri>(rawMem);}},
211         {TAG_CONVERT_URI, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
212             ret = ret && ReadValue(buffer, convertUri_, head);}},
213         {TAG_PIXELMAP, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
214             std::vector<std::uint8_t> value;
215             ret = ret && ReadValue(buffer, value, head);
216             pixelMap_ = Vector2PixelMap(value);}},
217         {TAG_CUSTOM_DATA, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
218             ret = ret && ReadValue(buffer, customData_, head);}},
219         {TAG_URI_PERMISSION, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
220             ret = ret && ReadValue(buffer, hasGrantUriPermission_, head);}},
221         {TAG_UDC_UDTYPE, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
222             ret = ret && ReadValue(buffer, udType_, head);}},
223         {TAG_UDC_DETAILS, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
224             ret = ret && ReadValue(buffer, details_, head);}},
225         {TAG_UDC_TEXTCONTENT, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
226             ret = ret && ReadValue(buffer, textContent_, head);}},
227         {TAG_UDC_SYSTEMCONTENTS, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
228             ret = ret && ReadValue(buffer, systemDefinedContents_, head);}},
229         {TAG_UDC_UDMFVALUE, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
230             ret = ret && ReadValue(buffer, udmfValue_, head);}},
231         {TAG_UDC_ENTYIES, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
232             ret = ret && ReadValue(buffer, entries_, head);}},
233         {TAG_DATA_ID, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
234             ret = ret && ReadValue(buffer, dataId_, head);}},
235         {TAG_RECORD_ID, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
236             ret = ret && ReadValue(buffer, recordId_, head);}},
237         {TAG_DELAY_RECORD_FLAG, [&](bool &ret, const std::vector<std::uint8_t> &buffer, TLVHead &head) -> void {
238             ret = ret && ReadValue(buffer, isDelay_, head);}},
239     };
240 }
241 
GetHtmlText() const242 std::shared_ptr<std::string> PasteDataRecord::GetHtmlText() const
243 {
244     return this->htmlText_;
245 }
246 
GetMimeType() const247 std::string PasteDataRecord::GetMimeType() const
248 {
249     return this->mimeType_;
250 }
251 
GetPlainText() const252 std::shared_ptr<std::string> PasteDataRecord::GetPlainText() const
253 {
254     return this->plainText_;
255 }
256 
GetPixelMap() const257 std::shared_ptr<PixelMap> PasteDataRecord::GetPixelMap() const
258 {
259     return this->pixelMap_;
260 }
261 
GetUri() const262 std::shared_ptr<OHOS::Uri> PasteDataRecord::GetUri() const
263 {
264     if (convertUri_.empty()) {
265         return GetOrginUri();
266     }
267     return std::make_shared<OHOS::Uri>(convertUri_);
268 }
269 
ClearPixelMap()270 void PasteDataRecord::ClearPixelMap()
271 {
272     this->pixelMap_ = nullptr;
273 }
274 
SetUri(std::shared_ptr<OHOS::Uri> uri)275 void PasteDataRecord::SetUri(std::shared_ptr<OHOS::Uri> uri)
276 {
277     uri_ = std::move(uri);
278     AddUriEntry();
279 }
280 
GetOrginUri() const281 std::shared_ptr<OHOS::Uri> PasteDataRecord::GetOrginUri() const
282 {
283     if (uri_) {
284         return uri_;
285     }
286     for (auto const& entry: entries_) {
287         if (entry && entry->GetMimeType() == MIMETYPE_TEXT_URI) {
288             return entry->ConvertToUri();
289         }
290     }
291     return nullptr;
292 }
293 
GetWant() const294 std::shared_ptr<OHOS::AAFwk::Want> PasteDataRecord::GetWant() const
295 {
296     return this->want_;
297 }
298 
GetCustomData() const299 std::shared_ptr<MineCustomData> PasteDataRecord::GetCustomData() const
300 {
301     return this->customData_;
302 }
303 
ConvertToText() const304 std::string PasteDataRecord::ConvertToText() const
305 {
306     if (this->htmlText_) {
307         return *this->htmlText_;
308     } else if (this->plainText_) {
309         return *this->plainText_;
310     } else if (this->uri_) {
311         return this->uri_->ToString();
312     } else {
313         return "";
314     }
315 }
316 
Encode(std::vector<std::uint8_t> & buffer)317 bool PasteDataRecord::Encode(std::vector<std::uint8_t> &buffer)
318 {
319     bool ret = Write(buffer, TAG_MIMETYPE, mimeType_);
320     ret = Write(buffer, TAG_HTMLTEXT, htmlText_) && ret;
321     ret = Write(buffer, TAG_WANT, ParcelUtil::Parcelable2Raw(want_.get())) && ret;
322     ret = Write(buffer, TAG_PLAINTEXT, plainText_) && ret;
323     ret = Write(buffer, TAG_URI, ParcelUtil::Parcelable2Raw(uri_.get())) && ret;
324     ret = Write(buffer, TAG_CONVERT_URI, convertUri_) && ret;
325     auto pixelVector = PixelMap2Vector(pixelMap_);
326     ret = Write(buffer, TAG_PIXELMAP, pixelVector) && ret;
327     ret = Write(buffer, TAG_CUSTOM_DATA, customData_) && ret;
328     ret = Write(buffer, TAG_URI_PERMISSION, hasGrantUriPermission_) && ret;
329     ret = Write(buffer, TAG_UDC_UDTYPE, udType_) && ret;
330     ret = Write(buffer, TAG_UDC_DETAILS, details_) && ret;
331     ret = Write(buffer, TAG_UDC_TEXTCONTENT, textContent_) && ret;
332     ret = Write(buffer, TAG_UDC_SYSTEMCONTENTS, systemDefinedContents_) && ret;
333     ret = Write(buffer, TAG_UDC_UDMFVALUE, udmfValue_) && ret;
334     ret = Write(buffer, TAG_UDC_ENTYIES, entries_) && ret;
335     ret = Write(buffer, TAG_DATA_ID, dataId_) && ret;
336     ret = Write(buffer, TAG_RECORD_ID, recordId_) && ret;
337     ret = Write(buffer, TAG_DELAY_RECORD_FLAG, isDelay_) && ret;
338     return ret;
339 }
340 
Decode(const std::vector<std::uint8_t> & buffer)341 bool PasteDataRecord::Decode(const std::vector<std::uint8_t> &buffer)
342 {
343     for (; IsEnough();) {
344         TLVHead head{};
345         bool ret = ReadHead(buffer, head);
346         auto it = decodeMap.find(head.tag);
347         if (it == decodeMap.end()) {
348             ret = ret && Skip(head.len, buffer.size());
349         } else {
350             auto func = it->second;
351             func(ret, buffer, head);
352         }
353         if (!ret) {
354             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "read value,tag:%{public}u, len:%{public}u",
355                 head.tag, head.len);
356             return false;
357         }
358     }
359     return true;
360 }
361 
Count()362 size_t PasteDataRecord::Count()
363 {
364     size_t expectedSize = 0;
365     expectedSize += TLVObject::Count(mimeType_);
366     expectedSize += TLVObject::Count(htmlText_);
367     expectedSize += TLVObject::Count(ParcelUtil::Parcelable2Raw(want_.get()));
368     expectedSize += TLVObject::Count(plainText_);
369     expectedSize += TLVObject::Count(ParcelUtil::Parcelable2Raw(uri_.get()));
370     expectedSize += TLVObject::Count(convertUri_);
371     auto pixelVector = PixelMap2Vector(pixelMap_);
372     expectedSize += TLVObject::Count(pixelVector);
373     expectedSize += TLVObject::Count(customData_);
374     expectedSize += TLVObject::Count(hasGrantUriPermission_);
375     expectedSize += TLVObject::Count(udType_);
376     expectedSize += TLVObject::Count(details_);
377     expectedSize += TLVObject::Count(textContent_);
378     expectedSize += TLVObject::Count(systemDefinedContents_);
379     expectedSize += TLVObject::Count(udmfValue_);
380     expectedSize += TLVObject::Count(entries_);
381     expectedSize += TLVObject::Count(dataId_);
382     expectedSize += TLVObject::Count(recordId_);
383     expectedSize += TLVObject::Count(isDelay_);
384     return expectedSize;
385 }
386 
WriteFd(MessageParcel & parcel,UriHandler & uriHandler,bool isClient)387 bool PasteDataRecord::WriteFd(MessageParcel &parcel, UriHandler &uriHandler, bool isClient)
388 {
389     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "isClient: %{public}d", isClient);
390     if (fd_->GetFd() >= 0) {
391         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "write fd_, fd_ is %{public}d", fd_->GetFd());
392         return parcel.WriteFileDescriptor(fd_->GetFd());
393     }
394     std::string tempUri = GetPassUri();
395     if (tempUri.empty()) {
396         return false;
397     }
398     int32_t fd = uriHandler.ToFd(tempUri, isClient);
399     bool ret = parcel.WriteFileDescriptor(fd);
400     uriHandler.ReleaseFd(fd);
401 
402     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "ret is %{public}d", ret);
403     return ret;
404 }
405 
ReadFd(MessageParcel & parcel,UriHandler & uriHandler)406 bool PasteDataRecord::ReadFd(MessageParcel &parcel, UriHandler &uriHandler)
407 {
408     int32_t fd = parcel.ReadFileDescriptor();
409     if (fd >= 0) {
410         convertUri_ = uriHandler.ToUri(fd);
411     }
412     if (!uriHandler.IsPaste()) {
413         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "Set fd, fd is %{public}d", fd);
414         fd_->SetFd(fd);
415     }
416     return true;
417 }
NeedFd(const UriHandler & uriHandler)418 bool PasteDataRecord::NeedFd(const UriHandler &uriHandler)
419 {
420     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "start");
421     std::string tempUri = GetPassUri();
422     if (tempUri.empty()) {
423         return false;
424     }
425     if (!uriHandler.IsFile(tempUri) && fd_->GetFd() < 0) {
426         PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "invalid file uri, fd:%{public}d", fd_->GetFd());
427         return false;
428     }
429     return true;
430 }
GetPassUri()431 std::string PasteDataRecord::GetPassUri()
432 {
433     std::string tempUri;
434     if (uri_ != nullptr) {
435         tempUri = uri_->ToString();
436     }
437     if (!convertUri_.empty()) {
438         tempUri = convertUri_;
439     }
440     return tempUri;
441 }
442 
ReplaceShareUri(int32_t userId)443 void PasteDataRecord::ReplaceShareUri(int32_t userId)
444 {
445     if (convertUri_.empty()) {
446         return;
447     }
448 
449     // convert uri format: /mnt/hmdfs/100/account/merge_view/services/psteboard_service/.share/xxx.txt
450     constexpr const char *SHARE_PATH_PREFIX = "/mnt/hmdfs/";
451     auto frontPos = convertUri_.find(SHARE_PATH_PREFIX);
452     auto rearPos = convertUri_.find("/account/");
453     if (frontPos == 0 && rearPos != std::string::npos) {
454         convertUri_ = SHARE_PATH_PREFIX + std::to_string(userId) + convertUri_.substr(rearPos);
455     }
456 }
SetConvertUri(const std::string & value)457 void PasteDataRecord::SetConvertUri(const std::string &value)
458 {
459     convertUri_ = value;
460 }
GetConvertUri() const461 std::string PasteDataRecord::GetConvertUri() const
462 {
463     return convertUri_;
464 }
SetGrantUriPermission(bool hasPermission)465 void PasteDataRecord::SetGrantUriPermission(bool hasPermission)
466 {
467     hasGrantUriPermission_ = hasPermission;
468 }
HasGrantUriPermission()469 bool PasteDataRecord::HasGrantUriPermission()
470 {
471     return hasGrantUriPermission_;
472 }
473 
SetTextContent(const std::string & content)474 void PasteDataRecord::SetTextContent(const std::string& content)
475 {
476     this->textContent_ = content;
477 }
478 
GetTextContent() const479 std::string PasteDataRecord::GetTextContent() const
480 {
481     return this->textContent_;
482 }
483 
SetDetails(const Details & details)484 void PasteDataRecord::SetDetails(const Details& details)
485 {
486     this->details_ = std::make_shared<Details>(details);
487 }
488 
GetDetails() const489 std::shared_ptr<Details> PasteDataRecord::GetDetails() const
490 {
491     return this->details_;
492 }
493 
SetSystemDefinedContent(const Details & contents)494 void PasteDataRecord::SetSystemDefinedContent(const Details& contents)
495 {
496     this->systemDefinedContents_ = std::make_shared<Details>(contents);
497 }
498 
GetSystemDefinedContent() const499 std::shared_ptr<Details> PasteDataRecord::GetSystemDefinedContent() const
500 {
501     return this->systemDefinedContents_;
502 }
GetUDType() const503 int32_t PasteDataRecord::GetUDType() const
504 {
505     return this->udType_;
506 }
507 
SetUDType(int32_t type)508 void PasteDataRecord::SetUDType(int32_t type)
509 {
510     this->udType_ = type;
511 }
512 
GetValidTypes(const std::vector<std::string> & types) const513 std::vector<std::string> PasteDataRecord::GetValidTypes(const std::vector<std::string>& types) const
514 {
515     std::vector<std::string> res;
516     auto allTypes = GetUdtTypes();
517     for (auto const& type : types) {
518         if (allTypes.find(type) != allTypes.end()) {
519             res.emplace_back(type);
520         }
521     }
522     return res;
523 }
524 
HasEmptyEntry() const525 bool PasteDataRecord::HasEmptyEntry() const
526 {
527     if (udmfValue_ && !std::holds_alternative<std::monostate>(*udmfValue_)) {
528         return false;
529     }
530     for (auto const &entry : GetEntries()) {
531         if (std::holds_alternative<std::monostate>(entry->GetValue())) {
532             return true;
533         }
534     }
535     return false;
536 }
537 
SetUDMFValue(const std::shared_ptr<EntryValue> & udmfValue)538 void PasteDataRecord::SetUDMFValue(const std::shared_ptr<EntryValue>& udmfValue)
539 {
540     this->udmfValue_ = udmfValue;
541 }
542 
GetUDMFValue()543 std::shared_ptr<EntryValue> PasteDataRecord::GetUDMFValue()
544 {
545     if (udmfValue_) {
546         PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "udmfValue_ is not null");
547         return this->udmfValue_;
548     }
549     if (mimeType_.empty()) {
550         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "mimetype is null");
551         return nullptr;
552     }
553     auto object = std::make_shared<Object>();
554     if (mimeType_ == MIMETYPE_TEXT_PLAIN) {
555         object->value_[UDMF::UNIFORM_DATA_TYPE] = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::PLAIN_TEXT);
556         if (plainText_ != nullptr) {
557             object->value_[UDMF::CONTENT] = *plainText_;
558         }
559     } else if (mimeType_ == MIMETYPE_TEXT_HTML) {
560         object->value_[UDMF::UNIFORM_DATA_TYPE] = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::HTML);
561         if (htmlText_ != nullptr) {
562             object->value_[UDMF::HTML_CONTENT] = *htmlText_;
563         }
564     } else if (mimeType_ == MIMETYPE_PIXELMAP) {
565         object->value_[UDMF::UNIFORM_DATA_TYPE] = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::SYSTEM_DEFINED_PIXEL_MAP);
566         if (pixelMap_ != nullptr) {
567             object->value_[UDMF::PIXEL_MAP] = pixelMap_;
568         }
569     } else if (mimeType_ == MIMETYPE_TEXT_URI) {
570         object->value_[UDMF::UNIFORM_DATA_TYPE] = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::FILE_URI);
571         auto uri = GetUri();
572         if (uri != nullptr) {
573             object->value_[UDMF::FILE_URI_PARAM] = uri->ToString();
574         }
575     } else if (mimeType_ == MIMETYPE_TEXT_WANT) {
576         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "mimeType is want, udmf not surpport");
577     } else {
578         auto itemData = customData_->GetItemData();
579         if (itemData.size() == 0) {
580             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "no customData");
581             return udmfValue_;
582         }
583         if (itemData.size() != 1) {
584             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT,
585                 "not surrport u8 map, mimeType:%{public}s, customData.size:%{public}zu", mimeType_.c_str(),
586                 itemData.size());
587         }
588         udmfValue_ = std::make_shared<EntryValue>(itemData.begin()->second);
589         return udmfValue_;
590     }
591     udmfValue_ = std::make_shared<EntryValue>(object);
592     return udmfValue_;
593 }
594 
GetUdtTypes() const595 std::set<std::string> PasteDataRecord::GetUdtTypes() const
596 {
597     std::set<std::string> types;
598     types.emplace(CommonUtils::Convert2UtdId(udType_, mimeType_));
599     for (auto const& entry: entries_) {
600         types.emplace(entry->GetUtdId());
601     }
602     return types;
603 }
604 
AddEntry(const std::string & utdType,std::shared_ptr<PasteDataEntry> value)605 void PasteDataRecord::AddEntry(const std::string& utdType, std::shared_ptr<PasteDataEntry> value)
606 {
607     if (!value) {
608         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "entry is null");
609         return;
610     }
611     if (utdType != value->GetUtdId()) {
612         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "type is diff. utdtype:%{public}s, UtdId:%{public}s",
613             utdType.c_str(), value->GetUtdId().c_str());
614         return;
615     }
616     // first entry save to record, or record type same
617     if (mimeType_.empty() || utdType == CommonUtils::Convert2UtdId(udType_, mimeType_)) {
618         mimeType_ = value->GetMimeType();
619         auto udType = UDMF::UtdUtils::GetUtdEnumFromUtdId(utdType);
620         udType_ = udType == UDMF::UDType::UD_BUTT ? UDMF::UDType::APPLICATION_DEFINED_RECORD : udType;
621         udmfValue_ = std::make_shared<EntryValue>(value->GetValue());
622         if (mimeType_ == MIMETYPE_PIXELMAP) {
623             pixelMap_ = value->ConvertToPixelMap();
624         } else if (mimeType_ == MIMETYPE_TEXT_HTML) {
625             htmlText_ = value->ConvertToHtml();
626         } else if (mimeType_ == MIMETYPE_TEXT_PLAIN) {
627             plainText_ = value->ConvertToPlianText();
628         } else if (mimeType_ == MIMETYPE_TEXT_URI) {
629             uri_ = value->ConvertToUri();
630         } else if (mimeType_ == MIMETYPE_TEXT_WANT) {
631             want_ = value->ConvertToWant();
632         } else {
633             customData_ = value->ConvertToCustomData();
634         }
635         return;
636     }
637     // not firest entry
638     bool has = false;
639     for (auto& entry : entries_) {
640         if (entry->GetUtdId() == utdType) {
641             entry = value;
642             has = true;
643             break;
644         }
645     }
646     if (!has) {
647         entries_.emplace_back(value);
648     }
649 }
650 
GetEntry(const std::string & utdType) const651 std::shared_ptr<PasteDataEntry> PasteDataRecord::GetEntry(const std::string& utdType) const
652 {
653     if (udmfValue_ && CommonUtils::Convert2UtdId(udType_, mimeType_) == utdType) {
654         return std::make_shared<PasteDataEntry>(utdType, *udmfValue_);
655     }
656     for (auto const& entry : entries_) {
657         if (entry->GetUtdId() == utdType ||
658             (CommonUtils::IsFileUri(utdType) && CommonUtils::IsFileUri(entry->GetUtdId()))) {
659             return entry;
660         }
661     }
662     return nullptr;
663 }
664 
GetEntries() const665 std::vector<std::shared_ptr<PasteDataEntry>> PasteDataRecord::GetEntries() const
666 {
667     std::vector<std::shared_ptr<PasteDataEntry>> entries = entries_;
668     if (udmfValue_) {
669         entries.insert(entries.begin(),
670             std::make_shared<PasteDataEntry>(CommonUtils::Convert2UtdId(udType_, mimeType_), *udmfValue_));
671     }
672     return entries;
673 }
674 
SetDataId(uint32_t dataId)675 void PasteDataRecord::SetDataId(uint32_t dataId)
676 {
677     dataId_ = dataId;
678 }
679 
GetDataId() const680 uint32_t PasteDataRecord::GetDataId() const
681 {
682     return dataId_;
683 }
684 
SetRecordId(uint32_t recordId)685 void PasteDataRecord::SetRecordId(uint32_t recordId)
686 {
687     recordId_ = recordId;
688 }
689 
GetRecordId() const690 uint32_t PasteDataRecord::GetRecordId() const
691 {
692     return recordId_;
693 }
694 
SetDelayRecordFlag(bool isDelay)695 void PasteDataRecord::SetDelayRecordFlag(bool isDelay)
696 {
697     isDelay_ = isDelay;
698 }
699 
IsDelayRecord() const700 bool PasteDataRecord::IsDelayRecord() const
701 {
702     return isDelay_;
703 }
704 
~FileDescriptor()705 FileDescriptor::~FileDescriptor()
706 {
707     if (fd_ >= 0) {
708         close(fd_);
709         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "close fd_: %{public}d", fd_);
710     }
711 }
SetFd(int32_t fd)712 void FileDescriptor::SetFd(int32_t fd)
713 {
714     fd_ = fd;
715 }
GetFd() const716 int32_t FileDescriptor::GetFd() const
717 {
718     return fd_;
719 }
720 } // namespace MiscServices
721 } // namespace OHOS