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