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