• 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 = new (std::nothrow) PasteboardObserverCapiImpl();
129     if (observerBox == nullptr) {
130         return ERR_INNER_ERROR;
131     }
132     observerBox->SetInnerObserver(observer);
133     observerBox->SetType(static_cast<Pasteboard_NotifyType>(type));
134     pasteboard->observers_[observer] = observerBox;
135     PasteboardClient::GetInstance()->Subscribe(static_cast<PasteboardObserverType>(type), observerBox);
136     return ERR_OK;
137 }
138 
OH_Pasteboard_Unsubscribe(OH_Pasteboard * pasteboard,int type,const OH_PasteboardObserver * observer)139 int OH_Pasteboard_Unsubscribe(OH_Pasteboard *pasteboard, int type, const OH_PasteboardObserver *observer)
140 {
141     if (!IsPasteboardValid(pasteboard) || observer == nullptr || type < NOTIFY_LOCAL_DATA_CHANGE ||
142         type > NOTIFY_REMOTE_DATA_CHANGE) {
143         return ERR_INVALID_PARAMETER;
144     }
145     std::lock_guard<std::mutex> lock(pasteboard->mutex);
146     auto iter = pasteboard->observers_.find(observer);
147     if (iter == pasteboard->observers_.end()) {
148         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "couldn't find this observer");
149         return ERR_OK;
150     }
151     PasteboardClient::GetInstance()->Unsubscribe(static_cast<PasteboardObserverType>(type), iter->second);
152     pasteboard->observers_.erase(iter);
153     return ERR_OK;
154 }
155 
OH_Pasteboard_GetChangeCount(OH_Pasteboard * pasteboard)156 uint32_t OH_Pasteboard_GetChangeCount(OH_Pasteboard *pasteboard)
157 {
158     uint32_t changeCount = 0;
159     PasteboardClient::GetInstance()->GetChangeCount(changeCount);
160     return changeCount;
161 }
162 
OH_Pasteboard_IsRemoteData(OH_Pasteboard * pasteboard)163 bool OH_Pasteboard_IsRemoteData(OH_Pasteboard *pasteboard)
164 {
165     if (!IsPasteboardValid(pasteboard)) {
166         return ERR_INVALID_PARAMETER;
167     }
168     return PasteboardClient::GetInstance()->IsRemoteData();
169 }
170 
OH_Pasteboard_GetDataSource(OH_Pasteboard * pasteboard,char * source,unsigned int len)171 int OH_Pasteboard_GetDataSource(OH_Pasteboard *pasteboard, char *source, unsigned int len)
172 {
173     if (!IsPasteboardValid(pasteboard) || source == nullptr || len == 0) {
174         return ERR_INVALID_PARAMETER;
175     }
176     std::string bundleName;
177     auto ret = PasteboardClient::GetInstance()->GetDataSource(bundleName);
178     if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
179         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "client getDataSource return invalid, result is %{public}d", ret);
180         return GetMappedCode(ret);
181     }
182     if (strcpy_s(source, len, bundleName.c_str()) != EOK) {
183         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "copy string fail");
184         return ERR_INNER_ERROR;
185     }
186     return ERR_OK;
187 }
188 
OH_Pasteboard_GetMimeTypes(OH_Pasteboard * pasteboard,unsigned int * count)189 char **OH_Pasteboard_GetMimeTypes(OH_Pasteboard *pasteboard, unsigned int *count)
190 {
191     if (!IsPasteboardValid(pasteboard) || count == nullptr) {
192         return nullptr;
193     }
194     std::lock_guard<std::mutex> lock(pasteboard->mutex);
195     pasteboard->mimeTypes_ = PasteboardClient::GetInstance()->GetMimeTypes();
196     unsigned int typeNum = pasteboard->mimeTypes_.size();
197     if (typeNum == 0 || typeNum > MAX_MIMETYPES_NUM) {
198         *count = 0;
199         return nullptr;
200     }
201     *count = typeNum;
202     delete[] pasteboard->mimeTypesPtr;
203     pasteboard->mimeTypesPtr = new char *[typeNum];
204     for (unsigned int i = 0; i < typeNum; ++i) {
205         pasteboard->mimeTypesPtr[i] = const_cast<char*>(pasteboard->mimeTypes_[i].c_str());
206     }
207     return pasteboard->mimeTypesPtr;
208 }
209 
OH_Pasteboard_HasType(OH_Pasteboard * pasteboard,const char * type)210 bool OH_Pasteboard_HasType(OH_Pasteboard *pasteboard, const char *type)
211 {
212     if (!IsPasteboardValid(pasteboard) || type == nullptr) {
213         return false;
214     }
215     return PasteboardClient::GetInstance()->HasDataType(std::string(type));
216 }
217 
OH_Pasteboard_HasData(OH_Pasteboard * pasteboard)218 bool OH_Pasteboard_HasData(OH_Pasteboard *pasteboard)
219 {
220     if (!IsPasteboardValid(pasteboard)) {
221         return false;
222     }
223     return PasteboardClient::GetInstance()->HasPasteData();
224 }
225 
OH_Pasteboard_GetData(OH_Pasteboard * pasteboard,int * status)226 OH_UdmfData *OH_Pasteboard_GetData(OH_Pasteboard *pasteboard, int *status)
227 {
228     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CAPI, "enter");
229     if (!IsPasteboardValid(pasteboard) || status == nullptr) {
230         return nullptr;
231     }
232     auto unifiedData = std::make_shared<OHOS::UDMF::UnifiedData>();
233     int32_t ret = PasteboardClient::GetInstance()->GetUdsdData(*unifiedData);
234     if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
235         PASTEBOARD_HILOGE(
236             PASTEBOARD_MODULE_CAPI, "client OH_Pasteboard_GetData return invalid, result is %{public}d", ret);
237         *status = GetMappedCode(ret);
238         return nullptr;
239     }
240     OH_UdmfData *data = OH_UdmfData_Create();
241     if (data == nullptr) {
242         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "Failed to create OH_UdmfData");
243         *status = ERR_PASTEBOARD_GET_DATA_FAILED;
244         return nullptr;
245     }
246     data->unifiedData_ = std::move(unifiedData);
247     *status = ERR_OK;
248     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CAPI, "leave");
249     return data;
250 }
251 
OH_Pasteboard_GetDataParams_Create(void)252 Pasteboard_GetDataParams *OH_Pasteboard_GetDataParams_Create(void)
253 {
254     Pasteboard_GetDataParams *params =  new (std::nothrow) Pasteboard_GetDataParams();
255     if (params == nullptr) {
256         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "new Pasteboard_GetDataParams failed!");
257         return nullptr;
258     }
259 
260     params->destUri = new (std::nothrow) char[MAX_PATH_LEN] {0};
261     if (params->destUri == nullptr) {
262         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "malloc failed!");
263         delete params;
264         params = nullptr;
265         return nullptr;
266     }
267     return params;
268 }
269 
OH_Pasteboard_GetDataParams_Destroy(Pasteboard_GetDataParams * params)270 void OH_Pasteboard_GetDataParams_Destroy(Pasteboard_GetDataParams* params)
271 {
272     if (params == nullptr) {
273         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "invalid params!");
274         return;
275     }
276     if (params->destUri != nullptr) {
277         delete[] params->destUri;
278         params->destUri = nullptr;
279     }
280     delete params;
281     params = nullptr;
282 }
283 
OH_Pasteboard_GetDataParams_SetProgressIndicator(Pasteboard_GetDataParams * params,Pasteboard_ProgressIndicator progressIndicator)284 void OH_Pasteboard_GetDataParams_SetProgressIndicator(Pasteboard_GetDataParams* params,
285     Pasteboard_ProgressIndicator progressIndicator)
286 {
287     if (params == nullptr) {
288         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "invalid params!");
289         return;
290     }
291     params->progressIndicator = progressIndicator;
292 }
293 
OH_Pasteboard_GetDataParams_SetDestUri(Pasteboard_GetDataParams * params,const char * destUri,uint32_t destUriLen)294 void OH_Pasteboard_GetDataParams_SetDestUri(Pasteboard_GetDataParams* params, const char* destUri, uint32_t destUriLen)
295 {
296     if (params == nullptr || params->destUri == nullptr || destUri == nullptr || destUriLen == 0 ||
297         destUriLen >= MAX_PATH_LEN) {
298         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "invalid params!");
299         return;
300     }
301 
302     params->destUriLen = destUriLen;
303     if (strcpy_s(params->destUri, MAX_PATH_LEN, destUri) != EOK) {
304         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "copy destUri failed!");
305         return;
306     }
307 }
308 
OH_Pasteboard_GetDataParams_SetFileConflictOptions(Pasteboard_GetDataParams * params,Pasteboard_FileConflictOptions option)309 void OH_Pasteboard_GetDataParams_SetFileConflictOptions(Pasteboard_GetDataParams* params,
310     Pasteboard_FileConflictOptions option)
311 {
312     if (params == nullptr) {
313         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "invalid params!");
314         return;
315     }
316     params->fileConflictOptions = option;
317 }
318 
OH_Pasteboard_GetDataParams_SetProgressListener(Pasteboard_GetDataParams * params,const OH_Pasteboard_ProgressListener listener)319 void OH_Pasteboard_GetDataParams_SetProgressListener(Pasteboard_GetDataParams* params,
320     const OH_Pasteboard_ProgressListener listener)
321 {
322     if (params == nullptr) {
323         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "invalid params!");
324         return;
325     }
326     params->progressListener = listener;
327 }
328 
OH_Pasteboard_ProgressInfo_GetProgress(Pasteboard_ProgressInfo * progressInfo)329 int OH_Pasteboard_ProgressInfo_GetProgress(Pasteboard_ProgressInfo* progressInfo)
330 {
331     if (progressInfo == nullptr) {
332         return ERR_INVALID_PARAMETER;
333     }
334     return progressInfo->progress;
335 }
336 
ProgressNotify(std::shared_ptr<GetDataParams> params)337 void ProgressNotify(std::shared_ptr<GetDataParams> params)
338 {
339     if (params == nullptr || params->info == nullptr) {
340         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "Error: params or params->info is nullptr in ProgressNotify.");
341         return;
342     }
343     if (g_callback != nullptr) {
344         g_callback(reinterpret_cast<Pasteboard_ProgressInfo *>(params->info));
345     }
346 }
347 
OH_Pasteboard_ProgressCancel(Pasteboard_GetDataParams * params)348 void OH_Pasteboard_ProgressCancel(Pasteboard_GetDataParams* params)
349 {
350     ProgressSignalClient::GetInstance().Cancel();
351 }
352 
OH_Pasteboard_GetDataWithProgress(OH_Pasteboard * pasteboard,Pasteboard_GetDataParams * params,int * status)353 OH_UdmfData* OH_Pasteboard_GetDataWithProgress(OH_Pasteboard* pasteboard, Pasteboard_GetDataParams* params, int* status)
354 {
355     if (!IsPasteboardValid(pasteboard) || params == nullptr || status == nullptr) {
356         if (status != nullptr) {
357             *status = ERR_INVALID_PARAMETER;
358         }
359         return nullptr;
360     }
361     auto unifiedData = std::make_shared<OHOS::UDMF::UnifiedData>();
362     auto getDataParams = std::make_shared<OHOS::MiscServices::GetDataParams>();
363     size_t destLen = (params->destUri == nullptr) ? 0 : strlen(params->destUri);
364     if (destLen != 0) {
365         if (destLen > MAX_DESTURI_LEN || params->destUriLen == 0 || params->destUriLen > MAX_DESTURI_LEN ||
366             destLen != static_cast<size_t>(params->destUriLen)) {
367             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "destUri is invalid, destUriLen=%{public}zu", destLen);
368             *status = ERR_INVALID_PARAMETER;
369             return nullptr;
370         }
371         getDataParams->destUri = params->destUri;
372     }
373     g_callback = params->progressListener;
374     getDataParams->fileConflictOption = (FileConflictOption)params->fileConflictOptions;
375     getDataParams->progressIndicator = (ProgressIndicator)params->progressIndicator;
376     getDataParams->info = reinterpret_cast<ProgressInfo *>(&params->info);
377     struct ProgressListener listener = {
378         .ProgressNotify = ProgressNotify,
379     };
380     getDataParams->listener = listener;
381     int32_t ret = PasteboardClient::GetInstance()->GetUnifiedDataWithProgress(*unifiedData, getDataParams);
382     if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
383         PASTEBOARD_HILOGE(
384             PASTEBOARD_MODULE_CAPI, "client OH_Pasteboard_GetDataWithProgress return invalid, result is %{public}d",
385             ret);
386         auto iter = errCodeMap.find(static_cast<PasteboardError>(ret));
387         if (iter != errCodeMap.end()) {
388             *status = iter->second;
389         } else {
390             *status = ERR_PASTEBOARD_GET_DATA_FAILED;
391         }
392         return nullptr;
393     }
394     OH_UdmfData *data = OH_UdmfData_Create();
395     if (data == nullptr) {
396         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "Failed to create OH_UdmfData");
397         *status = ERR_PASTEBOARD_GET_DATA_FAILED;
398         return nullptr;
399     }
400     data->unifiedData_ = std::move(unifiedData);
401     *status = ERR_OK;
402     return data;
403 }
404 
OH_Pasteboard_SetData(OH_Pasteboard * pasteboard,OH_UdmfData * data)405 int OH_Pasteboard_SetData(OH_Pasteboard *pasteboard, OH_UdmfData *data)
406 {
407     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CAPI, "enter");
408     if (!IsPasteboardValid(pasteboard) || data == nullptr) {
409         return ERR_INVALID_PARAMETER;
410     }
411     int32_t ret = PasteboardClient::GetInstance()->SetUdsdData(*(data->unifiedData_));
412     if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
413         PASTEBOARD_HILOGE(
414             PASTEBOARD_MODULE_CAPI, "client OH_Pasteboard_SetData return invalid, result is %{public}d", ret);
415         return GetMappedCode(ret);
416     }
417     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CAPI, "leave");
418     return ERR_OK;
419 }
420 
OH_Pasteboard_ClearData(OH_Pasteboard * pasteboard)421 int OH_Pasteboard_ClearData(OH_Pasteboard *pasteboard)
422 {
423     if (!IsPasteboardValid(pasteboard)) {
424         return ERR_INVALID_PARAMETER;
425     }
426     PasteboardClient::GetInstance()->Clear();
427     return ERR_OK;
428 } // namespace OHOS