• 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 "media_errors.h"
22 #include "nweb_log.h"
23 #include "remote_uri.h"
24 
25 using namespace OHOS::MiscServices;
26 using namespace OHOS::DistributedFS::ModuleRemoteUri;
27 
28 namespace OHOS::NWeb {
PasteboardObserverAdapterImpl(std::shared_ptr<PasteboardObserverAdapter> observer)29 PasteboardObserverAdapterImpl::PasteboardObserverAdapterImpl(
30     std::shared_ptr<PasteboardObserverAdapter> observer)
31     : observer_(observer) {}
32 
OnPasteboardChanged()33 void PasteboardObserverAdapterImpl::OnPasteboardChanged()
34 {
35     if (observer_) {
36         observer_->OnPasteboardChanged();
37     }
38 }
39 
PasteDataRecordAdapterImpl(std::shared_ptr<PasteDataRecord> record)40 PasteDataRecordAdapterImpl::PasteDataRecordAdapterImpl(
41     std::shared_ptr<PasteDataRecord> record)
42     : record_(record) {}
43 
PasteDataRecordAdapterImpl(const std::string & mimeType)44 PasteDataRecordAdapterImpl::PasteDataRecordAdapterImpl(
45     const std::string& mimeType)
46 {
47     builder_ = std::make_shared<PasteDataRecord::Builder>(mimeType);
48     if (builder_) {
49         record_ = builder_->Build();
50     }
51 }
52 
PasteDataRecordAdapterImpl(const std::string & mimeType,std::shared_ptr<std::string> htmlText,std::shared_ptr<std::string> plainText)53 PasteDataRecordAdapterImpl::PasteDataRecordAdapterImpl(
54     const std::string& mimeType,
55     std::shared_ptr<std::string> htmlText,
56     std::shared_ptr<std::string> plainText)
57 {
58     record_ = std::make_shared<PasteDataRecord>(mimeType,
59                                                 htmlText,
60                                                 nullptr,
61                                                 plainText,
62                                                 nullptr);
63 }
64 
NewRecord(const std::string & mimeType)65 std::shared_ptr<PasteDataRecordAdapter> PasteDataRecordAdapter::NewRecord(
66     const std::string& mimeType)
67 {
68     return std::make_shared<PasteDataRecordAdapterImpl>(mimeType);
69 }
70 
NewRecord(const std::string & mimeType,std::shared_ptr<std::string> htmlText,std::shared_ptr<std::string> plainText)71 std::shared_ptr<PasteDataRecordAdapter> PasteDataRecordAdapter::NewRecord(
72     const std::string& mimeType,
73     std::shared_ptr<std::string> htmlText,
74     std::shared_ptr<std::string> plainText)
75 {
76     return std::make_shared<PasteDataRecordAdapterImpl>(mimeType,
77                                                         htmlText,
78                                                         plainText);
79 }
80 
SetHtmlText(std::shared_ptr<std::string> htmlText)81 bool PasteDataRecordAdapterImpl::SetHtmlText(std::shared_ptr<std::string> htmlText)
82 {
83     if (builder_) {
84         record_ = builder_->SetHtmlText(htmlText).Build();
85         return true;
86     }
87     WVLOG_E("record_ is null");
88     return false;
89 }
90 
SetPlainText(std::shared_ptr<std::string> plainText)91 bool PasteDataRecordAdapterImpl::SetPlainText(std::shared_ptr<std::string> plainText)
92 {
93     if (builder_) {
94         record_ = builder_->SetPlainText(plainText).Build();
95         return true;
96     }
97     WVLOG_E("record_ is null");
98     return false;
99 }
100 
SetUri(const std::string & uriString)101 bool PasteDataRecordAdapterImpl::SetUri(const std::string& uriString)
102 {
103     if (uriString.empty() || !builder_) {
104         WVLOG_E("record_ or uriString is null");
105         return false;
106     }
107     std::shared_ptr<OHOS::Uri> uri = std::make_shared<OHOS::Uri>(uriString);
108     record_ = builder_->SetUri(uri).Build();
109     return true;
110 }
111 
SetCustomData(PasteCustomData & data)112 bool PasteDataRecordAdapterImpl::SetCustomData(PasteCustomData& data)
113 {
114     if (data.empty() || !builder_) {
115         WVLOG_E("custom data is empty or builder_ is null");
116         return false;
117     }
118     std::shared_ptr<MineCustomData> customData =
119         std::make_shared<MineCustomData>();
120     for (PasteCustomData::iterator iter = data.begin(); iter != data.end(); ++iter) {
121         customData->AddItemData(iter->first, iter->second);
122     }
123     record_ = builder_->SetCustomData(customData).Build();
124     return true;
125 }
126 
ImageToClipboardAlphaType(const Media::ImageInfo & imgInfo)127 ClipBoardImageAlphaType PasteDataRecordAdapterImpl::ImageToClipboardAlphaType
128     (const Media::ImageInfo &imgInfo)
129 {
130     switch (imgInfo.alphaType) {
131         case Media::AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN :
132             return ClipBoardImageAlphaType::ALPHA_TYPE_UNKNOWN;
133         case Media::AlphaType::IMAGE_ALPHA_TYPE_OPAQUE :
134             return ClipBoardImageAlphaType::ALPHA_TYPE_OPAQUE;
135         case Media::AlphaType::IMAGE_ALPHA_TYPE_PREMUL :
136             return ClipBoardImageAlphaType::ALPHA_TYPE_PREMULTIPLIED;
137         default :
138             return ClipBoardImageAlphaType::ALPHA_TYPE_UNKNOWN;
139     }
140 }
141 
ImageToClipboardColorType(const Media::ImageInfo & imgInfo)142 ClipBoardImageColorType PasteDataRecordAdapterImpl::ImageToClipboardColorType
143     (const Media::ImageInfo &imgInfo)
144 {
145     switch (imgInfo.pixelFormat) {
146         case Media::PixelFormat::RGBA_8888 :
147             return ClipBoardImageColorType::COLOR_TYPE_RGBA_8888;
148         case Media::PixelFormat::BGRA_8888 :
149             return ClipBoardImageColorType::COLOR_TYPE_BGRA_8888;
150         default :
151             return ClipBoardImageColorType::COLOR_TYPE_UNKNOWN;
152     }
153 }
154 
ClipboardToImageAlphaType(ClipBoardImageAlphaType alphaType)155 Media::AlphaType PasteDataRecordAdapterImpl::ClipboardToImageAlphaType
156     (ClipBoardImageAlphaType alphaType)
157 {
158     switch (alphaType) {
159         case ClipBoardImageAlphaType::ALPHA_TYPE_UNKNOWN :
160             return Media::AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN;
161         case ClipBoardImageAlphaType::ALPHA_TYPE_OPAQUE :
162             return Media::AlphaType::IMAGE_ALPHA_TYPE_OPAQUE;
163         case ClipBoardImageAlphaType::ALPHA_TYPE_PREMULTIPLIED :
164             return Media::AlphaType::IMAGE_ALPHA_TYPE_PREMUL;
165         default :
166             return Media::AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN;
167     }
168 }
169 
ClipboardToImageColorType(ClipBoardImageColorType colorType)170 Media::PixelFormat PasteDataRecordAdapterImpl::ClipboardToImageColorType
171     (ClipBoardImageColorType colorType)
172 {
173     switch (colorType) {
174         case ClipBoardImageColorType::COLOR_TYPE_RGBA_8888 :
175             return Media::PixelFormat::RGBA_8888;
176         case ClipBoardImageColorType::COLOR_TYPE_BGRA_8888 :
177             return Media::PixelFormat::BGRA_8888;
178         default :
179             return Media::PixelFormat::UNKNOWN;
180     }
181 }
182 
SetImgData(std::shared_ptr<ClipBoardImageData> imageData)183 bool PasteDataRecordAdapterImpl::SetImgData(std::shared_ptr<ClipBoardImageData> imageData)
184 {
185     if (imageData == nullptr) {
186         WVLOG_E("imageData is null");
187         return false;
188     }
189     Media::InitializationOptions opt;
190     opt.size.width = imageData->width;
191     opt.size.height = imageData->height;
192     opt.pixelFormat = ClipboardToImageColorType(imageData->colorType);
193     opt.alphaType = ClipboardToImageAlphaType(imageData->alphaType);
194     opt.editable = true;
195     std::unique_ptr<Media::PixelMap> pixelMap = Media::PixelMap::Create(opt);
196     if (pixelMap == nullptr) {
197         WVLOG_E("create pixel map failed");
198         return false;
199     }
200     uint64_t stride = static_cast<uint64_t>(imageData->width) << 2;
201     uint64_t bufferSize = stride * static_cast<uint64_t>(imageData->height);
202     uint32_t ret = pixelMap->WritePixels(reinterpret_cast<const uint8_t *>(imageData->data), bufferSize);
203     if (ret != Media::SUCCESS) {
204         WVLOG_E("write pixel map failed %{public}u", ret);
205         return false;
206     }
207 
208     std::shared_ptr<Media::PixelMap> pixelMapIn = move(pixelMap);
209 
210     if (!builder_) {
211         WVLOG_E("record_ is null");
212         return false;
213     }
214     record_ = builder_->SetPixelMap(pixelMapIn).Build();
215     return true;
216 }
217 
GetMimeType()218 std::string PasteDataRecordAdapterImpl::GetMimeType()
219 {
220     return (record_ != nullptr) ? record_->GetMimeType() : "";
221 }
222 
GetHtmlText()223 std::shared_ptr<std::string> PasteDataRecordAdapterImpl::GetHtmlText()
224 {
225     return (record_ != nullptr) ? record_->GetHtmlText() : nullptr;
226 }
227 
GetPlainText()228 std::shared_ptr<std::string> PasteDataRecordAdapterImpl::GetPlainText()
229 {
230     return (record_ != nullptr) ? record_->GetPlainText() : nullptr;
231 }
232 
GetImgData(ClipBoardImageData & imageData)233 bool PasteDataRecordAdapterImpl::GetImgData(ClipBoardImageData &imageData)
234 {
235     if (record_ == nullptr) {
236         WVLOG_E("record_ is null");
237         return false;
238     }
239     std::shared_ptr<Media::PixelMap> pixelMap = record_->GetPixelMap();
240     if (pixelMap == nullptr) {
241         WVLOG_E("pixelMap is null");
242         return false;
243     }
244 
245     Media::ImageInfo imgInfo;
246     ClearImgBuffer();
247     bufferSize_ = pixelMap->GetCapacity();
248     if ((bufferSize_ == 0) || (pixelMap->GetPixels() == nullptr)) {
249         WVLOG_E("data in pixel map is empty");
250         return false;
251     }
252 
253     imgBuffer_ = static_cast<uint8_t *>(calloc(static_cast<size_t>(bufferSize_), sizeof(uint8_t)));
254     if (imgBuffer_ == nullptr) {
255         WVLOG_E("calloc imgbuffer failed");
256         return false;
257     }
258 
259     if (memcpy_s(imgBuffer_, bufferSize_, pixelMap->GetPixels(), bufferSize_)) {
260         WVLOG_E("memcpy imgbuffer failed");
261         ClearImgBuffer();
262         return false;
263     }
264 
265     int32_t width = pixelMap->GetWidth();
266     int32_t height = pixelMap->GetHeight();
267     pixelMap->GetImageInfo(imgInfo);
268     int32_t rowBytes = pixelMap->GetRowBytes();
269 
270     imageData.colorType = ImageToClipboardColorType(imgInfo);
271     imageData.alphaType = ImageToClipboardAlphaType(imgInfo);
272     imageData.data = (uint32_t *)(imgBuffer_);
273     imageData.dataSize = static_cast<size_t>(bufferSize_);
274     imageData.width = width;
275     imageData.height = height;
276     imageData.rowBytes = static_cast<size_t>(rowBytes);
277     return true;
278 }
279 
GetUri()280 std::shared_ptr<std::string> PasteDataRecordAdapterImpl::GetUri()
281 {
282     if (record_ == nullptr) {
283         return nullptr;
284     }
285     auto uri = record_->GetUri();
286     if (uri == nullptr) {
287         return nullptr;
288     }
289     return std::make_shared<std::string>(uri->ToString());
290 }
291 
GetCustomData()292 std::shared_ptr<PasteCustomData> PasteDataRecordAdapterImpl::GetCustomData()
293 {
294     if (record_ == nullptr) {
295         return nullptr;
296     }
297     auto customData = record_->GetCustomData();
298     if (customData == nullptr) {
299         return nullptr;
300     }
301     return std::make_shared<PasteCustomData>(customData->GetItemData());
302 }
303 
ClearImgBuffer()304 void PasteDataRecordAdapterImpl::ClearImgBuffer()
305 {
306     if (imgBuffer_) {
307         free(imgBuffer_);
308         imgBuffer_ = nullptr;
309         bufferSize_ = 0;
310     }
311 }
312 
Clear()313 void PasteDataRecordAdapterImpl::Clear()
314 {
315     ClearImgBuffer();
316 }
317 
GetRecord()318 std::shared_ptr<PasteDataRecord> PasteDataRecordAdapterImpl::GetRecord()
319 {
320     return record_;
321 }
322 
PasteDataAdapterImpl()323 PasteDataAdapterImpl::PasteDataAdapterImpl()
324     : data_(std::make_shared<PasteData>()) {}
325 
PasteDataAdapterImpl(std::shared_ptr<PasteData> data)326 PasteDataAdapterImpl::PasteDataAdapterImpl(
327     std::shared_ptr<PasteData> data) : data_(data) {}
328 
AddHtmlRecord(const std::string & html)329 void PasteDataAdapterImpl::AddHtmlRecord(const std::string& html)
330 {
331     if (data_ != nullptr) {
332         data_->AddHtmlRecord(html);
333     }
334 }
335 
AddTextRecord(const std::string & text)336 void PasteDataAdapterImpl::AddTextRecord(const std::string& text)
337 {
338     if (data_ != nullptr) {
339         data_->AddTextRecord(text);
340     }
341 }
342 
GetMimeTypes()343 std::vector<std::string> PasteDataAdapterImpl::GetMimeTypes()
344 {
345     return (data_ != nullptr) ? data_->GetMimeTypes() :
346                                 std::vector<std::string>();
347 }
348 
GetPrimaryHtml()349 std::shared_ptr<std::string> PasteDataAdapterImpl::GetPrimaryHtml()
350 {
351     return (data_ != nullptr) ? data_->GetPrimaryHtml() : nullptr;
352 }
353 
GetPrimaryText()354 std::shared_ptr<std::string> PasteDataAdapterImpl::GetPrimaryText()
355 {
356     return (data_ != nullptr) ? data_->GetPrimaryText() : nullptr;
357 }
358 
GetPrimaryMimeType()359 std::shared_ptr<std::string> PasteDataAdapterImpl::GetPrimaryMimeType()
360 {
361     return (data_ != nullptr) ? data_->GetPrimaryMimeType() : nullptr;
362 }
363 
GetRecordAt(std::size_t index)364 std::shared_ptr<PasteDataRecordAdapter> PasteDataAdapterImpl::GetRecordAt(
365     std::size_t index)
366 {
367     if (data_ == nullptr || data_->GetRecordCount() <= index) {
368         return nullptr;
369     }
370     return std::make_shared<PasteDataRecordAdapterImpl>(data_->GetRecordAt(index));
371 }
372 
GetRecordCount()373 std::size_t PasteDataAdapterImpl::GetRecordCount()
374 {
375     return (data_ != nullptr) ? data_->GetRecordCount() : 0;
376 }
377 
AllRecords() const378 PasteRecordList PasteDataAdapterImpl::AllRecords() const
379 {
380     if (data_ == nullptr) {
381         return PasteRecordList();
382     }
383     PasteRecordList result;
384     for (auto& record: data_->AllRecords()) {
385         result.push_back(std::make_shared<PasteDataRecordAdapterImpl>(record));
386     }
387     return result;
388 }
389 
GetInstance()390 PasteBoardClientAdapterImpl& PasteBoardClientAdapterImpl::GetInstance()
391 {
392     static PasteBoardClientAdapterImpl instance;
393     return instance;
394 }
395 
GetPasteData(PasteRecordList & data)396 bool PasteBoardClientAdapterImpl::GetPasteData(PasteRecordList& data)
397 {
398     PasteData pData;
399     if (!PasteboardClient::GetInstance()->HasPasteData() ||
400         !PasteboardClient::GetInstance()->GetPasteData(pData)) {
401         isLocalPaste_ = false;
402         tokenId_ = 0;
403         return false;
404     }
405     for (auto& record: pData.AllRecords()) {
406         data.push_back(std::make_shared<PasteDataRecordAdapterImpl>(record));
407     }
408     tokenId_ = pData.GetTokenId();
409     isLocalPaste_ = pData.IsLocalPaste();
410     return true;
411 }
412 
SetPasteData(const PasteRecordList & data)413 void PasteBoardClientAdapterImpl::SetPasteData(const PasteRecordList& data)
414 {
415     std::vector<std::shared_ptr<PasteDataRecord>> recordList;
416     for (auto& record: data) {
417         PasteDataRecordAdapterImpl* rawRecord =
418             reinterpret_cast<PasteDataRecordAdapterImpl*>(record.get());
419         if (rawRecord == nullptr) {
420             continue;
421         }
422         recordList.push_back(rawRecord->GetRecord());
423     }
424     PasteData pData(recordList);
425     PasteboardClient::GetInstance()->SetPasteData(pData);
426 }
427 
HasPasteData()428 bool PasteBoardClientAdapterImpl::HasPasteData()
429 {
430     return PasteboardClient::GetInstance()->HasPasteData();
431 }
432 
Clear()433 void PasteBoardClientAdapterImpl::Clear()
434 {
435     PasteRecordList recordList;
436     if (!GetPasteData(recordList)) {
437         WVLOG_E("get paste data failed while clear");
438         PasteboardClient::GetInstance()->Clear();
439         return;
440     }
441     for (auto& record: recordList) {
442         PasteDataRecordAdapterImpl* rawRecord =
443             reinterpret_cast<PasteDataRecordAdapterImpl*>(record.get());
444         if (rawRecord == nullptr) {
445             continue;
446         }
447         rawRecord->Clear();
448     }
449     PasteboardClient::GetInstance()->Clear();
450 }
451 
OpenRemoteUri(const std::string & path)452 int32_t PasteBoardClientAdapterImpl::OpenRemoteUri(const std::string& path)
453 {
454     return RemoteUri::OpenRemoteUri(path);
455 }
456 
IsLocalPaste() const457 bool PasteBoardClientAdapterImpl::IsLocalPaste() const
458 {
459     return isLocalPaste_;
460 }
461 
GetTokenId() const462 uint32_t PasteBoardClientAdapterImpl::GetTokenId() const
463 {
464     return tokenId_;
465 }
466 
AddPasteboardChangedObserver(std::shared_ptr<PasteboardObserverAdapter> callback)467 void PasteBoardClientAdapterImpl::AddPasteboardChangedObserver(
468     std::shared_ptr<PasteboardObserverAdapter> callback)
469 {
470     if (callback) {
471         sptr<PasteboardObserver> observer;
472         {
473             std::lock_guard<std::mutex> lock(mutex_);
474             ObserverMap::iterator iter = reg_.find(callback.get());
475             if (iter != reg_.end()) {
476                 return;
477             }
478             observer = new (std::nothrow) PasteboardObserverAdapterImpl(callback);
479             if (!observer) {
480                 return;
481             }
482             reg_.emplace(std::make_pair(callback.get(), observer));
483         }
484         PasteboardClient::GetInstance()->AddPasteboardChangedObserver(observer);
485     }
486 }
487 
RemovePasteboardChangedObserver(std::shared_ptr<PasteboardObserverAdapter> callback)488 void PasteBoardClientAdapterImpl::RemovePasteboardChangedObserver(
489     std::shared_ptr<PasteboardObserverAdapter> callback)
490 {
491     if (callback) {
492         sptr<PasteboardObserver> observer;
493         {
494             std::lock_guard<std::mutex> lock(mutex_);
495             ObserverMap::iterator iter = reg_.find(callback.get());
496             if (iter == reg_.end()) {
497                 return;
498             }
499             observer = iter->second;
500             reg_.erase(iter);
501         }
502         PasteboardClient::GetInstance()->RemovePasteboardChangedObserver(observer);
503     }
504 }
505 } // namespace OHOS::NWeb
506