• 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 "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