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 #include "adapter/ohos/osal/pixel_map_ohos.h"
18 #include "base/utils/utils.h"
19
20 #ifdef SYSTEM_CLIPBOARD_SUPPORTED
21 #include "pasteboard_client.h"
22 #endif
23
24 namespace OHOS::Ace {
25 #ifndef SYSTEM_CLIPBOARD_SUPPORTED
26 namespace {
27 std::string g_clipboard;
28 RefPtr<PixelMap> g_pixmap;
29 }
30 #endif
TransitionCopyOption(CopyOptions copyOption)31 MiscServices::ShareOption TransitionCopyOption(CopyOptions copyOption)
32 {
33 auto shareOption = MiscServices::ShareOption::InApp;
34 switch (copyOption) {
35 case CopyOptions::InApp:
36 shareOption = MiscServices::ShareOption::InApp;
37 break;
38 case CopyOptions::Local:
39 shareOption = MiscServices::ShareOption::LocalDevice;
40 break;
41 case CopyOptions::Distributed:
42 shareOption = MiscServices::ShareOption::CrossDevice;
43 break;
44 default:
45 break;
46 }
47 return shareOption;
48 }
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 taskExecutor_->PostSyncTask(
55 [&hasData]() {
56 hasData = OHOS::MiscServices::PasteboardClient::GetInstance()->HasPasteData();
57 },
58 TaskExecutor::TaskType::PLATFORM);
59 callback(hasData);
60 #endif
61 }
62
SetData(const std::string & data,CopyOptions copyOption,bool isDragData)63 void ClipboardImpl::SetData(const std::string& data, CopyOptions copyOption, bool isDragData)
64 {
65 CHECK_NULL_VOID_NOLOG(taskExecutor_);
66 #ifdef SYSTEM_CLIPBOARD_SUPPORTED
67 auto shareOption = TransitionCopyOption(copyOption);
68 taskExecutor_->PostTask(
69 [data, shareOption, isDragData]() {
70 auto pasteData = OHOS::MiscServices::PasteboardClient::GetInstance()->CreatePlainTextData(data);
71 CHECK_NULL_VOID(pasteData);
72 pasteData->SetShareOption(shareOption);
73 pasteData->SetDraggedDataFlag(isDragData);
74 OHOS::MiscServices::PasteboardClient::GetInstance()->SetPasteData(*pasteData);
75 },
76 TaskExecutor::TaskType::PLATFORM);
77 #else
78 LOGI("Current device doesn't support system clipboard");
79 taskExecutor_->PostTask([data]() { g_clipboard = data; }, TaskExecutor::TaskType::UI);
80 #endif
81 }
82
SetPixelMapData(const RefPtr<PixelMap> & pixmap,CopyOptions copyOption)83 void ClipboardImpl::SetPixelMapData(const RefPtr<PixelMap>& pixmap, CopyOptions copyOption)
84 {
85 CHECK_NULL_VOID_NOLOG(taskExecutor_);
86 #ifdef SYSTEM_CLIPBOARD_SUPPORTED
87 auto shareOption = TransitionCopyOption(copyOption);
88 taskExecutor_->PostTask(
89 [pixmap, shareOption]() {
90 CHECK_NULL_VOID(pixmap);
91 auto pixmapOhos = AceType::DynamicCast<PixelMapOhos>(pixmap);
92 CHECK_NULL_VOID_NOLOG(pixmapOhos);
93 auto pasteData = OHOS::MiscServices::PasteboardClient::GetInstance()->CreatePixelMapData(
94 pixmapOhos->GetPixelMapSharedPtr());
95 CHECK_NULL_VOID(pasteData);
96 pasteData->SetShareOption(shareOption);
97 LOGI("Set pixmap to system clipboard");
98 OHOS::MiscServices::PasteboardClient::GetInstance()->SetPasteData(*pasteData);
99 },
100 TaskExecutor::TaskType::PLATFORM);
101 #else
102 LOGI("Current device doesn't support system clipboard");
103 taskExecutor_->PostTask([pixmap]() { g_pixmap = pixmap; }, TaskExecutor::TaskType::UI);
104 #endif
105 }
106
GetData(const std::function<void (const std::string &)> & callback,bool syncMode)107 void ClipboardImpl::GetData(const std::function<void(const std::string&)>& callback, bool syncMode)
108 {
109 #ifdef SYSTEM_CLIPBOARD_SUPPORTED
110 if (!taskExecutor_ || !callback) {
111 return;
112 }
113
114 if (syncMode) {
115 GetDataSync(callback);
116 } else {
117 GetDataAsync(callback);
118 }
119 #else
120 LOGI("Current device doesn't support system clipboard");
121 if (syncMode) {
122 callback(g_clipboard);
123 } else {
124 taskExecutor_->PostTask(
125 [callback, taskExecutor = WeakClaim(RawPtr(taskExecutor_)), textData = g_clipboard]() {
126 callback(textData);
127 },
128 TaskExecutor::TaskType::UI);
129 }
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(
150 [callback, taskExecutor = WeakClaim(RawPtr(taskExecutor_)), imageData = g_pixmap]() {
151 callback(imageData);
152 },
153 TaskExecutor::TaskType::UI);
154 }
155 #endif
156 }
157
158 #ifdef SYSTEM_CLIPBOARD_SUPPORTED
GetDataSync(const std::function<void (const std::string &)> & callback)159 void ClipboardImpl::GetDataSync(const std::function<void(const std::string&)>& callback)
160 {
161 std::string result;
162 taskExecutor_->PostSyncTask(
163 [&result]() {
164 auto has = OHOS::MiscServices::PasteboardClient::GetInstance()->HasPasteData();
165 CHECK_NULL_VOID(has);
166 OHOS::MiscServices::PasteData pasteData;
167 auto ok = OHOS::MiscServices::PasteboardClient::GetInstance()->GetPasteData(pasteData);
168 CHECK_NULL_VOID(ok);
169 auto textData = pasteData.GetPrimaryText();
170 CHECK_NULL_VOID(textData);
171 result = *textData;
172 },
173 TaskExecutor::TaskType::PLATFORM);
174 callback(result);
175 }
176
GetDataAsync(const std::function<void (const std::string &)> & callback)177 void ClipboardImpl::GetDataAsync(const std::function<void(const std::string&)>& callback)
178 {
179 taskExecutor_->PostTask(
180 [callback, weakExecutor = WeakClaim(RawPtr(taskExecutor_))]() {
181 auto taskExecutor = weakExecutor.Upgrade();
182 CHECK_NULL_VOID(taskExecutor);
183 auto has = OHOS::MiscServices::PasteboardClient::GetInstance()->HasPasteData();
184 if (!has) {
185 LOGE("GetDataAsync: SystemKeyboardData is not exist from MiscServices");
186 taskExecutor->PostTask([callback]() { callback(""); }, TaskExecutor::TaskType::UI);
187 return;
188 }
189 OHOS::MiscServices::PasteData pasteData;
190 auto ok = OHOS::MiscServices::PasteboardClient::GetInstance()->GetPasteData(pasteData);
191 if (!ok) {
192 LOGE("GetDataAsync: Get SystemKeyboardData fail from MiscServices");
193 taskExecutor->PostTask([callback]() { callback(""); }, TaskExecutor::TaskType::UI);
194 return;
195 }
196 auto textData = pasteData.GetPrimaryText();
197 if (!textData) {
198 LOGE("GetDataAsync: Get SystemKeyboardTextData fail from MiscServices");
199 taskExecutor->PostTask([callback]() { callback(""); }, TaskExecutor::TaskType::UI);
200 return;
201 }
202 auto result = *textData;
203 taskExecutor->PostTask([callback, result]() { callback(result); }, TaskExecutor::TaskType::UI);
204 },
205 TaskExecutor::TaskType::PLATFORM);
206 }
207
GetPixelMapDataSync(const std::function<void (const RefPtr<PixelMap> &)> & callback)208 void ClipboardImpl::GetPixelMapDataSync(const std::function<void(const RefPtr<PixelMap>&)>& callback)
209 {
210 RefPtr<PixelMap> pixmap;
211 taskExecutor_->PostSyncTask(
212 [&pixmap]() {
213 auto has = OHOS::MiscServices::PasteboardClient::GetInstance()->HasPasteData();
214 CHECK_NULL_VOID(has);
215 OHOS::MiscServices::PasteData pasteData;
216 auto ok = OHOS::MiscServices::PasteboardClient::GetInstance()->GetPasteData(pasteData);
217 CHECK_NULL_VOID(ok);
218 auto imageData = pasteData.GetPrimaryPixelMap();
219 CHECK_NULL_VOID(imageData);
220 pixmap = AceType::MakeRefPtr<PixelMapOhos>(imageData);
221 },
222 TaskExecutor::TaskType::PLATFORM);
223 callback(pixmap);
224 }
225
GetPixelMapDataAsync(const std::function<void (const RefPtr<PixelMap> &)> & callback)226 void ClipboardImpl::GetPixelMapDataAsync(const std::function<void(const RefPtr<PixelMap>&)>& callback)
227 {
228 taskExecutor_->PostTask(
229 [callback, weakExecutor = WeakClaim(RawPtr(taskExecutor_))]() {
230 auto taskExecutor = weakExecutor.Upgrade();
231 CHECK_NULL_VOID(taskExecutor);
232 auto has = OHOS::MiscServices::PasteboardClient::GetInstance()->HasPasteData();
233 if (!has) {
234 LOGE("SystemKeyboardData is not exist from MiscServices");
235 taskExecutor->PostTask([callback]() { callback(nullptr); }, TaskExecutor::TaskType::UI);
236 return;
237 }
238 OHOS::MiscServices::PasteData pasteData;
239 auto ok = OHOS::MiscServices::PasteboardClient::GetInstance()->GetPasteData(pasteData);
240 if (!ok) {
241 LOGE("Get SystemKeyboardData fail from MiscServices");
242 taskExecutor->PostTask([callback]() { callback(nullptr); }, TaskExecutor::TaskType::UI);
243 return;
244 }
245 auto imageData = pasteData.GetPrimaryPixelMap();
246 if (!imageData) {
247 LOGE("Get SystemKeyboardImageData fail from MiscServices");
248 taskExecutor->PostTask([callback]() { callback(nullptr); }, TaskExecutor::TaskType::UI);
249 return;
250 }
251 auto result = AceType::MakeRefPtr<PixelMapOhos>(imageData);
252 taskExecutor->PostTask([callback, result]() { callback(result); }, TaskExecutor::TaskType::UI);
253 },
254 TaskExecutor::TaskType::PLATFORM);
255 }
256 #endif
257
Clear()258 void ClipboardImpl::Clear() {}
259
260 } // namespace OHOS::Ace