1 /*
2 * Copyright (c) 2022 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 "pasteboard_client_adapter_impl.h"
17
18 #include <mutex>
19 #include <securec.h>
20
21 #include "hisysevent_adapter.h"
22 #include "media_errors.h"
23 #include "nweb_log.h"
24 #include "ohos_adapter_helper.h"
25 #include "pasteboard_error.h"
26 #include "remote_uri.h"
27
28 using namespace OHOS::MiscServices;
29 using namespace OHOS::DistributedFS::ModuleRemoteUri;
30
31 namespace OHOS::NWeb {
32 constexpr char PASTE_BOARD_ERROR[] = "PASTE_BOARD_ERROR";
33 constexpr char ERROR_CODE[] = "ERROR_CODE";
34 constexpr char RECORD_SIZE[] = "RECORD_SIZE";
35 constexpr char DATA_TYPE[] = "DATA_TYPE";
36 constexpr char MIMETYPE_HYBRID[] = "hybrid";
37 constexpr char MIMETYPE_NULL[] = "null";
38 constexpr char SPAN_STRING_TAG[] = "openharmony.styled-string";
39 constexpr char CUSTOM_DATA_TAG[] = "openharmony.arkweb.custom-data";
40 constexpr char CUSTOM_DATA_TAG2[] = "ohos/custom-data";
41
PasteboardObserverAdapterImpl(std::shared_ptr<PasteboardObserverAdapter> observer)42 PasteboardObserverAdapterImpl::PasteboardObserverAdapterImpl(
43 std::shared_ptr<PasteboardObserverAdapter> observer)
44 : observer_(observer) {}
45
OnPasteboardChanged()46 void PasteboardObserverAdapterImpl::OnPasteboardChanged()
47 {
48 if (observer_) {
49 observer_->OnPasteboardChanged();
50 }
51 }
52
PasteDataRecordAdapterImpl()53 PasteDataRecordAdapterImpl::PasteDataRecordAdapterImpl()
54 {
55 record_ = std::make_shared<PasteDataRecord>();
56 }
57
PasteDataRecordAdapterImpl(std::shared_ptr<PasteDataRecord> record)58 PasteDataRecordAdapterImpl::PasteDataRecordAdapterImpl(
59 std::shared_ptr<PasteDataRecord> record)
60 : record_(record) {}
61
PasteDataRecordAdapterImpl(const std::string & mimeType)62 PasteDataRecordAdapterImpl::PasteDataRecordAdapterImpl(
63 const std::string& mimeType)
64 {
65 builder_ = std::make_shared<PasteDataRecord::Builder>(mimeType);
66 if (builder_) {
67 record_ = builder_->Build();
68 }
69 }
70
PasteDataRecordAdapterImpl(const std::string & mimeType,std::shared_ptr<std::string> htmlText,std::shared_ptr<std::string> plainText)71 PasteDataRecordAdapterImpl::PasteDataRecordAdapterImpl(
72 const std::string& mimeType,
73 std::shared_ptr<std::string> htmlText,
74 std::shared_ptr<std::string> plainText)
75 {
76 record_ = std::make_shared<PasteDataRecord>(mimeType,
77 htmlText,
78 nullptr,
79 plainText,
80 nullptr);
81 }
82
NewRecord(const std::string & mimeType)83 std::shared_ptr<PasteDataRecordAdapter> PasteDataRecordAdapter::NewRecord(
84 const std::string& mimeType)
85 {
86 // To adapt to multiple entries, the mime type of the record will be specified when writing the first data.
87 (void)mimeType;
88 return std::make_shared<PasteDataRecordAdapterImpl>();
89 }
90
NewRecord(const std::string & mimeType,std::shared_ptr<std::string> htmlText,std::shared_ptr<std::string> plainText)91 std::shared_ptr<PasteDataRecordAdapter> PasteDataRecordAdapter::NewRecord(
92 const std::string& mimeType,
93 std::shared_ptr<std::string> htmlText,
94 std::shared_ptr<std::string> plainText)
95 {
96 return std::make_shared<PasteDataRecordAdapterImpl>(mimeType,
97 htmlText,
98 plainText);
99 }
100
SetHtmlText(std::shared_ptr<std::string> htmlText)101 bool PasteDataRecordAdapterImpl::SetHtmlText(std::shared_ptr<std::string> htmlText)
102 {
103 return SetHtmlText(htmlText, nullptr);
104 }
105
SetHtmlText(std::shared_ptr<std::string> htmlText,std::shared_ptr<std::string> plainText)106 bool PasteDataRecordAdapterImpl::SetHtmlText(
107 std::shared_ptr<std::string> htmlText, std::shared_ptr<std::string> plainText)
108 {
109 if (!record_ || !htmlText) {
110 WVLOG_E("record_ or htmlText is null");
111 return false;
112 }
113 auto utdId = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::HTML);
114 auto object = std::make_shared<Object>();
115 if (!object) {
116 WVLOG_E("udmf object create failed");
117 return false;
118 }
119 object->value_[UDMF::UNIFORM_DATA_TYPE] = utdId;
120 object->value_[UDMF::HTML_CONTENT] = *htmlText;
121 if (plainText) {
122 object->value_[UDMF::PLAIN_CONTENT] = *plainText;
123 }
124 record_->AddEntry(utdId, std::make_shared<PasteDataEntry>(utdId, object));
125 return true;
126 }
127
SetPlainText(std::shared_ptr<std::string> plainText)128 bool PasteDataRecordAdapterImpl::SetPlainText(std::shared_ptr<std::string> plainText)
129 {
130 if (!record_ || !plainText) {
131 WVLOG_E("record_ or plainText is null");
132 return false;
133 }
134 if (auto htmlText = record_->GetHtmlText(); htmlText && !htmlText->empty()) {
135 SetHtmlText(htmlText, plainText);
136 }
137 auto utdId = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::PLAIN_TEXT);
138 auto object = std::make_shared<Object>();
139 if (!object) {
140 WVLOG_E("udmf object create failed");
141 return false;
142 }
143 object->value_[UDMF::UNIFORM_DATA_TYPE] = utdId;
144 object->value_[UDMF::CONTENT] = *plainText;
145 record_->AddEntry(utdId, std::make_shared<PasteDataEntry>(utdId, object));
146 return true;
147 }
148
SetUri(const std::string & uriString)149 bool PasteDataRecordAdapterImpl::SetUri(const std::string& uriString)
150 {
151 if (!record_ || uriString.empty()) {
152 WVLOG_E("record_ or uriString is null");
153 return false;
154 }
155 auto utdId = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::FILE_URI);
156 record_->AddEntry(utdId, std::make_shared<PasteDataEntry>(utdId, uriString));
157 return true;
158 }
159
SetCustomData(PasteCustomData & data)160 bool PasteDataRecordAdapterImpl::SetCustomData(PasteCustomData& data)
161 {
162 if (!record_ || data.empty()) {
163 WVLOG_E("custom data is empty or record_ is null");
164 return false;
165 }
166 for (PasteCustomData::iterator iter = data.begin(); iter != data.end(); ++iter) {
167 record_->AddEntry(iter->first, std::make_shared<PasteDataEntry>(iter->first, iter->second));
168 }
169 return true;
170 }
171
ImageToClipboardAlphaType(const Media::ImageInfo & imgInfo)172 ClipBoardImageAlphaType PasteDataRecordAdapterImpl::ImageToClipboardAlphaType
173 (const Media::ImageInfo &imgInfo)
174 {
175 switch (imgInfo.alphaType) {
176 case Media::AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN :
177 return ClipBoardImageAlphaType::ALPHA_TYPE_UNKNOWN;
178 case Media::AlphaType::IMAGE_ALPHA_TYPE_OPAQUE :
179 return ClipBoardImageAlphaType::ALPHA_TYPE_OPAQUE;
180 case Media::AlphaType::IMAGE_ALPHA_TYPE_PREMUL :
181 return ClipBoardImageAlphaType::ALPHA_TYPE_PREMULTIPLIED;
182 default :
183 return ClipBoardImageAlphaType::ALPHA_TYPE_UNKNOWN;
184 }
185 }
186
ImageToClipboardColorType(const Media::ImageInfo & imgInfo)187 ClipBoardImageColorType PasteDataRecordAdapterImpl::ImageToClipboardColorType
188 (const Media::ImageInfo &imgInfo)
189 {
190 switch (imgInfo.pixelFormat) {
191 case Media::PixelFormat::RGBA_8888 :
192 return ClipBoardImageColorType::COLOR_TYPE_RGBA_8888;
193 case Media::PixelFormat::BGRA_8888 :
194 return ClipBoardImageColorType::COLOR_TYPE_BGRA_8888;
195 default :
196 return ClipBoardImageColorType::COLOR_TYPE_UNKNOWN;
197 }
198 }
199
ClipboardToImageAlphaType(ClipBoardImageAlphaType alphaType)200 Media::AlphaType PasteDataRecordAdapterImpl::ClipboardToImageAlphaType
201 (ClipBoardImageAlphaType alphaType)
202 {
203 switch (alphaType) {
204 case ClipBoardImageAlphaType::ALPHA_TYPE_UNKNOWN :
205 return Media::AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN;
206 case ClipBoardImageAlphaType::ALPHA_TYPE_OPAQUE :
207 return Media::AlphaType::IMAGE_ALPHA_TYPE_OPAQUE;
208 case ClipBoardImageAlphaType::ALPHA_TYPE_PREMULTIPLIED :
209 return Media::AlphaType::IMAGE_ALPHA_TYPE_PREMUL;
210 default :
211 return Media::AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN;
212 }
213 }
214
ClipboardToImageColorType(ClipBoardImageColorType colorType)215 Media::PixelFormat PasteDataRecordAdapterImpl::ClipboardToImageColorType
216 (ClipBoardImageColorType colorType)
217 {
218 switch (colorType) {
219 case ClipBoardImageColorType::COLOR_TYPE_RGBA_8888 :
220 return Media::PixelFormat::RGBA_8888;
221 case ClipBoardImageColorType::COLOR_TYPE_BGRA_8888 :
222 return Media::PixelFormat::BGRA_8888;
223 default :
224 return Media::PixelFormat::UNKNOWN;
225 }
226 }
227
SetImgData(std::shared_ptr<ClipBoardImageDataAdapter> imageData)228 bool PasteDataRecordAdapterImpl::SetImgData(std::shared_ptr<ClipBoardImageDataAdapter> imageData)
229 {
230 if (imageData == nullptr) {
231 WVLOG_E("imageData is null");
232 return false;
233 }
234 Media::InitializationOptions opt;
235 opt.size.width = imageData->GetWidth();
236 opt.size.height = imageData->GetHeight();
237 opt.pixelFormat = ClipboardToImageColorType(imageData->GetColorType());
238 opt.alphaType = ClipboardToImageAlphaType(imageData->GetAlphaType());
239 opt.editable = true;
240 std::unique_ptr<Media::PixelMap> pixelMap = Media::PixelMap::Create(opt);
241 if (pixelMap == nullptr) {
242 WVLOG_E("create pixel map failed");
243 return false;
244 }
245 uint64_t stride = static_cast<uint64_t>(imageData->GetWidth()) << 2;
246 uint64_t bufferSize = stride * static_cast<uint64_t>(imageData->GetHeight());
247 uint32_t ret = pixelMap->WritePixels(reinterpret_cast<const uint8_t *>(imageData->GetData()), bufferSize);
248 if (ret != Media::SUCCESS) {
249 WVLOG_E("write pixel map failed %{public}u", ret);
250 return false;
251 }
252
253 std::shared_ptr<Media::PixelMap> pixelMapIn = move(pixelMap);
254
255 if (!record_) {
256 WVLOG_E("record_ is null");
257 return false;
258 }
259 auto utdId = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::SYSTEM_DEFINED_PIXEL_MAP);
260 auto object = std::make_shared<Object>();
261 if (!object) {
262 WVLOG_E("udmf object create failed");
263 return false;
264 }
265 object->value_[UDMF::UNIFORM_DATA_TYPE] = utdId;
266 object->value_[UDMF::PIXEL_MAP] = pixelMapIn;
267 record_->AddEntry(utdId, std::make_shared<PasteDataEntry>(utdId, object));
268 return true;
269 }
270
GetMimeType()271 std::string PasteDataRecordAdapterImpl::GetMimeType()
272 {
273 return (record_ != nullptr) ? record_->GetMimeType() : "";
274 }
275
GetHtmlText()276 std::shared_ptr<std::string> PasteDataRecordAdapterImpl::GetHtmlText()
277 {
278 if (!record_) {
279 WVLOG_E("record_ is null");
280 return nullptr;
281 }
282 auto entry = record_->GetEntry(UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::HTML));
283 return (entry ? entry->ConvertToHtml() : nullptr);
284 }
285
GetPlainText()286 std::shared_ptr<std::string> PasteDataRecordAdapterImpl::GetPlainText()
287 {
288 if (!record_) {
289 WVLOG_E("record_ is null");
290 return nullptr;
291 }
292 auto entry = record_->GetEntry(UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::PLAIN_TEXT));
293 if (entry) {
294 return entry->ConvertToPlianText();
295 }
296 auto tempPlainText = record_->GetPlainText();
297 if (tempPlainText && !tempPlainText->empty()) {
298 WVLOG_I("Compatibility adaptation with old versions of read plainText");
299 return tempPlainText;
300 }
301 return nullptr;
302 }
303
GetPixelMap()304 std::shared_ptr<Media::PixelMap> PasteDataRecordAdapterImpl::GetPixelMap()
305 {
306 if (record_ == nullptr) {
307 WVLOG_E("record_ is null");
308 return nullptr;
309 }
310
311 std::shared_ptr<Media::PixelMap> pixelMap = nullptr;
312 auto entry = record_->GetEntry(UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::SYSTEM_DEFINED_PIXEL_MAP));
313 if (entry) {
314 pixelMap = entry->ConvertToPixelMap();
315 }
316 if (pixelMap == nullptr) {
317 pixelMap = record_->GetPixelMap();
318 if (pixelMap) {
319 WVLOG_I("Compatibility adaptation with old versions of read pixelMap");
320 }
321 }
322 return pixelMap;
323 }
324
GetImgData(std::shared_ptr<ClipBoardImageDataAdapter> imageData)325 bool PasteDataRecordAdapterImpl::GetImgData(std::shared_ptr<ClipBoardImageDataAdapter> imageData)
326 {
327 if (record_ == nullptr) {
328 WVLOG_E("record_ is null");
329 return false;
330 }
331
332 if (imageData == nullptr) {
333 WVLOG_E("imageData is null");
334 return false;
335 }
336
337 std::shared_ptr<Media::PixelMap> pixelMap = GetPixelMap();
338 if (pixelMap == nullptr) {
339 WVLOG_E("pixelMap is null");
340 return false;
341 }
342
343 Media::ImageInfo imgInfo;
344 ClearImgBuffer();
345 bufferSize_ = pixelMap->GetCapacity();
346 if ((bufferSize_ == 0) || (pixelMap->GetPixels() == nullptr)) {
347 WVLOG_E("data in pixel map is empty");
348 return false;
349 }
350
351 imgBuffer_ = static_cast<uint8_t *>(calloc(static_cast<size_t>(bufferSize_), sizeof(uint8_t)));
352 if (imgBuffer_ == nullptr) {
353 WVLOG_E("calloc imgbuffer failed");
354 return false;
355 }
356
357 if (memcpy_s(imgBuffer_, bufferSize_, pixelMap->GetPixels(), bufferSize_)) {
358 WVLOG_E("memcpy imgbuffer failed");
359 ClearImgBuffer();
360 return false;
361 }
362
363 int32_t width = pixelMap->GetWidth();
364 int32_t height = pixelMap->GetHeight();
365 pixelMap->GetImageInfo(imgInfo);
366 int32_t rowBytes = pixelMap->GetRowBytes();
367
368 imageData->SetColorType(ImageToClipboardColorType(imgInfo));
369 imageData->SetAlphaType(ImageToClipboardAlphaType(imgInfo));
370 imageData->SetData((uint32_t *)(imgBuffer_));
371 imageData->SetDataSize(static_cast<size_t>(bufferSize_));
372 imageData->SetWidth(width);
373 imageData->SetHeight(height);
374 imageData->SetRowBytes(static_cast<size_t>(rowBytes));
375 return true;
376 }
377
GetUri()378 std::shared_ptr<std::string> PasteDataRecordAdapterImpl::GetUri()
379 {
380 if (record_ == nullptr) {
381 WVLOG_E("record_ is null");
382 return nullptr;
383 }
384 auto entry = record_->GetEntry(UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::FILE_URI));
385 if (entry == nullptr) {
386 return nullptr;
387 }
388 auto uri = entry->ConvertToUri();
389 if (uri == nullptr) {
390 return nullptr;
391 }
392 return std::make_shared<std::string>(uri->ToString());
393 }
394
GetCustomData()395 std::shared_ptr<PasteCustomData> PasteDataRecordAdapterImpl::GetCustomData()
396 {
397 if (record_ == nullptr) {
398 WVLOG_E("record_ is null");
399 return nullptr;
400 }
401 auto customData = std::make_shared<PasteCustomData>();
402 if (customData == nullptr) {
403 WVLOG_E("customData create failed");
404 return nullptr;
405 }
406 for (auto type : { SPAN_STRING_TAG, CUSTOM_DATA_TAG, CUSTOM_DATA_TAG2 }) {
407 auto entry = record_->GetEntry(type);
408 if (!entry) {
409 continue;
410 }
411 auto data = entry->ConvertToCustomData();
412 if (!data) {
413 continue;
414 }
415 for (const auto& [key, value] : data->GetItemData()) {
416 customData->emplace(key, value);
417 }
418 }
419 // Compatibility adaptation with old versions of read customData
420 if (record_->GetCustomData()) {
421 for (const auto& [key, value] : record_->GetCustomData()->GetItemData()) {
422 customData->emplace(key, value);
423 }
424 }
425
426 return (customData->empty() ? nullptr : customData);
427 }
428
ClearImgBuffer()429 void PasteDataRecordAdapterImpl::ClearImgBuffer()
430 {
431 if (imgBuffer_) {
432 free(imgBuffer_);
433 imgBuffer_ = nullptr;
434 bufferSize_ = 0;
435 }
436 }
437
Clear()438 void PasteDataRecordAdapterImpl::Clear()
439 {
440 ClearImgBuffer();
441 }
442
GetRecord()443 std::shared_ptr<PasteDataRecord> PasteDataRecordAdapterImpl::GetRecord()
444 {
445 return record_;
446 }
447
PasteDataAdapterImpl()448 PasteDataAdapterImpl::PasteDataAdapterImpl()
449 : data_(std::make_shared<PasteData>()) {}
450
PasteDataAdapterImpl(std::shared_ptr<PasteData> data)451 PasteDataAdapterImpl::PasteDataAdapterImpl(
452 std::shared_ptr<PasteData> data) : data_(data) {}
453
AddHtmlRecord(const std::string & html)454 void PasteDataAdapterImpl::AddHtmlRecord(const std::string& html)
455 {
456 if (data_ != nullptr) {
457 data_->AddHtmlRecord(html);
458 }
459 }
460
AddTextRecord(const std::string & text)461 void PasteDataAdapterImpl::AddTextRecord(const std::string& text)
462 {
463 if (data_ != nullptr) {
464 data_->AddTextRecord(text);
465 }
466 }
467
GetMimeTypes()468 std::vector<std::string> PasteDataAdapterImpl::GetMimeTypes()
469 {
470 return (data_ != nullptr) ? data_->GetMimeTypes() :
471 std::vector<std::string>();
472 }
473
GetPrimaryHtml()474 std::shared_ptr<std::string> PasteDataAdapterImpl::GetPrimaryHtml()
475 {
476 return (data_ != nullptr) ? data_->GetPrimaryHtml() : nullptr;
477 }
478
GetPrimaryText()479 std::shared_ptr<std::string> PasteDataAdapterImpl::GetPrimaryText()
480 {
481 return (data_ != nullptr) ? data_->GetPrimaryText() : nullptr;
482 }
483
GetPrimaryMimeType()484 std::shared_ptr<std::string> PasteDataAdapterImpl::GetPrimaryMimeType()
485 {
486 return (data_ != nullptr) ? data_->GetPrimaryMimeType() : nullptr;
487 }
488
GetRecordAt(std::size_t index)489 std::shared_ptr<PasteDataRecordAdapter> PasteDataAdapterImpl::GetRecordAt(
490 std::size_t index)
491 {
492 if (data_ == nullptr || data_->GetRecordCount() <= index) {
493 return nullptr;
494 }
495 return std::make_shared<PasteDataRecordAdapterImpl>(data_->GetRecordAt(index));
496 }
497
GetRecordCount()498 std::size_t PasteDataAdapterImpl::GetRecordCount()
499 {
500 return (data_ != nullptr) ? data_->GetRecordCount() : 0;
501 }
502
AllRecords()503 PasteRecordVector PasteDataAdapterImpl::AllRecords()
504 {
505 if (data_ == nullptr) {
506 return PasteRecordVector();
507 }
508 PasteRecordVector result;
509 for (auto& record: data_->AllRecords()) {
510 result.push_back(std::make_shared<PasteDataRecordAdapterImpl>(record));
511 }
512 return result;
513 }
514
GetInstance()515 PasteBoardClientAdapterImpl& PasteBoardClientAdapterImpl::GetInstance()
516 {
517 static PasteBoardClientAdapterImpl instance;
518 return instance;
519 }
520
TransitionCopyOption(CopyOptionMode copyOption)521 MiscServices::ShareOption PasteBoardClientAdapterImpl::TransitionCopyOption(CopyOptionMode copyOption)
522 {
523 auto shareOption = MiscServices::ShareOption::CrossDevice;
524 switch (copyOption) {
525 case CopyOptionMode::IN_APP:
526 shareOption = MiscServices::ShareOption::InApp;
527 break;
528 case CopyOptionMode::LOCAL_DEVICE:
529 shareOption = MiscServices::ShareOption::LocalDevice;
530 break;
531 case CopyOptionMode::CROSS_DEVICE:
532 shareOption = MiscServices::ShareOption::CrossDevice;
533 break;
534 default:
535 break;
536 }
537 return shareOption;
538 }
539
ReportPasteboardErrorEvent(int32_t errorCode,int32_t recordSize,const std::string & dataType)540 void ReportPasteboardErrorEvent(int32_t errorCode, int32_t recordSize, const std::string &dataType)
541 {
542 OhosAdapterHelper::GetInstance().GetHiSysEventAdapterInstance().Write(PASTE_BOARD_ERROR,
543 HiSysEventAdapter::EventType::FAULT, { ERROR_CODE, std::to_string(errorCode),
544 RECORD_SIZE, std::to_string(recordSize), DATA_TYPE, dataType });
545 }
546
GetPasteMimeTypeExtention(const PasteRecordVector & data)547 std::string GetPasteMimeTypeExtention(const PasteRecordVector& data)
548 {
549 if (data.empty()) {
550 return MIMETYPE_NULL;
551 }
552 bool isHybrid = false;
553 std::string primaryMimeType = data.front()->GetMimeType();
554 for (auto &item : data) {
555 if (primaryMimeType != item->GetMimeType()) {
556 isHybrid = true;
557 break;
558 }
559 }
560 if (isHybrid) {
561 return MIMETYPE_HYBRID;
562 }
563 return primaryMimeType;
564 }
565
GetPasteData(PasteRecordVector & data)566 bool PasteBoardClientAdapterImpl::GetPasteData(PasteRecordVector& data)
567 {
568 PasteData pData;
569 if (!PasteboardClient::GetInstance()->HasPasteData() ||
570 PasteboardClient::GetInstance()->GetPasteData(pData) != static_cast<int32_t>(PasteboardError::E_OK)) {
571 WVLOG_E("no data to paste or get data from clipboard failed");
572 ReportPasteboardErrorEvent(PasteboardClient::GetInstance()->GetPasteData(pData),
573 pData.AllRecords().size(), GetPasteMimeTypeExtention(data));
574 isLocalPaste_ = false;
575 tokenId_ = 0;
576 return false;
577 }
578 for (auto& record: pData.AllRecords()) {
579 data.push_back(std::make_shared<PasteDataRecordAdapterImpl>(record));
580 }
581 tokenId_ = pData.GetTokenId();
582 isLocalPaste_ = pData.IsLocalPaste();
583 return true;
584 }
585
SetPasteData(const PasteRecordVector & data,CopyOptionMode copyOption)586 void PasteBoardClientAdapterImpl::SetPasteData(const PasteRecordVector& data, CopyOptionMode copyOption)
587 {
588 if (copyOption == CopyOptionMode::NONE) {
589 WVLOG_E("SetPasteData failed, copy option mode is 'NONE'");
590 return;
591 }
592 std::vector<std::shared_ptr<PasteDataRecord>> recordList;
593 for (auto& record: data) {
594 PasteDataRecordAdapterImpl* rawRecord =
595 reinterpret_cast<PasteDataRecordAdapterImpl*>(record.get());
596 if (rawRecord == nullptr) {
597 continue;
598 }
599 recordList.push_back(rawRecord->GetRecord());
600 }
601 PasteData pData(recordList);
602 auto shareOption = TransitionCopyOption(copyOption);
603 pData.SetShareOption(shareOption);
604 int32_t ret = PasteboardClient::GetInstance()->SetPasteData(pData);
605 if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
606 WVLOG_E("set paste data to clipboard failed");
607 ReportPasteboardErrorEvent(ret, pData.AllRecords().size(), GetPasteMimeTypeExtention(data));
608 }
609 }
610
HasPasteData()611 bool PasteBoardClientAdapterImpl::HasPasteData()
612 {
613 return PasteboardClient::GetInstance()->HasPasteData();
614 }
615
Clear()616 void PasteBoardClientAdapterImpl::Clear()
617 {
618 PasteRecordVector recordVector;
619 if (!GetPasteData(recordVector)) {
620 WVLOG_E("get paste data failed while clear");
621 PasteboardClient::GetInstance()->Clear();
622 return;
623 }
624 for (auto& record: recordVector) {
625 PasteDataRecordAdapterImpl* rawRecord =
626 reinterpret_cast<PasteDataRecordAdapterImpl*>(record.get());
627 if (rawRecord == nullptr) {
628 continue;
629 }
630 rawRecord->Clear();
631 }
632 PasteboardClient::GetInstance()->Clear();
633 }
634
OpenRemoteUri(const std::string & path)635 int32_t PasteBoardClientAdapterImpl::OpenRemoteUri(const std::string& path)
636 {
637 return RemoteUri::OpenRemoteUri(path);
638 }
639
IsLocalPaste()640 bool PasteBoardClientAdapterImpl::IsLocalPaste()
641 {
642 return isLocalPaste_;
643 }
644
GetTokenId()645 uint32_t PasteBoardClientAdapterImpl::GetTokenId()
646 {
647 return tokenId_;
648 }
649
AddPasteboardChangedObserver(std::shared_ptr<PasteboardObserverAdapter> callback)650 int32_t PasteBoardClientAdapterImpl::AddPasteboardChangedObserver(
651 std::shared_ptr<PasteboardObserverAdapter> callback)
652 {
653 static int32_t count = 0;
654 int32_t id = -1;
655 if (callback) {
656 sptr<PasteboardObserver> observer;
657 {
658 std::lock_guard<std::mutex> lock(mutex_);
659 observer = new (std::nothrow) PasteboardObserverAdapterImpl(callback);
660 if (!observer) {
661 return -1;
662 }
663
664 id = count++;
665 if (count < 0) {
666 count = 0;
667 }
668 reg_.emplace(std::make_pair(id, observer));
669 }
670 PasteboardClient::GetInstance()->AddPasteboardChangedObserver(observer);
671 }
672 return id;
673 }
674
RemovePasteboardChangedObserver(int32_t callbackId)675 void PasteBoardClientAdapterImpl::RemovePasteboardChangedObserver(
676 int32_t callbackId)
677 {
678 sptr<PasteboardObserver> observer;
679 {
680 std::lock_guard<std::mutex> lock(mutex_);
681 ObserverMap::iterator iter = reg_.find(callbackId);
682 if (iter == reg_.end()) {
683 return;
684 }
685 observer = iter->second;
686 reg_.erase(iter);
687 }
688 PasteboardClient::GetInstance()->RemovePasteboardChangedObserver(observer);
689 }
690 } // namespace OHOS::NWeb
691