• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 #define LOG_TAG "Pasteboard_Capi"
17 
18 #include "oh_pasteboard_observer_impl.h"
19 #include "pasteboard_client.h"
20 #include "pasteboard_hilog.h"
21 #include "udmf_capi_common.h"
22 
23 using namespace OHOS::MiscServices;
24 
25 static OH_Pasteboard_ProgressListener g_callback = {0};
26 #define MAX_PATH_LEN 1024
27 #define MAX_DESTURI_LEN 250
28 
IsPasteboardValid(OH_Pasteboard * pasteboard)29 static bool IsPasteboardValid(OH_Pasteboard *pasteboard)
30 {
31     return pasteboard != nullptr && pasteboard->cid == PASTEBOARD_STRUCT_ID;
32 }
33 
IsSubscriberValid(OH_PasteboardObserver * observer)34 static bool IsSubscriberValid(OH_PasteboardObserver *observer)
35 {
36     return observer != nullptr && observer->cid == SUBSCRIBER_STRUCT_ID;
37 }
38 
GetMappedCode(int32_t code)39 static PASTEBOARD_ErrCode GetMappedCode(int32_t code)
40 {
41     auto iter = errCodeMap.find(static_cast<PasteboardError>(code));
42     if (iter != errCodeMap.end()) {
43         return iter->second;
44     }
45     return ERR_INNER_ERROR;
46 }
47 
OH_PasteboardObserver_Create()48 OH_PasteboardObserver *OH_PasteboardObserver_Create()
49 {
50     OH_PasteboardObserver *observer = new (std::nothrow) OH_PasteboardObserver();
51     if (observer == nullptr) {
52         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "allocate memory fail.");
53         return nullptr;
54     }
55     return observer;
56 }
57 
OH_PasteboardObserver_Destroy(OH_PasteboardObserver * observer)58 int OH_PasteboardObserver_Destroy(OH_PasteboardObserver *observer)
59 {
60     if (!IsSubscriberValid(observer)) {
61         return ERR_INVALID_PARAMETER;
62     }
63     if (observer->finalize != nullptr) {
64         (observer->finalize)(observer->context);
65         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CAPI, "context finalized");
66     }
67     delete observer;
68     return ERR_OK;
69 }
70 
OH_PasteboardObserver_SetData(OH_PasteboardObserver * observer,void * context,const Pasteboard_Notify callback,const Pasteboard_Finalize finalize)71 int OH_PasteboardObserver_SetData(OH_PasteboardObserver *observer, void *context, const Pasteboard_Notify callback,
72     const Pasteboard_Finalize finalize)
73 {
74     if (observer == nullptr || callback == nullptr) {
75         return ERR_INVALID_PARAMETER;
76     }
77     observer->callback = callback;
78     if (context != nullptr && finalize == nullptr) {
79         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "finalize is null");
80         return ERR_INVALID_PARAMETER;
81     }
82     observer->context = context;
83     observer->finalize = finalize;
84     return ERR_OK;
85 }
86 
OH_Pasteboard_Create()87 OH_Pasteboard *OH_Pasteboard_Create()
88 {
89     OH_Pasteboard *pasteboard = new (std::nothrow) OH_Pasteboard();
90     if (pasteboard == nullptr) {
91         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "allocate memory fail.");
92         return nullptr;
93     }
94     return pasteboard;
95 }
96 
OH_Pasteboard_Destroy(OH_Pasteboard * pasteboard)97 void OH_Pasteboard_Destroy(OH_Pasteboard *pasteboard)
98 {
99     if (!IsPasteboardValid(pasteboard)) {
100         return;
101     }
102     std::lock_guard<std::mutex> lock(pasteboard->mutex);
103     for (auto iter : pasteboard->observers_) {
104         if (iter.second != nullptr) {
105             PasteboardClient::GetInstance()->Unsubscribe(
106                 static_cast<PasteboardObserverType>(iter.second->GetType()), iter.second);
107         }
108     }
109     pasteboard->observers_.clear();
110     pasteboard->mimeTypes_.clear();
111     delete[] pasteboard->mimeTypesPtr;
112     pasteboard->mimeTypesPtr = nullptr;
113     delete pasteboard;
114 }
115 
OH_Pasteboard_Subscribe(OH_Pasteboard * pasteboard,int type,const OH_PasteboardObserver * observer)116 int OH_Pasteboard_Subscribe(OH_Pasteboard *pasteboard, int type, const OH_PasteboardObserver *observer)
117 {
118     if (!IsPasteboardValid(pasteboard) || observer == nullptr || type < NOTIFY_LOCAL_DATA_CHANGE ||
119         type > NOTIFY_REMOTE_DATA_CHANGE) {
120         return ERR_INVALID_PARAMETER;
121     }
122     std::lock_guard<std::mutex> lock(pasteboard->mutex);
123     auto iter = pasteboard->observers_.find(observer);
124     if (iter != pasteboard->observers_.end()) {
125         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CAPI, "observer exist.");
126         return ERR_OK;
127     }
128     OHOS::sptr<PasteboardObserverCapiImpl> observerBox = OHOS::sptr<PasteboardObserverCapiImpl>::MakeSptr();
129     if (observerBox == nullptr) {
130         return ERR_INNER_ERROR;
131     }
132     observerBox->SetInnerObserver(observer);
133     observerBox->SetType(static_cast<Pasteboard_NotifyType>(type));
134     bool ret = PasteboardClient::GetInstance()->Subscribe(static_cast<PasteboardObserverType>(type), observerBox);
135     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret, ERR_OK, PASTEBOARD_MODULE_CAPI, "subscribe observer failed");
136     pasteboard->observers_[observer] = observerBox;
137     return ERR_OK;
138 }
139 
OH_Pasteboard_Unsubscribe(OH_Pasteboard * pasteboard,int type,const OH_PasteboardObserver * observer)140 int OH_Pasteboard_Unsubscribe(OH_Pasteboard *pasteboard, int type, const OH_PasteboardObserver *observer)
141 {
142     if (!IsPasteboardValid(pasteboard) || observer == nullptr || type < NOTIFY_LOCAL_DATA_CHANGE ||
143         type > NOTIFY_REMOTE_DATA_CHANGE) {
144         return ERR_INVALID_PARAMETER;
145     }
146     std::lock_guard<std::mutex> lock(pasteboard->mutex);
147     auto iter = pasteboard->observers_.find(observer);
148     if (iter == pasteboard->observers_.end()) {
149         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "couldn't find this observer");
150         return ERR_OK;
151     }
152     PasteboardClient::GetInstance()->Unsubscribe(static_cast<PasteboardObserverType>(type), iter->second);
153     pasteboard->observers_.erase(iter);
154     return ERR_OK;
155 }
156 
OH_Pasteboard_GetChangeCount(OH_Pasteboard * pasteboard)157 uint32_t OH_Pasteboard_GetChangeCount(OH_Pasteboard *pasteboard)
158 {
159     uint32_t changeCount = 0;
160     PasteboardClient::GetInstance()->GetChangeCount(changeCount);
161     return changeCount;
162 }
163 
OH_Pasteboard_IsRemoteData(OH_Pasteboard * pasteboard)164 bool OH_Pasteboard_IsRemoteData(OH_Pasteboard *pasteboard)
165 {
166     return PasteboardClient::GetInstance()->IsRemoteData();
167 }
168 
OH_Pasteboard_GetDataSource(OH_Pasteboard * pasteboard,char * source,unsigned int len)169 int OH_Pasteboard_GetDataSource(OH_Pasteboard *pasteboard, char *source, unsigned int len)
170 {
171     if (!IsPasteboardValid(pasteboard) || source == nullptr || len == 0) {
172         return ERR_INVALID_PARAMETER;
173     }
174     std::string bundleName;
175     auto ret = PasteboardClient::GetInstance()->GetDataSource(bundleName);
176     if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
177         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "client getDataSource return invalid, result is %{public}d", ret);
178         return GetMappedCode(ret);
179     }
180     if (strcpy_s(source, len, bundleName.c_str()) != EOK) {
181         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "copy string fail");
182         return ERR_INNER_ERROR;
183     }
184     return ERR_OK;
185 }
186 
OH_Pasteboard_GetMimeTypes(OH_Pasteboard * pasteboard,unsigned int * count)187 char **OH_Pasteboard_GetMimeTypes(OH_Pasteboard *pasteboard, unsigned int *count)
188 {
189     if (!IsPasteboardValid(pasteboard) || count == nullptr) {
190         return nullptr;
191     }
192     std::lock_guard<std::mutex> lock(pasteboard->mutex);
193     pasteboard->mimeTypes_ = PasteboardClient::GetInstance()->GetMimeTypes();
194     unsigned int typeNum = pasteboard->mimeTypes_.size();
195     if (typeNum == 0 || typeNum > MAX_MIMETYPES_NUM) {
196         *count = 0;
197         return nullptr;
198     }
199     *count = typeNum;
200     delete[] pasteboard->mimeTypesPtr;
201     pasteboard->mimeTypesPtr = new char *[typeNum];
202     for (unsigned int i = 0; i < typeNum; ++i) {
203         pasteboard->mimeTypesPtr[i] = const_cast<char*>(pasteboard->mimeTypes_[i].c_str());
204     }
205     return pasteboard->mimeTypesPtr;
206 }
207 
OH_Pasteboard_HasType(OH_Pasteboard * pasteboard,const char * type)208 bool OH_Pasteboard_HasType(OH_Pasteboard *pasteboard, const char *type)
209 {
210     if (!IsPasteboardValid(pasteboard) || type == nullptr) {
211         return false;
212     }
213     return PasteboardClient::GetInstance()->HasDataType(std::string(type));
214 }
215 
OH_Pasteboard_HasData(OH_Pasteboard * pasteboard)216 bool OH_Pasteboard_HasData(OH_Pasteboard *pasteboard)
217 {
218     if (!IsPasteboardValid(pasteboard)) {
219         return false;
220     }
221     return PasteboardClient::GetInstance()->HasPasteData();
222 }
223 
OH_Pasteboard_GetData(OH_Pasteboard * pasteboard,int * status)224 OH_UdmfData *OH_Pasteboard_GetData(OH_Pasteboard *pasteboard, int *status)
225 {
226     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CAPI, "enter");
227     if (!IsPasteboardValid(pasteboard) || status == nullptr) {
228         return nullptr;
229     }
230     auto unifiedData = std::make_shared<OHOS::UDMF::UnifiedData>();
231     int32_t ret = PasteboardClient::GetInstance()->GetUdsdData(*unifiedData);
232     if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
233         PASTEBOARD_HILOGE(
234             PASTEBOARD_MODULE_CAPI, "client OH_Pasteboard_GetData return invalid, result is %{public}d", ret);
235         *status = GetMappedCode(ret);
236         return nullptr;
237     }
238     OH_UdmfData *data = OH_UdmfData_Create();
239     if (data == nullptr) {
240         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "Failed to create OH_UdmfData");
241         *status = ERR_PASTEBOARD_GET_DATA_FAILED;
242         return nullptr;
243     }
244     data->unifiedData_ = std::move(unifiedData);
245     *status = ERR_OK;
246     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CAPI, "leave");
247     return data;
248 }
249 
OH_Pasteboard_GetDataParams_Create(void)250 Pasteboard_GetDataParams *OH_Pasteboard_GetDataParams_Create(void)
251 {
252     Pasteboard_GetDataParams *params =  new (std::nothrow) Pasteboard_GetDataParams();
253     if (params == nullptr) {
254         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "new Pasteboard_GetDataParams failed!");
255         return nullptr;
256     }
257 
258     params->destUri = new (std::nothrow) char[MAX_PATH_LEN] {0};
259     if (params->destUri == nullptr) {
260         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "malloc failed!");
261         delete params;
262         params = nullptr;
263         return nullptr;
264     }
265     return params;
266 }
267 
OH_Pasteboard_GetDataParams_Destroy(Pasteboard_GetDataParams * params)268 void OH_Pasteboard_GetDataParams_Destroy(Pasteboard_GetDataParams* params)
269 {
270     if (params == nullptr) {
271         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "invalid params!");
272         return;
273     }
274     if (params->destUri != nullptr) {
275         delete[] params->destUri;
276         params->destUri = nullptr;
277     }
278     delete params;
279     params = nullptr;
280 }
281 
OH_Pasteboard_GetDataParams_SetProgressIndicator(Pasteboard_GetDataParams * params,Pasteboard_ProgressIndicator progressIndicator)282 void OH_Pasteboard_GetDataParams_SetProgressIndicator(Pasteboard_GetDataParams* params,
283     Pasteboard_ProgressIndicator progressIndicator)
284 {
285     if (params == nullptr) {
286         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "invalid params!");
287         return;
288     }
289     params->progressIndicator = progressIndicator;
290 }
291 
OH_Pasteboard_GetDataParams_SetDestUri(Pasteboard_GetDataParams * params,const char * destUri,uint32_t destUriLen)292 void OH_Pasteboard_GetDataParams_SetDestUri(Pasteboard_GetDataParams* params, const char* destUri, uint32_t destUriLen)
293 {
294     if (params == nullptr || params->destUri == nullptr || destUri == nullptr || destUriLen == 0 ||
295         destUriLen >= MAX_PATH_LEN) {
296         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "invalid params!");
297         return;
298     }
299 
300     params->destUriLen = destUriLen;
301     if (strcpy_s(params->destUri, MAX_PATH_LEN, destUri) != EOK) {
302         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "copy destUri failed!");
303         return;
304     }
305 }
306 
OH_Pasteboard_GetDataParams_SetFileConflictOptions(Pasteboard_GetDataParams * params,Pasteboard_FileConflictOptions option)307 void OH_Pasteboard_GetDataParams_SetFileConflictOptions(Pasteboard_GetDataParams* params,
308     Pasteboard_FileConflictOptions option)
309 {
310     if (params == nullptr) {
311         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "invalid params!");
312         return;
313     }
314     params->fileConflictOptions = option;
315 }
316 
OH_Pasteboard_GetDataParams_SetProgressListener(Pasteboard_GetDataParams * params,const OH_Pasteboard_ProgressListener listener)317 void OH_Pasteboard_GetDataParams_SetProgressListener(Pasteboard_GetDataParams* params,
318     const OH_Pasteboard_ProgressListener listener)
319 {
320     if (params == nullptr) {
321         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "invalid params!");
322         return;
323     }
324     params->progressListener = listener;
325 }
326 
OH_Pasteboard_ProgressInfo_GetProgress(Pasteboard_ProgressInfo * progressInfo)327 int OH_Pasteboard_ProgressInfo_GetProgress(Pasteboard_ProgressInfo* progressInfo)
328 {
329     if (progressInfo == nullptr) {
330         return ERR_INVALID_PARAMETER;
331     }
332     return progressInfo->progress;
333 }
334 
ProgressNotify(std::shared_ptr<GetDataParams> params)335 void ProgressNotify(std::shared_ptr<GetDataParams> params)
336 {
337     if (params == nullptr || params->info == nullptr) {
338         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "Error: params or params->info is nullptr in ProgressNotify.");
339         return;
340     }
341     if (g_callback != nullptr) {
342         g_callback(reinterpret_cast<Pasteboard_ProgressInfo *>(params->info));
343     }
344 }
345 
OH_Pasteboard_ProgressCancel(Pasteboard_GetDataParams * params)346 void OH_Pasteboard_ProgressCancel(Pasteboard_GetDataParams* params)
347 {
348     ProgressSignalClient::GetInstance().Cancel();
349 }
350 
OH_Pasteboard_GetDataWithProgress(OH_Pasteboard * pasteboard,Pasteboard_GetDataParams * params,int * status)351 OH_UdmfData* OH_Pasteboard_GetDataWithProgress(OH_Pasteboard* pasteboard, Pasteboard_GetDataParams* params, int* status)
352 {
353     if (!IsPasteboardValid(pasteboard) || params == nullptr || status == nullptr) {
354         if (status != nullptr) {
355             *status = ERR_INVALID_PARAMETER;
356         }
357         return nullptr;
358     }
359     auto unifiedData = std::make_shared<OHOS::UDMF::UnifiedData>();
360     auto getDataParams = std::make_shared<OHOS::MiscServices::GetDataParams>();
361     size_t destLen = (params->destUri == nullptr) ? 0 : strlen(params->destUri);
362     if (destLen != 0) {
363         if (destLen > MAX_DESTURI_LEN || params->destUriLen == 0 || params->destUriLen > MAX_DESTURI_LEN ||
364             destLen != static_cast<size_t>(params->destUriLen)) {
365             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "destUri is invalid, destUriLen=%{public}zu", destLen);
366             *status = ERR_INVALID_PARAMETER;
367             return nullptr;
368         }
369         getDataParams->destUri = params->destUri;
370     }
371     g_callback = params->progressListener;
372     getDataParams->fileConflictOption = (FileConflictOption)params->fileConflictOptions;
373     getDataParams->progressIndicator = (ProgressIndicator)params->progressIndicator;
374     getDataParams->info = reinterpret_cast<ProgressInfo *>(&params->info);
375     struct ProgressListener listener = {
376         .ProgressNotify = ProgressNotify,
377     };
378     getDataParams->listener = listener;
379     int32_t ret = PasteboardClient::GetInstance()->GetUnifiedDataWithProgress(*unifiedData, getDataParams);
380     if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
381         PASTEBOARD_HILOGE(
382             PASTEBOARD_MODULE_CAPI, "client OH_Pasteboard_GetDataWithProgress return invalid, result is %{public}d",
383             ret);
384         auto iter = errCodeMap.find(static_cast<PasteboardError>(ret));
385         if (iter != errCodeMap.end()) {
386             *status = iter->second;
387         } else {
388             *status = ERR_PASTEBOARD_GET_DATA_FAILED;
389         }
390         return nullptr;
391     }
392     OH_UdmfData *data = OH_UdmfData_Create();
393     if (data == nullptr) {
394         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "Failed to create OH_UdmfData");
395         *status = ERR_PASTEBOARD_GET_DATA_FAILED;
396         return nullptr;
397     }
398     data->unifiedData_ = std::move(unifiedData);
399     *status = ERR_OK;
400     return data;
401 }
402 
OH_Pasteboard_SetData(OH_Pasteboard * pasteboard,OH_UdmfData * data)403 int OH_Pasteboard_SetData(OH_Pasteboard *pasteboard, OH_UdmfData *data)
404 {
405     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CAPI, "enter");
406     if (!IsPasteboardValid(pasteboard) || data == nullptr) {
407         return ERR_INVALID_PARAMETER;
408     }
409     int32_t ret = PasteboardClient::GetInstance()->SetUdsdData(*(data->unifiedData_));
410     if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
411         PASTEBOARD_HILOGE(
412             PASTEBOARD_MODULE_CAPI, "client OH_Pasteboard_SetData return invalid, result is %{public}d", ret);
413         return GetMappedCode(ret);
414     }
415     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CAPI, "leave");
416     return ERR_OK;
417 }
418 
OH_Pasteboard_ClearData(OH_Pasteboard * pasteboard)419 int OH_Pasteboard_ClearData(OH_Pasteboard *pasteboard)
420 {
421     if (!IsPasteboardValid(pasteboard)) {
422         return ERR_INVALID_PARAMETER;
423     }
424     PasteboardClient::GetInstance()->Clear();
425     return ERR_OK;
426 } // namespace OHOS