• 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 "adapter/ohos/capability/clipboard/clipboard_impl.h"
17 
18 #include "adapter/ohos/osal/pixel_map_ohos.h"
19 #include "base/utils/utils.h"
20 
21 namespace OHOS::Ace {
22 #ifndef SYSTEM_CLIPBOARD_SUPPORTED
23 namespace {
24 std::string g_clipboard;
25 RefPtr<PixelMap> g_pixmap;
26 } // namespace
27 #endif
28 
29 #ifdef SYSTEM_CLIPBOARD_SUPPORTED
TransitionCopyOption(CopyOptions copyOption)30 MiscServices::ShareOption TransitionCopyOption(CopyOptions copyOption)
31 {
32     auto shareOption = MiscServices::ShareOption::InApp;
33     switch (copyOption) {
34         case CopyOptions::InApp:
35             shareOption = MiscServices::ShareOption::InApp;
36             break;
37         case CopyOptions::Local:
38             shareOption = MiscServices::ShareOption::LocalDevice;
39             break;
40         case CopyOptions::Distributed:
41             shareOption = MiscServices::ShareOption::CrossDevice;
42             break;
43         default:
44             break;
45     }
46     return shareOption;
47 }
48 #endif
49 
HasData(const std::function<void (bool hasData)> & callback)50 void ClipboardImpl::HasData(const std::function<void(bool hasData)>& callback)
51 {
52 #ifdef SYSTEM_CLIPBOARD_SUPPORTED
53     bool hasData = false;
54     CHECK_NULL_VOID(taskExecutor_);
55     taskExecutor_->PostSyncTask(
56         [&hasData]() { hasData = OHOS::MiscServices::PasteboardClient::GetInstance()->HasPasteData(); },
57         TaskExecutor::TaskType::PLATFORM);
58     callback(hasData);
59 #endif
60 }
61 
SetData(const std::string & data,CopyOptions copyOption,bool isDragData)62 void ClipboardImpl::SetData(const std::string& data, CopyOptions copyOption, bool isDragData)
63 {
64     CHECK_NULL_VOID(taskExecutor_);
65 #ifdef SYSTEM_CLIPBOARD_SUPPORTED
66     auto shareOption = TransitionCopyOption(copyOption);
67     taskExecutor_->PostTask(
68         [data, shareOption, isDragData]() {
69             auto pasteData = OHOS::MiscServices::PasteboardClient::GetInstance()->CreatePlainTextData(data);
70             CHECK_NULL_VOID(pasteData);
71             pasteData->SetShareOption(shareOption);
72             pasteData->SetDraggedDataFlag(isDragData);
73             OHOS::MiscServices::PasteboardClient::GetInstance()->SetPasteData(*pasteData);
74         },
75         TaskExecutor::TaskType::PLATFORM);
76 #else
77     taskExecutor_->PostTask([data]() { g_clipboard = data; }, TaskExecutor::TaskType::UI);
78 #endif
79 }
80 
SetPixelMapData(const RefPtr<PixelMap> & pixmap,CopyOptions copyOption)81 void ClipboardImpl::SetPixelMapData(const RefPtr<PixelMap>& pixmap, CopyOptions copyOption)
82 {
83     CHECK_NULL_VOID(taskExecutor_);
84 #ifdef SYSTEM_CLIPBOARD_SUPPORTED
85     auto shareOption = TransitionCopyOption(copyOption);
86     taskExecutor_->PostTask(
87         [pixmap, shareOption]() {
88             CHECK_NULL_VOID(pixmap);
89             auto pixmapOhos = AceType::DynamicCast<PixelMapOhos>(pixmap);
90             CHECK_NULL_VOID(pixmapOhos);
91             auto pasteData = OHOS::MiscServices::PasteboardClient::GetInstance()->CreatePixelMapData(
92                 pixmapOhos->GetPixelMapSharedPtr());
93             CHECK_NULL_VOID(pasteData);
94             pasteData->SetShareOption(shareOption);
95             LOGI("Set pixmap to system clipboard");
96             OHOS::MiscServices::PasteboardClient::GetInstance()->SetPasteData(*pasteData);
97         },
98         TaskExecutor::TaskType::PLATFORM);
99 #else
100     taskExecutor_->PostTask([pixmap]() { g_pixmap = pixmap; }, TaskExecutor::TaskType::UI);
101 #endif
102 }
103 
GetData(const std::function<void (const std::string &)> & callback,bool syncMode)104 void ClipboardImpl::GetData(const std::function<void(const std::string&)>& callback, bool syncMode)
105 {
106 #ifdef SYSTEM_CLIPBOARD_SUPPORTED
107     if (!taskExecutor_ || !callback) {
108         return;
109     }
110 
111     if (syncMode) {
112         GetDataSync(callback);
113     } else {
114         GetDataAsync(callback);
115     }
116 #else
117     if (syncMode) {
118         callback(g_clipboard);
119         return;
120     }
121     CHECK_NULL_VOID(taskExecutor_);
122     taskExecutor_->PostTask(
123         [callback, taskExecutor = WeakClaim(RawPtr(taskExecutor_)), textData = g_clipboard]() {
124             callback(textData);
125         },
126         TaskExecutor::TaskType::UI);
127 #endif
128 }
129 
GetPixelMapData(const std::function<void (const RefPtr<PixelMap> &)> & callback,bool syncMode)130 void ClipboardImpl::GetPixelMapData(const std::function<void(const RefPtr<PixelMap>&)>& callback, bool syncMode)
131 {
132     if (!taskExecutor_ || !callback) {
133         return;
134     }
135 #ifdef SYSTEM_CLIPBOARD_SUPPORTED
136     if (syncMode) {
137         GetPixelMapDataSync(callback);
138     } else {
139         GetPixelMapDataAsync(callback);
140     }
141 #else
142     if (syncMode) {
143         callback(g_pixmap);
144     } else {
145         taskExecutor_->PostTask([callback, taskExecutor = WeakClaim(RawPtr(taskExecutor_)),
146                                     imageData = g_pixmap]() { callback(imageData); },
147             TaskExecutor::TaskType::UI);
148     }
149 #endif
150 }
151 
CreatePasteDataMix()152 RefPtr<PasteDataMix> ClipboardImpl::CreatePasteDataMix()
153 {
154     return AceType::MakeRefPtr<PasteDataImpl>();
155 }
156 
AddPixelMapRecord(const RefPtr<PasteDataMix> & pasteData,const RefPtr<PixelMap> & pixmap)157 void ClipboardImpl::AddPixelMapRecord(const RefPtr<PasteDataMix>& pasteData, const RefPtr<PixelMap>& pixmap)
158 {
159 #ifdef SYSTEM_CLIPBOARD_SUPPORTED
160     CHECK_NULL_VOID(taskExecutor_);
161     auto peData = AceType::DynamicCast<PasteDataImpl>(pasteData);
162     CHECK_NULL_VOID(peData);
163     auto pixmapOhos = AceType::DynamicCast<PixelMapOhos>(pixmap);
164     CHECK_NULL_VOID(pixmapOhos);
165     LOGI("add pixelMap record to pasteData");
166     peData->GetPasteDataData()->AddPixelMapRecord(pixmapOhos->GetPixelMapSharedPtr());
167 #endif
168 }
169 
AddImageRecord(const RefPtr<PasteDataMix> & pasteData,const std::string & uri)170 void ClipboardImpl::AddImageRecord(const RefPtr<PasteDataMix>& pasteData, const std::string& uri)
171 {
172 #ifdef SYSTEM_CLIPBOARD_SUPPORTED
173     CHECK_NULL_VOID(taskExecutor_);
174     auto peData = AceType::DynamicCast<PasteDataImpl>(pasteData);
175     CHECK_NULL_VOID(peData);
176     LOGI("add url record to pasteData, url:  %{public}s", uri.c_str());
177     peData->GetPasteDataData()->AddUriRecord(OHOS::Uri(uri));
178 #endif
179 }
180 
AddTextRecord(const RefPtr<PasteDataMix> & pasteData,const std::string & selectedStr)181 void ClipboardImpl::AddTextRecord(const RefPtr<PasteDataMix>& pasteData, const std::string& selectedStr)
182 {
183 #ifdef SYSTEM_CLIPBOARD_SUPPORTED
184     CHECK_NULL_VOID(taskExecutor_);
185     auto peData = AceType::DynamicCast<PasteDataImpl>(pasteData);
186     CHECK_NULL_VOID(peData);
187     LOGI("add text record to pasteData, text:  %{public}s", selectedStr.c_str());
188     peData->GetPasteDataData()->AddTextRecord(selectedStr);
189 #endif
190 }
191 
SetData(const RefPtr<PasteDataMix> & pasteData,CopyOptions copyOption)192 void ClipboardImpl::SetData(const RefPtr<PasteDataMix>& pasteData, CopyOptions copyOption)
193 {
194 #ifdef SYSTEM_CLIPBOARD_SUPPORTED
195     auto shareOption = TransitionCopyOption(copyOption);
196     auto peData = AceType::DynamicCast<PasteDataImpl>(pasteData);
197     CHECK_NULL_VOID(peData);
198     taskExecutor_->PostTask(
199         [peData, shareOption]() {
200             auto pasteData = peData->GetPasteDataData();
201             pasteData->SetShareOption(shareOption);
202             LOGI("add pasteData to clipboard, shareOption:  %{public}d", shareOption);
203             OHOS::MiscServices::PasteboardClient::GetInstance()->SetPasteData(*pasteData);
204         },
205         TaskExecutor::TaskType::PLATFORM);
206 #endif
207 }
208 
GetData(const std::function<void (const std::string &,bool isLastRecord)> & textCallback,const std::function<void (const RefPtr<PixelMap> &,bool isLastRecord)> & pixelMapCallback,const std::function<void (const std::string &,bool isLastRecord)> & urlCallback,bool syncMode)209 void ClipboardImpl::GetData(const std::function<void(const std::string&, bool isLastRecord)>& textCallback,
210     const std::function<void(const RefPtr<PixelMap>&, bool isLastRecord)>& pixelMapCallback,
211     const std::function<void(const std::string&, bool isLastRecord)>& urlCallback, bool syncMode)
212 {
213 #ifdef SYSTEM_CLIPBOARD_SUPPORTED
214     if (!taskExecutor_ || !textCallback || !pixelMapCallback || !urlCallback) {
215         return;
216     }
217 
218     if (syncMode) {
219         GetDataSync(textCallback, pixelMapCallback, urlCallback);
220     } else {
221         GetDataAsync(textCallback, pixelMapCallback, urlCallback);
222     }
223 #endif
224 }
225 
226 #ifdef SYSTEM_CLIPBOARD_SUPPORTED
GetPasteDataData()227 std::shared_ptr<MiscServices::PasteData> PasteDataImpl::GetPasteDataData()
228 {
229     if (pasteData_ == nullptr) {
230         pasteData_ = std::make_shared<MiscServices::PasteData>();
231     }
232     return pasteData_;
233 }
SetUnifiedData(std::shared_ptr<MiscServices::PasteData> pasteData)234 void PasteDataImpl::SetUnifiedData(std::shared_ptr<MiscServices::PasteData> pasteData)
235 {
236     pasteData_ = pasteData;
237 }
238 
GetDataSync(const std::function<void (const std::string &)> & callback)239 void ClipboardImpl::GetDataSync(const std::function<void(const std::string&)>& callback)
240 {
241     std::string result;
242     taskExecutor_->PostSyncTask(
243         [&result]() {
244             auto has = OHOS::MiscServices::PasteboardClient::GetInstance()->HasPasteData();
245             CHECK_NULL_VOID(has);
246             OHOS::MiscServices::PasteData pasteData;
247             auto ok = OHOS::MiscServices::PasteboardClient::GetInstance()->GetPasteData(pasteData);
248             CHECK_NULL_VOID(ok);
249             auto textData = pasteData.GetPrimaryText();
250             CHECK_NULL_VOID(textData);
251             result = *textData;
252         },
253         TaskExecutor::TaskType::PLATFORM);
254     callback(result);
255 }
256 
GetDataAsync(const std::function<void (const std::string &)> & callback)257 void ClipboardImpl::GetDataAsync(const std::function<void(const std::string&)>& callback)
258 {
259     taskExecutor_->PostTask(
260         [callback, weakExecutor = WeakClaim(RawPtr(taskExecutor_))]() {
261             auto taskExecutor = weakExecutor.Upgrade();
262             CHECK_NULL_VOID(taskExecutor);
263             auto has = OHOS::MiscServices::PasteboardClient::GetInstance()->HasPasteData();
264             if (!has) {
265                 LOGW("GetDataAsync: SystemKeyboardData is not exist from MiscServices");
266                 taskExecutor->PostTask([callback]() { callback(""); }, TaskExecutor::TaskType::UI);
267                 return;
268             }
269             OHOS::MiscServices::PasteData pasteData;
270             auto ok = OHOS::MiscServices::PasteboardClient::GetInstance()->GetPasteData(pasteData);
271             if (!ok) {
272                 LOGW("GetDataAsync: Get SystemKeyboardData fail from MiscServices");
273                 taskExecutor->PostTask([callback]() { callback(""); }, TaskExecutor::TaskType::UI);
274                 return;
275             }
276             std::string resText;
277             for (const auto& pasteDataRecord : pasteData.AllRecords()) {
278                 if (pasteDataRecord == nullptr) {
279                     continue;
280                 }
281                 if (pasteDataRecord->GetPlainText() != nullptr) {
282                     auto textData = pasteDataRecord->GetPlainText();
283                     resText.append(*textData);
284                 }
285             }
286             if (resText.empty()) {
287                 LOGW("GetDataAsync: Get SystemKeyboardTextData fail from MiscServices");
288                 taskExecutor->PostTask([callback]() { callback(""); }, TaskExecutor::TaskType::UI);
289                 return;
290             }
291             auto result = resText;
292             taskExecutor->PostTask([callback, result]() { callback(result); }, TaskExecutor::TaskType::UI);
293         },
294         TaskExecutor::TaskType::PLATFORM);
295 }
296 
GetDataSync(const std::function<void (const std::string &,bool isLastRecord)> & textCallback,const std::function<void (const RefPtr<PixelMap> &,bool isLastRecord)> & pixelMapCallback,const std::function<void (const std::string &,bool isLastRecord)> & urlCallback)297 void ClipboardImpl::GetDataSync(const std::function<void(const std::string&, bool isLastRecord)>& textCallback,
298     const std::function<void(const RefPtr<PixelMap>&, bool isLastRecord)>& pixelMapCallback,
299     const std::function<void(const std::string&, bool isLastRecord)>& urlCallback)
300 {
301     LOGI("get data from clipboard, sync");
302     OHOS::MiscServices::PasteData pasteData;
303     taskExecutor_->PostSyncTask(
304         [&pasteData]() {
305             auto has = OHOS::MiscServices::PasteboardClient::GetInstance()->HasPasteData();
306             CHECK_NULL_VOID(has);
307             auto ok = OHOS::MiscServices::PasteboardClient::GetInstance()->GetPasteData(pasteData);
308             CHECK_NULL_VOID(ok);
309         },
310         TaskExecutor::TaskType::PLATFORM);
311 
312     auto count = pasteData.GetRecordCount();
313     size_t index = 0;
314     for (const auto& pasteDataRecord : pasteData.AllRecords()) {
315         index++;
316         if (pasteDataRecord == nullptr) {
317             continue;
318         }
319         bool isLastRecord = index == count;
320         if (pasteDataRecord->GetPlainText() != nullptr) {
321             auto textData = pasteDataRecord->GetPlainText();
322             auto result = *textData;
323             textCallback(result, isLastRecord);
324         } else if (pasteDataRecord->GetPixelMap() != nullptr) {
325             auto imageData = pasteDataRecord->GetPixelMap();
326             auto result = AceType::MakeRefPtr<PixelMapOhos>(imageData);
327             pixelMapCallback(result, isLastRecord);
328         } else if (pasteDataRecord->GetUri() != nullptr) {
329             auto textData = pasteDataRecord->GetUri();
330             auto result = (*textData).ToString();
331             urlCallback(result, isLastRecord);
332         }
333     }
334 }
335 
GetDataAsync(const std::function<void (const std::string &,bool isLastRecord)> & textCallback,const std::function<void (const RefPtr<PixelMap> &,bool isLastRecord)> & pixelMapCallback,const std::function<void (const std::string &,bool isLastRecord)> & urlCallback)336 void ClipboardImpl::GetDataAsync(const std::function<void(const std::string&, bool isLastRecord)>& textCallback,
337     const std::function<void(const RefPtr<PixelMap>&, bool isLastRecord)>& pixelMapCallback,
338     const std::function<void(const std::string&, bool isLastRecord)>& urlCallback)
339 {
340     LOGI("get data from clipboard, async");
341     taskExecutor_->PostTask(
342         [textCallback, pixelMapCallback, urlCallback, weakExecutor = WeakClaim(RawPtr(taskExecutor_))]() {
343             auto taskExecutor = weakExecutor.Upgrade();
344             auto has = OHOS::MiscServices::PasteboardClient::GetInstance()->HasPasteData();
345             CHECK_NULL_VOID(has);
346             OHOS::MiscServices::PasteData pasteData;
347             auto ok = OHOS::MiscServices::PasteboardClient::GetInstance()->GetPasteData(pasteData);
348             CHECK_NULL_VOID(ok);
349             auto count = pasteData.GetRecordCount();
350             size_t index = 0;
351             for (const auto& pasteDataRecord : pasteData.AllRecords()) {
352                 index++;
353                 if (pasteDataRecord == nullptr) {
354                     continue;
355                 }
356                 bool isLastRecord = index == count;
357                 if (pasteDataRecord->GetPlainText() != nullptr) {
358                     auto textData = pasteDataRecord->GetPlainText();
359                     auto result = *textData;
360                     taskExecutor->PostTask(
361                         [textCallback, result, isLastRecord]() { textCallback(result, isLastRecord); },
362                         TaskExecutor::TaskType::UI);
363                 } else if (pasteDataRecord->GetPixelMap() != nullptr) {
364                     auto imageData = pasteDataRecord->GetPixelMap();
365                     auto result = AceType::MakeRefPtr<PixelMapOhos>(imageData);
366                     taskExecutor->PostTask(
367                         [pixelMapCallback, result, isLastRecord]() { pixelMapCallback(result, isLastRecord); },
368                         TaskExecutor::TaskType::UI);
369                 } else if (pasteDataRecord->GetUri() != nullptr) {
370                     auto textData = pasteDataRecord->GetUri();
371                     auto result = (*textData).ToString();
372                     taskExecutor->PostTask([urlCallback, result, isLastRecord]() { urlCallback(result, isLastRecord); },
373                         TaskExecutor::TaskType::UI);
374                 }
375             }
376         },
377         TaskExecutor::TaskType::PLATFORM);
378 }
379 
GetPixelMapDataSync(const std::function<void (const RefPtr<PixelMap> &)> & callback)380 void ClipboardImpl::GetPixelMapDataSync(const std::function<void(const RefPtr<PixelMap>&)>& callback)
381 {
382     RefPtr<PixelMap> pixmap;
383     taskExecutor_->PostSyncTask(
384         [&pixmap]() {
385             auto has = OHOS::MiscServices::PasteboardClient::GetInstance()->HasPasteData();
386             CHECK_NULL_VOID(has);
387             OHOS::MiscServices::PasteData pasteData;
388             auto ok = OHOS::MiscServices::PasteboardClient::GetInstance()->GetPasteData(pasteData);
389             CHECK_NULL_VOID(ok);
390             auto imageData = pasteData.GetPrimaryPixelMap();
391             CHECK_NULL_VOID(imageData);
392             pixmap = AceType::MakeRefPtr<PixelMapOhos>(imageData);
393         },
394         TaskExecutor::TaskType::PLATFORM);
395     callback(pixmap);
396 }
397 
GetPixelMapDataAsync(const std::function<void (const RefPtr<PixelMap> &)> & callback)398 void ClipboardImpl::GetPixelMapDataAsync(const std::function<void(const RefPtr<PixelMap>&)>& callback)
399 {
400     taskExecutor_->PostTask(
401         [callback, weakExecutor = WeakClaim(RawPtr(taskExecutor_))]() {
402             auto taskExecutor = weakExecutor.Upgrade();
403             CHECK_NULL_VOID(taskExecutor);
404             auto has = OHOS::MiscServices::PasteboardClient::GetInstance()->HasPasteData();
405             if (!has) {
406                 LOGW("SystemKeyboardData is not exist from MiscServices");
407                 taskExecutor->PostTask([callback]() { callback(nullptr); }, TaskExecutor::TaskType::UI);
408                 return;
409             }
410             OHOS::MiscServices::PasteData pasteData;
411             auto ok = OHOS::MiscServices::PasteboardClient::GetInstance()->GetPasteData(pasteData);
412             if (!ok) {
413                 LOGW("Get SystemKeyboardData fail from MiscServices");
414                 taskExecutor->PostTask([callback]() { callback(nullptr); }, TaskExecutor::TaskType::UI);
415                 return;
416             }
417             auto imageData = pasteData.GetPrimaryPixelMap();
418             if (!imageData) {
419                 LOGW("Get SystemKeyboardImageData fail from MiscServices");
420                 taskExecutor->PostTask([callback]() { callback(nullptr); }, TaskExecutor::TaskType::UI);
421                 return;
422             }
423             auto result = AceType::MakeRefPtr<PixelMapOhos>(imageData);
424             taskExecutor->PostTask([callback, result]() { callback(result); }, TaskExecutor::TaskType::UI);
425         },
426         TaskExecutor::TaskType::PLATFORM);
427 }
428 #endif
429 
Clear()430 void ClipboardImpl::Clear() {}
431 
432 } // namespace OHOS::Ace
433