1 /*
2 * Copyright (C) 2024 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_entry.h"
16
17 #include "common/constant.h"
18 #include "pasteboard_hilog.h"
19 namespace OHOS {
20 namespace MiscServices {
21
22 const char *PASTE_FILE_SIZE = "pasteFileSize";
23
24 enum TAG_CUSTOMDATA : uint16_t {
25 TAG_ITEM_DATA = TAG_BUFF + 1,
26 };
27
28 enum TAG_ENTRY : uint16_t {
29 TAG_ENTRY_UTDID = TAG_BUFF + 1,
30 TAG_ENTRY_MIMETYPE,
31 TAG_ENTRY_VALUE,
32 };
33
GetItemData()34 std::map<std::string, std::vector<uint8_t>> MineCustomData::GetItemData()
35 {
36 return this->itemData_;
37 }
38
AddItemData(const std::string & mimeType,const std::vector<uint8_t> & arrayBuffer)39 void MineCustomData::AddItemData(const std::string &mimeType, const std::vector<uint8_t> &arrayBuffer)
40 {
41 itemData_.emplace(mimeType, arrayBuffer);
42 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "itemData_.size = %{public}zu", itemData_.size());
43 }
44
EncodeTLV(WriteOnlyBuffer & buffer) const45 bool MineCustomData::EncodeTLV(WriteOnlyBuffer &buffer) const
46 {
47 return buffer.Write(TAG_ITEM_DATA, itemData_);
48 }
49
DecodeTLV(ReadOnlyBuffer & buffer)50 bool MineCustomData::DecodeTLV(ReadOnlyBuffer &buffer)
51 {
52 for (; buffer.IsEnough();) {
53 TLVHead head{};
54 bool ret = buffer.ReadHead(head);
55 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret, false, PASTEBOARD_MODULE_COMMON, "read head failed");
56 switch (head.tag) {
57 case TAG_ITEM_DATA:
58 ret = buffer.ReadValue(itemData_, head);
59 break;
60 default:
61 ret = buffer.Skip(head.len);
62 break;
63 }
64 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret, false, PASTEBOARD_MODULE_COMMON,
65 "read value failed, tag=%{public}hu, len=%{public}u", head.tag, head.len);
66 }
67 return true;
68 }
69
CountTLV() const70 size_t MineCustomData::CountTLV() const
71 {
72 return TLVCountable::Count(itemData_);
73 }
74
PasteDataEntry(const PasteDataEntry & entry)75 PasteDataEntry::PasteDataEntry(const PasteDataEntry &entry)
76 : utdId_(entry.utdId_), mimeType_(entry.mimeType_), value_(entry.value_)
77 {
78 }
79
operator =(const PasteDataEntry & entry)80 PasteDataEntry &PasteDataEntry::operator=(const PasteDataEntry &entry)
81 {
82 if (this == &entry) {
83 return *this;
84 }
85 this->utdId_ = entry.GetUtdId();
86 this->mimeType_ = entry.GetMimeType();
87 this->value_ = entry.GetValue();
88 return *this;
89 }
90
PasteDataEntry(const std::string & utdId,const EntryValue & value)91 PasteDataEntry::PasteDataEntry(const std::string &utdId, const EntryValue &value) : utdId_(utdId), value_(value)
92 {
93 mimeType_ = CommonUtils::Convert2MimeType(utdId_);
94 }
95
PasteDataEntry(const std::string & utdId,const std::string & mimeType,const EntryValue & value)96 PasteDataEntry::PasteDataEntry(const std::string &utdId, const std::string &mimeType, const EntryValue &value)
97 : utdId_(utdId), mimeType_(std::move(mimeType)), value_(std::move(value))
98 {
99 }
100
SetUtdId(const std::string & utdId)101 void PasteDataEntry::SetUtdId(const std::string &utdId)
102 {
103 utdId_ = utdId;
104 }
105
GetUtdId() const106 std::string PasteDataEntry::GetUtdId() const
107 {
108 return utdId_;
109 }
110
SetMimeType(const std::string & mimeType)111 void PasteDataEntry::SetMimeType(const std::string &mimeType)
112 {
113 mimeType_ = mimeType;
114 }
115
GetMimeType() const116 std::string PasteDataEntry::GetMimeType() const
117 {
118 return mimeType_;
119 }
120
GetValue() const121 EntryValue PasteDataEntry::GetValue() const
122 {
123 return value_;
124 }
125
SetValue(const EntryValue & value)126 void PasteDataEntry::SetValue(const EntryValue &value)
127 {
128 value_ = value;
129 }
130
EncodeTLV(WriteOnlyBuffer & buffer) const131 bool PasteDataEntry::EncodeTLV(WriteOnlyBuffer &buffer) const
132 {
133 bool ret = buffer.Write(TAG_ENTRY_UTDID, utdId_);
134 ret = ret && buffer.Write(TAG_ENTRY_MIMETYPE, mimeType_);
135 ret = ret && buffer.Write(TAG_ENTRY_VALUE, value_);
136 return ret;
137 }
138
DecodeTLV(ReadOnlyBuffer & buffer)139 bool PasteDataEntry::DecodeTLV(ReadOnlyBuffer &buffer)
140 {
141 for (; buffer.IsEnough();) {
142 TLVHead head{};
143 bool ret = buffer.ReadHead(head);
144 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret, false, PASTEBOARD_MODULE_CLIENT, "read head failed");
145 switch (head.tag) {
146 case TAG_ENTRY_UTDID:
147 ret = buffer.ReadValue(utdId_, head);
148 break;
149 case TAG_ENTRY_MIMETYPE:
150 ret = buffer.ReadValue(mimeType_, head);
151 break;
152 case TAG_ENTRY_VALUE:
153 ret = buffer.ReadValue(value_, head);
154 break;
155 default:
156 ret = buffer.Skip(head.len);
157 break;
158 }
159 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret, false, PASTEBOARD_MODULE_COMMON,
160 "read value failed, tag=%{public}hu, len=%{public}u", head.tag, head.len);
161 }
162 return true;
163 }
164
CountTLV() const165 size_t PasteDataEntry::CountTLV() const
166 {
167 return TLVCountable::Count(utdId_) + TLVCountable::Count(mimeType_) + TLVCountable::Count(value_);
168 }
169
ConvertToPlainText() const170 std::shared_ptr<std::string> PasteDataEntry::ConvertToPlainText() const
171 {
172 std::string res;
173 auto utdId = GetUtdId();
174 auto entry = GetValue();
175 if (std::holds_alternative<std::string>(entry)) {
176 res = std::get<std::string>(entry);
177 return std::make_shared<std::string>(res);
178 }
179 if (!std::holds_alternative<std::shared_ptr<Object>>(entry)) {
180 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "value error, no plaintext");
181 return nullptr;
182 }
183 auto object = std::get<std::shared_ptr<Object>>(entry);
184 if (utdId == UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDType::PLAIN_TEXT)) {
185 object->GetValue(UDMF::CONTENT, res);
186 } else if (utdId == UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDType::HTML)) {
187 object->GetValue(UDMF::PLAIN_CONTENT, res);
188 } else {
189 object->GetValue(UDMF::URL, res);
190 }
191 return std::make_shared<std::string>(res);
192 }
193
ConvertToHtml() const194 std::shared_ptr<std::string> PasteDataEntry::ConvertToHtml() const
195 {
196 std::string res;
197 if (GetUtdId() != UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDType::HTML)) {
198 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "type error, utdId:%{public}s", GetUtdId().c_str());
199 return nullptr;
200 }
201 auto entry = GetValue();
202 if (std::holds_alternative<std::string>(entry)) {
203 res = std::get<std::string>(entry);
204 return std::make_shared<std::string>(res);
205 }
206 if (!std::holds_alternative<std::shared_ptr<Object>>(entry)) {
207 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "value error, no html");
208 return nullptr;
209 }
210 auto object = std::get<std::shared_ptr<Object>>(entry);
211 object->GetValue(UDMF::HTML_CONTENT, res);
212 return std::make_shared<std::string>(res);
213 }
214
ConvertToUri() const215 std::shared_ptr<Uri> PasteDataEntry::ConvertToUri() const
216 {
217 std::string res;
218 if (!CommonUtils::IsFileUri(GetUtdId())) {
219 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "type error, utdId:%{public}s", GetUtdId().c_str());
220 return nullptr;
221 }
222 auto entry = GetValue();
223 if (std::holds_alternative<std::string>(entry)) {
224 res = std::get<std::string>(entry);
225 return std::make_shared<Uri>(Uri(res));
226 }
227 if (!std::holds_alternative<std::shared_ptr<Object>>(entry)) {
228 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "value error, no uri");
229 return nullptr;
230 }
231 auto object = std::get<std::shared_ptr<Object>>(entry);
232 object->GetValue(UDMF::FILE_URI_PARAM, res);
233 return std::make_shared<Uri>(Uri(res));
234 }
235
ConvertToWant() const236 std::shared_ptr<AAFwk::Want> PasteDataEntry::ConvertToWant() const
237 {
238 if (GetUtdId() != UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDType::OPENHARMONY_WANT)) {
239 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "type error, utdId:%{public}s", GetUtdId().c_str());
240 return nullptr;
241 }
242 auto entry = GetValue();
243 if (!std::holds_alternative<std::shared_ptr<AAFwk::Want>>(entry)) {
244 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "value error, no want");
245 return nullptr;
246 }
247 // no uds want
248 return std::get<std::shared_ptr<AAFwk::Want>>(entry);
249 }
250
ConvertToPixelMap() const251 std::shared_ptr<Media::PixelMap> PasteDataEntry::ConvertToPixelMap() const
252 {
253 auto utdId = GetUtdId();
254 if (utdId != UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDType::SYSTEM_DEFINED_PIXEL_MAP)) {
255 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "type error, utdId:%{public}s", utdId.c_str());
256 return nullptr;
257 }
258 auto entry = GetValue();
259 if (std::holds_alternative<std::shared_ptr<Media::PixelMap>>(entry)) {
260 return std::get<std::shared_ptr<Media::PixelMap>>(entry);
261 }
262 if (!std::holds_alternative<std::shared_ptr<Object>>(entry)) {
263 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "value error, no pixelmap");
264 return nullptr;
265 }
266 auto object = std::get<std::shared_ptr<Object>>(entry);
267 std::string objecType;
268 if (!object->GetValue(UDMF::UNIFORM_DATA_TYPE, objecType)) {
269 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "type error, utdId:%{public}s", utdId.c_str());
270 return nullptr;
271 }
272 if (objecType != UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::SYSTEM_DEFINED_PIXEL_MAP)) {
273 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "type error, objecType:%{public}s", objecType.c_str());
274 return nullptr;
275 }
276 auto val = object->value_[UDMF::PIXEL_MAP];
277 if (std::holds_alternative<std::shared_ptr<Media::PixelMap>>(val)) {
278 return std::get<std::shared_ptr<Media::PixelMap>>(val);
279 }
280 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "value error, no pixelmap");
281 return nullptr;
282 }
283
ConvertToCustomData() const284 std::shared_ptr<MineCustomData> PasteDataEntry::ConvertToCustomData() const
285 {
286 auto entry = GetValue();
287 MineCustomData customdata;
288 if (std::holds_alternative<std::vector<uint8_t>>(entry)) {
289 customdata.AddItemData(GetMimeType(), std::get<std::vector<uint8_t>>(entry));
290 return std::make_shared<MineCustomData>(customdata);
291 }
292 if (!std::holds_alternative<std::shared_ptr<Object>>(entry)) {
293 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "value error, no cust data, utdId:%{public}s", utdId_.c_str());
294 return nullptr;
295 }
296 auto object = std::get<std::shared_ptr<Object>>(entry);
297 std::string objecType;
298 if (!object->GetValue(UDMF::UNIFORM_DATA_TYPE, objecType)) {
299 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "type error, utdId:%{public}s", utdId_.c_str());
300 return nullptr;
301 }
302 if (objecType != GetUtdId()) {
303 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "type diff error, utdId:%{public}s, objecType:%{public}s",
304 utdId_.c_str(), objecType.c_str());
305 }
306 std::vector<uint8_t> recordValue;
307 if (!object->GetValue(UDMF::ARRAY_BUFFER, recordValue)) {
308 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "get value error, utdId:%{public}s", utdId_.c_str());
309 return nullptr;
310 }
311 customdata.AddItemData(utdId_, recordValue);
312 return std::make_shared<MineCustomData>(customdata);
313 }
314
HasContent(const std::string & utdId) const315 bool PasteDataEntry::HasContent(const std::string &utdId) const
316 {
317 auto mimeType = CommonUtils::Convert2MimeType(utdId);
318 return HasContentByMimeType(mimeType);
319 }
320
HasContentByMimeType(const std::string & mimeType) const321 bool PasteDataEntry::HasContentByMimeType(const std::string &mimeType) const
322 {
323 if (mimeType == MIMETYPE_PIXELMAP) {
324 return ConvertToPixelMap() != nullptr;
325 } else if (mimeType == MIMETYPE_TEXT_HTML) {
326 auto html = ConvertToHtml();
327 return html != nullptr && !html->empty();
328 } else if (mimeType == MIMETYPE_TEXT_PLAIN) {
329 auto plainText = ConvertToPlainText();
330 return plainText != nullptr && !plainText->empty();
331 } else if (mimeType == MIMETYPE_TEXT_URI) {
332 auto uri = ConvertToUri();
333 return uri != nullptr && !uri->ToString().empty();
334 } else if (mimeType == MIMETYPE_TEXT_WANT) {
335 return ConvertToWant() != nullptr;
336 } else {
337 return ConvertToCustomData() != nullptr;
338 }
339 }
340
SetFileSize(int64_t fileSize)341 void PasteDataEntry::SetFileSize(int64_t fileSize)
342 {
343 auto entry = GetValue();
344 PASTEBOARD_CHECK_AND_RETURN_LOGE(std::holds_alternative<std::shared_ptr<Object>>(entry), PASTEBOARD_MODULE_COMMON,
345 "entry not contain object");
346
347 auto object = std::get<std::shared_ptr<Object>>(entry);
348 PASTEBOARD_CHECK_AND_RETURN_LOGE(object != nullptr, PASTEBOARD_MODULE_COMMON, "entry object is null");
349
350 object->value_[PASTE_FILE_SIZE] = fileSize;
351 }
352
GetFileSize() const353 int64_t PasteDataEntry::GetFileSize() const
354 {
355 auto entry = GetValue();
356 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(std::holds_alternative<std::shared_ptr<Object>>(entry), 0,
357 PASTEBOARD_MODULE_COMMON, "entry not contain object");
358
359 auto object = std::get<std::shared_ptr<Object>>(entry);
360 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(object != nullptr, 0, PASTEBOARD_MODULE_COMMON, "entry object is null");
361
362 int64_t fileSize = 0L;
363 object->GetValue(PASTE_FILE_SIZE, fileSize);
364 return fileSize;
365 }
366
Convert(UDType uDType)367 std::string CommonUtils::Convert(UDType uDType)
368 {
369 switch (uDType) {
370 // fall-through
371 case UDType::PLAIN_TEXT:
372 // fall-through
373 case UDType::HYPERLINK:
374 return MIMETYPE_TEXT_PLAIN;
375 // fall-through
376 case UDType::HTML:
377 return MIMETYPE_TEXT_HTML;
378 // fall-through
379 case UDType::FILE:
380 // fall-through
381 case UDType::IMAGE:
382 // fall-through
383 case UDType::VIDEO:
384 // fall-through
385 case UDType::AUDIO:
386 // fall-through
387 case UDType::FOLDER:
388 // fall-through
389 case UDType::FILE_URI:
390 return MIMETYPE_TEXT_URI;
391 // fall-through
392 case UDType::SYSTEM_DEFINED_PIXEL_MAP:
393 return MIMETYPE_PIXELMAP;
394 // fall-through
395 case UDType::OPENHARMONY_WANT:
396 return MIMETYPE_TEXT_WANT;
397 default:
398 return UDMF::UtdUtils::GetUtdIdFromUtdEnum(uDType);
399 }
400 }
401
Convert2MimeType(const std::string & utdId)402 std::string CommonUtils::Convert2MimeType(const std::string &utdId)
403 {
404 if (utdId == UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDType::PLAIN_TEXT) ||
405 utdId == UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDType::HYPERLINK)) {
406 return MIMETYPE_TEXT_PLAIN;
407 }
408 if (utdId == UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDType::HTML)) {
409 return MIMETYPE_TEXT_HTML;
410 }
411 if (IsFileUri(utdId)) {
412 return MIMETYPE_TEXT_URI;
413 }
414 if (utdId == UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDType::SYSTEM_DEFINED_PIXEL_MAP)) {
415 return MIMETYPE_PIXELMAP;
416 }
417 if (utdId == UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDType::OPENHARMONY_WANT)) {
418 return MIMETYPE_TEXT_WANT;
419 }
420 return utdId;
421 }
422
423 // other is appdefined-types
Convert2UtdId(int32_t uDType,const std::string & mimeType)424 std::string CommonUtils::Convert2UtdId(int32_t uDType, const std::string &mimeType)
425 {
426 if (mimeType == MIMETYPE_TEXT_PLAIN && uDType == UDMF::HYPERLINK) {
427 return UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDType::HYPERLINK);
428 }
429 if (mimeType == MIMETYPE_TEXT_PLAIN) {
430 return UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDType::PLAIN_TEXT);
431 }
432 if (mimeType == MIMETYPE_TEXT_URI) {
433 return UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDType::FILE_URI);
434 }
435 if (mimeType == MIMETYPE_TEXT_HTML) {
436 return UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDType::HTML);
437 }
438 if (mimeType == MIMETYPE_TEXT_WANT) {
439 return UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDType::OPENHARMONY_WANT);
440 }
441 if (mimeType == MIMETYPE_PIXELMAP) {
442 return UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDType::SYSTEM_DEFINED_PIXEL_MAP);
443 }
444 return mimeType;
445 }
446
Convert(int32_t uDType,const std::string & mimeType)447 UDMF::UDType CommonUtils::Convert(int32_t uDType, const std::string &mimeType)
448 {
449 if (uDType != UDMF::UD_BUTT) {
450 return static_cast<UDType>(uDType);
451 }
452 if (mimeType == MIMETYPE_TEXT_URI) {
453 return UDMF::FILE_URI;
454 }
455 if (mimeType == MIMETYPE_TEXT_PLAIN) {
456 return UDMF::PLAIN_TEXT;
457 }
458 if (mimeType == MIMETYPE_TEXT_HTML) {
459 return UDMF::HTML;
460 }
461 if (mimeType == MIMETYPE_TEXT_WANT) {
462 return UDMF::OPENHARMONY_WANT;
463 }
464 if (mimeType == MIMETYPE_PIXELMAP) {
465 return UDMF::SYSTEM_DEFINED_PIXEL_MAP;
466 }
467 auto type = UDMF::UtdUtils::GetUtdEnumFromUtdId(mimeType);
468 if (type != UDMF::UD_BUTT) {
469 return static_cast<UDType>(type);
470 }
471 return UDMF::APPLICATION_DEFINED_RECORD;
472 }
473
IsFileUri(const std::string & utdId)474 bool CommonUtils::IsFileUri(const std::string &utdId)
475 {
476 return utdId == UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDType::FILE_URI) ||
477 utdId == UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDType::FILE) ||
478 utdId == UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDType::AUDIO) ||
479 utdId == UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDType::IMAGE) ||
480 utdId == UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDType::FOLDER) ||
481 utdId == UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDType::VIDEO);
482 }
483 } // namespace MiscServices
484 } // namespace OHOS