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