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