• 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_NOLOG(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_NOLOG(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     LOGI("Current device doesn't support system clipboard");
78     taskExecutor_->PostTask([data]() { g_clipboard = data; }, TaskExecutor::TaskType::UI);
79 #endif
80 }
81 
SetPixelMapData(const RefPtr<PixelMap> & pixmap,CopyOptions copyOption)82 void ClipboardImpl::SetPixelMapData(const RefPtr<PixelMap>& pixmap, CopyOptions copyOption)
83 {
84     CHECK_NULL_VOID_NOLOG(taskExecutor_);
85 #ifdef SYSTEM_CLIPBOARD_SUPPORTED
86     auto shareOption = TransitionCopyOption(copyOption);
87     taskExecutor_->PostTask(
88         [pixmap, shareOption]() {
89             CHECK_NULL_VOID(pixmap);
90             auto pixmapOhos = AceType::DynamicCast<PixelMapOhos>(pixmap);
91             CHECK_NULL_VOID_NOLOG(pixmapOhos);
92             auto pasteData = OHOS::MiscServices::PasteboardClient::GetInstance()->CreatePixelMapData(
93                 pixmapOhos->GetPixelMapSharedPtr());
94             CHECK_NULL_VOID(pasteData);
95             pasteData->SetShareOption(shareOption);
96             LOGI("Set pixmap to system clipboard");
97             OHOS::MiscServices::PasteboardClient::GetInstance()->SetPasteData(*pasteData);
98         },
99         TaskExecutor::TaskType::PLATFORM);
100 #else
101     LOGI("Current device doesn't support system clipboard");
102     taskExecutor_->PostTask([pixmap]() { g_pixmap = pixmap; }, TaskExecutor::TaskType::UI);
103 #endif
104 }
105 
GetData(const std::function<void (const std::string &)> & callback,bool syncMode)106 void ClipboardImpl::GetData(const std::function<void(const std::string&)>& callback, bool syncMode)
107 {
108 #ifdef SYSTEM_CLIPBOARD_SUPPORTED
109     if (!taskExecutor_ || !callback) {
110         return;
111     }
112 
113     if (syncMode) {
114         GetDataSync(callback);
115     } else {
116         GetDataAsync(callback);
117     }
118 #else
119     LOGI("Current device doesn't support system clipboard");
120     if (syncMode) {
121         callback(g_clipboard);
122         return;
123     }
124     CHECK_NULL_VOID_NOLOG(taskExecutor_);
125     taskExecutor_->PostTask(
126         [callback, taskExecutor = WeakClaim(RawPtr(taskExecutor_)), textData = g_clipboard]() {
127             callback(textData);
128         },
129         TaskExecutor::TaskType::UI);
130 #endif
131 }
132 
GetPixelMapData(const std::function<void (const RefPtr<PixelMap> &)> & callback,bool syncMode)133 void ClipboardImpl::GetPixelMapData(const std::function<void(const RefPtr<PixelMap>&)>& callback, bool syncMode)
134 {
135     if (!taskExecutor_ || !callback) {
136         return;
137     }
138 #ifdef SYSTEM_CLIPBOARD_SUPPORTED
139     if (syncMode) {
140         GetPixelMapDataSync(callback);
141     } else {
142         GetPixelMapDataAsync(callback);
143     }
144 #else
145     LOGI("Current device doesn't support system clipboard");
146     if (syncMode) {
147         callback(g_pixmap);
148     } else {
149         taskExecutor_->PostTask([callback, taskExecutor = WeakClaim(RawPtr(taskExecutor_)),
150                                     imageData = g_pixmap]() { callback(imageData); },
151             TaskExecutor::TaskType::UI);
152     }
153 #endif
154 }
155 
CreatePasteDataMix()156 RefPtr<PasteDataMix> ClipboardImpl::CreatePasteDataMix()
157 {
158     return AceType::MakeRefPtr<PasteDataImpl>();
159 }
160 
AddPixelMapRecord(const RefPtr<PasteDataMix> & pasteData,const RefPtr<PixelMap> & pixmap)161 void ClipboardImpl::AddPixelMapRecord(const RefPtr<PasteDataMix>& pasteData, const RefPtr<PixelMap>& pixmap)
162 {
163     CHECK_NULL_VOID_NOLOG(taskExecutor_);
164     auto peData = AceType::DynamicCast<PasteDataImpl>(pasteData);
165     CHECK_NULL_VOID(peData);
166     auto pixmapOhos = AceType::DynamicCast<PixelMapOhos>(pixmap);
167     CHECK_NULL_VOID_NOLOG(pixmapOhos);
168     LOGI("add pixelMap record to pasteData");
169     peData->GetPasteDataData()->AddPixelMapRecord(pixmapOhos->GetPixelMapSharedPtr());
170 }
171 
AddImageRecord(const RefPtr<PasteDataMix> & pasteData,const std::string & uri)172 void ClipboardImpl::AddImageRecord(const RefPtr<PasteDataMix>& pasteData, const std::string& uri)
173 {
174     CHECK_NULL_VOID_NOLOG(taskExecutor_);
175     auto peData = AceType::DynamicCast<PasteDataImpl>(pasteData);
176     CHECK_NULL_VOID(peData);
177     LOGI("add url record to pasteData, url:  %{public}s", uri.c_str());
178     peData->GetPasteDataData()->AddUriRecord(OHOS::Uri(uri));
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     CHECK_NULL_VOID_NOLOG(taskExecutor_);
184     auto peData = AceType::DynamicCast<PasteDataImpl>(pasteData);
185     CHECK_NULL_VOID(peData);
186     LOGI("add text record to pasteData, text:  %{public}s", selectedStr.c_str());
187     peData->GetPasteDataData()->AddTextRecord(selectedStr);
188 }
189 
SetData(const RefPtr<PasteDataMix> & pasteData,CopyOptions copyOption)190 void ClipboardImpl::SetData(const RefPtr<PasteDataMix>& pasteData, CopyOptions copyOption)
191 {
192 #ifdef SYSTEM_CLIPBOARD_SUPPORTED
193     auto shareOption = TransitionCopyOption(copyOption);
194     auto peData = AceType::DynamicCast<PasteDataImpl>(pasteData);
195     CHECK_NULL_VOID(peData);
196     taskExecutor_->PostTask(
197         [peData, shareOption]() {
198             auto pasteData = peData->GetPasteDataData();
199             pasteData->SetShareOption(shareOption);
200             LOGI("add pasteData to clipboard, shareOption:  %{public}d", shareOption);
201             OHOS::MiscServices::PasteboardClient::GetInstance()->SetPasteData(*pasteData);
202         },
203         TaskExecutor::TaskType::PLATFORM);
204 #else
205     LOGI("Current device doesn't support system clipboard");
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 #else
224     LOGI("Current device doesn't support system clipboard");
225 #endif
226 }
227 
228 #ifdef SYSTEM_CLIPBOARD_SUPPORTED
GetPasteDataData()229 std::shared_ptr<MiscServices::PasteData> PasteDataImpl::GetPasteDataData()
230 {
231     if (pasteData_ == nullptr) {
232         pasteData_ = std::make_shared<MiscServices::PasteData>();
233     }
234     return pasteData_;
235 }
SetUnifiedData(std::shared_ptr<MiscServices::PasteData> pasteData)236 void PasteDataImpl::SetUnifiedData(std::shared_ptr<MiscServices::PasteData> pasteData)
237 {
238     pasteData_ = pasteData;
239 }
240 
GetDataSync(const std::function<void (const std::string &)> & callback)241 void ClipboardImpl::GetDataSync(const std::function<void(const std::string&)>& callback)
242 {
243     std::string result;
244     taskExecutor_->PostSyncTask(
245         [&result]() {
246             auto has = OHOS::MiscServices::PasteboardClient::GetInstance()->HasPasteData();
247             CHECK_NULL_VOID(has);
248             OHOS::MiscServices::PasteData pasteData;
249             auto ok = OHOS::MiscServices::PasteboardClient::GetInstance()->GetPasteData(pasteData);
250             CHECK_NULL_VOID(ok);
251             auto textData = pasteData.GetPrimaryText();
252             CHECK_NULL_VOID(textData);
253             result = *textData;
254         },
255         TaskExecutor::TaskType::PLATFORM);
256     callback(result);
257 }
258 
GetDataAsync(const std::function<void (const std::string &)> & callback)259 void ClipboardImpl::GetDataAsync(const std::function<void(const std::string&)>& callback)
260 {
261     taskExecutor_->PostTask(
262         [callback, weakExecutor = WeakClaim(RawPtr(taskExecutor_))]() {
263             auto taskExecutor = weakExecutor.Upgrade();
264             CHECK_NULL_VOID(taskExecutor);
265             auto has = OHOS::MiscServices::PasteboardClient::GetInstance()->HasPasteData();
266             if (!has) {
267                 LOGE("GetDataAsync: SystemKeyboardData is not exist from MiscServices");
268                 taskExecutor->PostTask([callback]() { callback(""); }, TaskExecutor::TaskType::UI);
269                 return;
270             }
271             OHOS::MiscServices::PasteData pasteData;
272             auto ok = OHOS::MiscServices::PasteboardClient::GetInstance()->GetPasteData(pasteData);
273             if (!ok) {
274                 LOGE("GetDataAsync: Get SystemKeyboardData fail from MiscServices");
275                 taskExecutor->PostTask([callback]() { callback(""); }, TaskExecutor::TaskType::UI);
276                 return;
277             }
278             auto textData = pasteData.GetPrimaryText();
279             if (!textData) {
280                 LOGE("GetDataAsync: Get SystemKeyboardTextData fail from MiscServices");
281                 taskExecutor->PostTask([callback]() { callback(""); }, TaskExecutor::TaskType::UI);
282                 return;
283             }
284             auto result = *textData;
285             taskExecutor->PostTask([callback, result]() { callback(result); }, TaskExecutor::TaskType::UI);
286         },
287         TaskExecutor::TaskType::PLATFORM);
288 }
289 
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)290 void ClipboardImpl::GetDataSync(const std::function<void(const std::string&, bool isLastRecord)>& textCallback,
291     const std::function<void(const RefPtr<PixelMap>&, bool isLastRecord)>& pixelMapCallback,
292     const std::function<void(const std::string&, bool isLastRecord)>& urlCallback)
293 {
294     LOGI("get data from clipboard, sync");
295     OHOS::MiscServices::PasteData pasteData;
296     taskExecutor_->PostSyncTask(
297         [&pasteData]() {
298             auto has = OHOS::MiscServices::PasteboardClient::GetInstance()->HasPasteData();
299             CHECK_NULL_VOID(has);
300             auto ok = OHOS::MiscServices::PasteboardClient::GetInstance()->GetPasteData(pasteData);
301             CHECK_NULL_VOID(ok);
302         },
303         TaskExecutor::TaskType::PLATFORM);
304 
305     auto count = pasteData.GetRecordCount();
306     size_t index = 0;
307     for (const auto& pasteDataRecord : pasteData.AllRecords()) {
308         index++;
309         if (pasteDataRecord == nullptr) {
310             continue;
311         }
312         bool isLastRecord = index == count;
313         if (pasteDataRecord->GetPlainText() != nullptr) {
314             auto textData = pasteDataRecord->GetPlainText();
315             auto result = *textData;
316             textCallback(result, isLastRecord);
317         } else if (pasteDataRecord->GetPixelMap() != nullptr) {
318             auto imageData = pasteDataRecord->GetPixelMap();
319             auto result = AceType::MakeRefPtr<PixelMapOhos>(imageData);
320             pixelMapCallback(result, isLastRecord);
321         } else if (pasteDataRecord->GetUri() != nullptr) {
322             auto textData = pasteDataRecord->GetUri();
323             auto result = (*textData).ToString();
324             urlCallback(result, isLastRecord);
325         }
326     }
327 }
328 
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)329 void ClipboardImpl::GetDataAsync(const std::function<void(const std::string&, bool isLastRecord)>& textCallback,
330     const std::function<void(const RefPtr<PixelMap>&, bool isLastRecord)>& pixelMapCallback,
331     const std::function<void(const std::string&, bool isLastRecord)>& urlCallback)
332 {
333     LOGI("get data from clipboard, async");
334     taskExecutor_->PostTask(
335         [textCallback, pixelMapCallback, urlCallback, weakExecutor = WeakClaim(RawPtr(taskExecutor_))]() {
336             auto taskExecutor = weakExecutor.Upgrade();
337             auto has = OHOS::MiscServices::PasteboardClient::GetInstance()->HasPasteData();
338             CHECK_NULL_VOID(has);
339             OHOS::MiscServices::PasteData pasteData;
340             auto ok = OHOS::MiscServices::PasteboardClient::GetInstance()->GetPasteData(pasteData);
341             CHECK_NULL_VOID(ok);
342             auto count = pasteData.GetRecordCount();
343             size_t index = 0;
344             for (const auto& pasteDataRecord : pasteData.AllRecords()) {
345                 index++;
346                 if (pasteDataRecord == nullptr) {
347                     continue;
348                 }
349                 bool isLastRecord = index == count;
350                 if (pasteDataRecord->GetPlainText() != nullptr) {
351                     auto textData = pasteDataRecord->GetPlainText();
352                     auto result = *textData;
353                     taskExecutor->PostTask(
354                         [textCallback, result, isLastRecord]() { textCallback(result, isLastRecord); },
355                         TaskExecutor::TaskType::UI);
356                 } else if (pasteDataRecord->GetPixelMap() != nullptr) {
357                     auto imageData = pasteDataRecord->GetPixelMap();
358                     auto result = AceType::MakeRefPtr<PixelMapOhos>(imageData);
359                     taskExecutor->PostTask(
360                         [pixelMapCallback, result, isLastRecord]() { pixelMapCallback(result, isLastRecord); },
361                         TaskExecutor::TaskType::UI);
362                 } else if (pasteDataRecord->GetUri() != nullptr) {
363                     auto textData = pasteDataRecord->GetUri();
364                     auto result = (*textData).ToString();
365                     taskExecutor->PostTask([urlCallback, result, isLastRecord]() { urlCallback(result, isLastRecord); },
366                         TaskExecutor::TaskType::UI);
367                 }
368             }
369         },
370         TaskExecutor::TaskType::PLATFORM);
371 }
372 
GetPixelMapDataSync(const std::function<void (const RefPtr<PixelMap> &)> & callback)373 void ClipboardImpl::GetPixelMapDataSync(const std::function<void(const RefPtr<PixelMap>&)>& callback)
374 {
375     RefPtr<PixelMap> pixmap;
376     taskExecutor_->PostSyncTask(
377         [&pixmap]() {
378             auto has = OHOS::MiscServices::PasteboardClient::GetInstance()->HasPasteData();
379             CHECK_NULL_VOID(has);
380             OHOS::MiscServices::PasteData pasteData;
381             auto ok = OHOS::MiscServices::PasteboardClient::GetInstance()->GetPasteData(pasteData);
382             CHECK_NULL_VOID(ok);
383             auto imageData = pasteData.GetPrimaryPixelMap();
384             CHECK_NULL_VOID(imageData);
385             pixmap = AceType::MakeRefPtr<PixelMapOhos>(imageData);
386         },
387         TaskExecutor::TaskType::PLATFORM);
388     callback(pixmap);
389 }
390 
GetPixelMapDataAsync(const std::function<void (const RefPtr<PixelMap> &)> & callback)391 void ClipboardImpl::GetPixelMapDataAsync(const std::function<void(const RefPtr<PixelMap>&)>& callback)
392 {
393     taskExecutor_->PostTask(
394         [callback, weakExecutor = WeakClaim(RawPtr(taskExecutor_))]() {
395             auto taskExecutor = weakExecutor.Upgrade();
396             CHECK_NULL_VOID(taskExecutor);
397             auto has = OHOS::MiscServices::PasteboardClient::GetInstance()->HasPasteData();
398             if (!has) {
399                 LOGE("SystemKeyboardData is not exist from MiscServices");
400                 taskExecutor->PostTask([callback]() { callback(nullptr); }, TaskExecutor::TaskType::UI);
401                 return;
402             }
403             OHOS::MiscServices::PasteData pasteData;
404             auto ok = OHOS::MiscServices::PasteboardClient::GetInstance()->GetPasteData(pasteData);
405             if (!ok) {
406                 LOGE("Get SystemKeyboardData fail from MiscServices");
407                 taskExecutor->PostTask([callback]() { callback(nullptr); }, TaskExecutor::TaskType::UI);
408                 return;
409             }
410             auto imageData = pasteData.GetPrimaryPixelMap();
411             if (!imageData) {
412                 LOGE("Get SystemKeyboardImageData fail from MiscServices");
413                 taskExecutor->PostTask([callback]() { callback(nullptr); }, TaskExecutor::TaskType::UI);
414                 return;
415             }
416             auto result = AceType::MakeRefPtr<PixelMapOhos>(imageData);
417             taskExecutor->PostTask([callback, result]() { callback(result); }, TaskExecutor::TaskType::UI);
418         },
419         TaskExecutor::TaskType::PLATFORM);
420 }
421 #endif
422 
Clear()423 void ClipboardImpl::Clear() {}
424 
425 } // namespace OHOS::Ace
426