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