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 #include <securec.h>
17 
18 #include "pasteboard_ffi.h"
19 
20 using namespace OHOS::FFI;
21 using namespace OHOS::Media;
22 using namespace OHOS::MiscServices;
23 using namespace OHOS::MiscServicesCj;
24 
25 namespace OHOS {
26 namespace CJSystemapi {
27 extern "C" {
FfiOHOSCreateStringPasteData(const char *mimeType, const char *value)28 RetDataI64 FfiOHOSCreateStringPasteData(const char *mimeType, const char *value)
29 {
30     LOGI("[PasteData] FfiOHOSCreateStringPasteData");
31     RetDataI64 ret;
32     std::string mmType = mimeType;
33     CJValueType valueType;
34     valueType.stringValue = value;
35 
36     ret.data = CreateCjPasteDataObject(mmType, valueType);
37     ret.code = SUCCESS_CODE;
38     LOGI("[PasteData] FfiOHOSCreateStringPasteData success");
39 
40     return ret;
41 }
42 
FfiOHOSCreatePixelMapPasteData(const char *mimeType, int64_t pixelMapId)43 RetDataI64 FfiOHOSCreatePixelMapPasteData(const char *mimeType, int64_t pixelMapId)
44 {
45     LOGI("[PasteData] FfiOHOSCreatePixelMapPasteData");
46     RetDataI64 ret = { .code = ERR_INVALID_INSTANCE_CODE, .data = 0 };
47     auto pixelMapImpl = FFIData::GetData<PixelMapImpl>(pixelMapId);
48     if (pixelMapImpl == nullptr) {
49         return ret;
50     }
51     std::string mmType = mimeType;
52     CJValueType valueType;
53     valueType.pixelMap = pixelMapImpl->GetRealPixelMap();
54 
55     ret.data = CreateCjPasteDataObject(mmType, valueType);
56     ret.code = SUCCESS_CODE;
57     LOGI("[PasteData] FfiOHOSCreatePixelMapPasteData success");
58 
59     return ret;
60 }
61 
FfiOHOSCreateArrayBufPasteData(const char *mimeType, uint8_t *buffPtr, int64_t bufferSize)62 RetDataI64 FfiOHOSCreateArrayBufPasteData(const char *mimeType, uint8_t *buffPtr, int64_t bufferSize)
63 {
64     LOGI("[PasteData] FfiOHOSCreateArrayBufPasteData");
65     RetDataI64 ret;
66     std::string mmType = mimeType;
67     CJValueType valueType;
68     valueType.arrayBufferData = buffPtr;
69     valueType.arrayBufferSize = bufferSize;
70 
71     ret.data = CreateCjPasteDataObject(mmType, valueType);
72     ret.code = SUCCESS_CODE;
73     LOGI("[PasteData] FfiOHOSCreateArrayBufPasteData success");
74 
75     return ret;
76 }
77 
PasteBoardMallocCString(const std::string &origin)78 char *PasteBoardMallocCString(const std::string &origin)
79 {
80     auto len = origin.length() + 1;
81     char *res = static_cast<char *>(malloc(sizeof(char) * len));
82     if (res == nullptr) {
83         return nullptr;
84     }
85     auto ret = strcpy_s(res, sizeof(char) * len, origin.c_str());
86     if (ret != EOK) {
87         LOGE("strcpy_s error");
88         free(res);
89         return nullptr;
90     }
91     return res;
92 }
93 
FillCPasteDataRecord(CPasteDataRecord *retPtr, std::shared_ptr<PasteDataRecord> record)94 void FillCPasteDataRecord(CPasteDataRecord *retPtr, std::shared_ptr<PasteDataRecord> record)
95 {
96     if (record == nullptr) {
97         return;
98     }
99     retPtr->htmlText = nullptr;
100     retPtr->mimeType = nullptr;
101     retPtr->plainText = nullptr;
102     retPtr->uri = nullptr;
103     retPtr->pixelMap = ERR_INVALID_INSTANCE_CODE;
104     if (record->GetHtmlText() != nullptr) {
105         std::string resHtmlText = *(record->GetHtmlText());
106         retPtr->htmlText = PasteBoardMallocCString(resHtmlText);
107     }
108     if (!record->GetMimeType().empty()) {
109         std::string resMimeType = record->GetMimeType();
110         retPtr->mimeType = PasteBoardMallocCString(resMimeType);
111     }
112     if (record->GetPlainText() != nullptr) {
113         std::string resPlainText = *(record->GetPlainText());
114         retPtr->plainText = PasteBoardMallocCString(resPlainText);
115     }
116     if (record->GetUri() != nullptr) {
117         std::string resUri = record->GetUri()->ToString();
118         retPtr->uri = PasteBoardMallocCString(resUri);
119     }
120     std::shared_ptr<PixelMap> pixelMap = record->GetPixelMap();
121     auto nativeImage = FFIData::Create<PixelMapImpl>(move(pixelMap));
122     if (!nativeImage) {
123         retPtr->pixelMap = 0;
124         return;
125     }
126     retPtr->pixelMap = nativeImage->GetID();
127 }
128 
FfiOHOSCreateStringPasteDataRecord(const char *mimeType, const char *value, CPasteDataRecord *retPtr)129 RetDataI64 FfiOHOSCreateStringPasteDataRecord(const char *mimeType, const char *value, CPasteDataRecord *retPtr)
130 {
131     LOGI("[PasteDataRecord] FfiOHOSCreateStringPasteDataRecord");
132     RetDataI64 ret = { .code = ERR_INVALID_INSTANCE_CODE, .data = 0 };
133     std::string mmType = mimeType;
134     CJValueType valueType;
135     valueType.stringValue = value;
136 
137     ret.data = CreateCjPasteDataRecordObject(mmType, valueType);
138     if (ret.data == 0) {
139         return ret;
140     }
141     auto recordInstance = FFIData::GetData<PasteDataRecordImpl>(ret.data);
142     if (!recordInstance) {
143         FFIData::Release(ret.data);
144         return ret;
145     }
146     std::shared_ptr<PasteDataRecord> record = recordInstance->GetRealPasteDataRecord();
147     FillCPasteDataRecord(retPtr, record);
148     ret.code = SUCCESS_CODE;
149     LOGI("[PasteDataRecord] FfiOHOSCreateStringPasteDataRecord success");
150 
151     return ret;
152 }
153 
FfiOHOSCreatePixelMapPasteDataRecord(const char *mimeType, int64_t pixelMapId, CPasteDataRecord *retPtr)154 RetDataI64 FfiOHOSCreatePixelMapPasteDataRecord(const char *mimeType, int64_t pixelMapId, CPasteDataRecord *retPtr)
155 {
156     LOGI("[PasteDataRecord] FfiOHOSCreateStringPasteDataRecord");
157     RetDataI64 ret = { .code = ERR_INVALID_INSTANCE_CODE, .data = 0 };
158     std::string mmType = mimeType;
159     auto pixelMapImpl = FFIData::GetData<PixelMapImpl>(pixelMapId);
160     if (pixelMapImpl == nullptr) {
161         return ret;
162     }
163 
164     auto pixelMap = pixelMapImpl->GetRealPixelMap();
165     CJValueType valueType;
166     valueType.pixelMap = pixelMap;
167     ret.data = CreateCjPasteDataRecordObject(mmType, valueType);
168     if (ret.data == 0) {
169         return ret;
170     }
171     auto recordInstance = FFIData::GetData<PasteDataRecordImpl>(ret.data);
172     if (!recordInstance) {
173         FFIData::Release(ret.data);
174         return ret;
175     }
176     std::shared_ptr<PasteDataRecord> record = recordInstance->GetRealPasteDataRecord();
177     FillCPasteDataRecord(retPtr, record);
178     ret.code = SUCCESS_CODE;
179     LOGI("[PasteDataRecord] FfiOHOSCreateStringPasteDataRecord success");
180 
181     return ret;
182 }
183 
FfiOHOSCreateArrayBufPasteDataRecord( const char *mimeType, uint8_t *buffPtr, int64_t bufferSize, CPasteDataRecord *retPtr)184 RetDataI64 FfiOHOSCreateArrayBufPasteDataRecord(
185     const char *mimeType, uint8_t *buffPtr, int64_t bufferSize, CPasteDataRecord *retPtr)
186 {
187     LOGI("[PasteDataRecord] FfiOHOSCreateArrayBufPasteDataRecord");
188     RetDataI64 ret = { .code = ERR_INVALID_INSTANCE_CODE, .data = 0 };
189     std::string mmType = mimeType;
190     CJValueType valueType;
191     valueType.arrayBufferData = buffPtr;
192     valueType.arrayBufferSize = bufferSize;
193 
194     ret.data = CreateCjPasteDataRecordObject(mmType, valueType);
195     if (ret.data == 0) {
196         return ret;
197     }
198     auto recordInstance = FFIData::GetData<PasteDataRecordImpl>(ret.data);
199     if (!recordInstance) {
200         FFIData::Release(ret.data);
201         return ret;
202     }
203     std::shared_ptr<PasteDataRecord> record = recordInstance->GetRealPasteDataRecord();
204     FillCPasteDataRecord(retPtr, record);
205     ret.code = SUCCESS_CODE;
206     LOGI("[PasteDataRecord] FfiOHOSCreateArrayBufPasteDataRecord success");
207 
208     return ret;
209 }
210 
FfiOHOSPasteDataGetPrimaryText(int64_t id)211 RetDataCString FfiOHOSPasteDataGetPrimaryText(int64_t id)
212 {
213     LOGI("[PasteData] FfiOHOSPasteDataGetPrimaryText start");
214     RetDataCString ret = { .code = ERR_INVALID_INSTANCE_CODE, .data = nullptr };
215     auto instance = FFIData::GetData<PasteDataImpl>(id);
216     if (!instance) {
217         LOGE("[PasteData] GetPrimaryText: instance not exist %{public}" PRId64, id);
218         return ret;
219     }
220 
221     auto pasteData = instance->GetRealPasteData();
222     if (pasteData == nullptr) {
223         LOGE("[PasteData] GetPrimaryText: pasteData not exist");
224         return ret;
225     }
226 
227     std::shared_ptr<std::string> p = pasteData->GetPrimaryText();
228     if (p != nullptr) {
229         ret.data = PasteBoardMallocCString(*p);
230         if (ret.data == nullptr) {
231             ret.code = ERR_CODE_PARAM_INVALID;
232             return ret;
233         }
234     }
235     ret.code = SUCCESS_CODE;
236     LOGI("[PasteData] FfiOHOSPasteDataGetPrimaryText success");
237 
238     return ret;
239 }
240 
FfiOHOSPasteDataRecordToPlainText(int64_t id)241 RetDataCString FfiOHOSPasteDataRecordToPlainText(int64_t id)
242 {
243     LOGI("[PasteData] FfiOHOSPasteDataRecordToPlainText start");
244     RetDataCString ret = { .code = ERR_INVALID_INSTANCE_CODE, .data = nullptr };
245     auto instance = FFIData::GetData<PasteDataRecordImpl>(id);
246     if (!instance) {
247         LOGE("[PasteRecord] ToPlainText: instance not exist %{public}" PRId64, id);
248         ret.code = ERR_INVALID_INSTANCE_CODE;
249         return ret;
250     }
251 
252     std::string res = instance->GetRealPasteDataRecord()->ConvertToText();
253     ret.data = PasteBoardMallocCString(res);
254     if (ret.data == nullptr) {
255         ret.code = ERR_CODE_PARAM_INVALID;
256         return ret;
257     }
258     ret.code = SUCCESS_CODE;
259     LOGI("[PasteRecord] FfiOHOSPasteDataRecordToPlainText success");
260 
261     return ret;
262 }
263 
FfiOHOSPasteDataGetPrimaryHtml(int64_t id)264 RetDataCString FfiOHOSPasteDataGetPrimaryHtml(int64_t id)
265 {
266     LOGI("[PasteData] FfiOHOSPasteDataGetPrimaryHtml start");
267     RetDataCString ret = { .code = ERR_INVALID_INSTANCE_CODE, .data = nullptr };
268     auto instance = FFIData::GetData<PasteDataImpl>(id);
269     if (!instance) {
270         LOGE("[PasteData] GetPrimaryHtml: instance not exist %{public}" PRId64, id);
271         return ret;
272     }
273 
274     auto pasteData = instance->GetRealPasteData();
275     if (pasteData == nullptr) {
276         LOGE("[PasteData] GetPrimaryHtml: pasteData not exist");
277         return ret;
278     }
279 
280     std::shared_ptr<std::string> p = pasteData->GetPrimaryHtml();
281     if (p != nullptr) {
282         ret.data = PasteBoardMallocCString(*p);
283         if (ret.data == nullptr) {
284             ret.code = ERR_CODE_PARAM_INVALID;
285             return ret;
286         }
287     }
288     ret.code = SUCCESS_CODE;
289     LOGI("[PasteData] FfiOHOSPasteDataGetPrimaryHtml success");
290 
291     return ret;
292 }
293 
FfiOHOSPasteDataGetPrimaryUri(int64_t id)294 RetDataCString FfiOHOSPasteDataGetPrimaryUri(int64_t id)
295 {
296     LOGI("[PasteData] FfiOHOSPasteDataGetPrimaryUri start");
297     RetDataCString ret = { .code = ERR_INVALID_INSTANCE_CODE, .data = nullptr };
298     auto instance = FFIData::GetData<PasteDataImpl>(id);
299     if (!instance) {
300         LOGE("[PasteData] GetPrimaryUri: instance not exist %{public}" PRId64, id);
301         return ret;
302     }
303 
304     auto pasteData = instance->GetRealPasteData();
305     if (pasteData == nullptr) {
306         LOGE("[PasteData] GetPrimaryUri: pasteData not exist");
307         return ret;
308     }
309 
310     std::shared_ptr<OHOS::Uri> p = pasteData->GetPrimaryUri();
311     if (p != nullptr) {
312         std::string uri = p->ToString();
313         ret.data = PasteBoardMallocCString(uri);
314         if (ret.data == nullptr) {
315             ret.code = ERR_CODE_PARAM_INVALID;
316             return ret;
317         }
318     }
319     ret.code = SUCCESS_CODE;
320     LOGI("[PasteData] FfiOHOSPasteDataGetPrimaryUri success");
321 
322     return ret;
323 }
324 
FfiOHOSPasteDataGetPrimaryPixelMap(int64_t id)325 RetDataI64 FfiOHOSPasteDataGetPrimaryPixelMap(int64_t id)
326 {
327     LOGI("[PasteData] FfiOHOSPasteDataGetPrimaryPixelMap start");
328     RetDataI64 ret = { .code = ERR_INVALID_INSTANCE_CODE, .data = 0 };
329     auto instance = FFIData::GetData<PasteDataImpl>(id);
330     if (!instance) {
331         LOGE("[PasteData] GetPrimaryPixelMap: instance not exist %{public}" PRId64, id);
332         return ret;
333     }
334 
335     auto pasteData = instance->GetRealPasteData();
336     if (pasteData == nullptr) {
337         LOGE("[PasteData] GetPrimaryPixelMap: pasteData not exist");
338         return ret;
339     }
340 
341     std::shared_ptr<PixelMap> pixelMap = pasteData->GetPrimaryPixelMap();
342     if (pixelMap != nullptr) {
343         auto nativeImage = FFIData::Create<PixelMapImpl>(move(pixelMap));
344         if (!nativeImage) {
345             return ret;
346         }
347         ret.data = nativeImage->GetID();
348         ret.code = SUCCESS_CODE;
349         LOGI("[PasteData] FfiOHOSPasteDataGetPrimaryPixelMap success");
350     } else {
351         LOGE("[PasteData] pixelMap not exist");
352     }
353 
354     return ret;
355 }
356 
FfiOHOSPasteDataGetPrimaryMimeType(int64_t id)357 RetDataCString FfiOHOSPasteDataGetPrimaryMimeType(int64_t id)
358 {
359     LOGI("[PasteData] FfiOHOSPasteDataGetPrimaryMimeType start");
360     RetDataCString ret = { .code = ERR_INVALID_INSTANCE_CODE, .data = nullptr };
361     auto instance = FFIData::GetData<PasteDataImpl>(id);
362     if (!instance) {
363         LOGE("[PasteData] GetPrimaryMimeType: instance not exist %{public}" PRId64, id);
364         return ret;
365     }
366 
367     auto pasteData = instance->GetRealPasteData();
368     if (pasteData == nullptr) {
369         LOGE("[PasteData] GetPrimaryMimeType: pasteData not exist");
370         return ret;
371     }
372 
373     std::shared_ptr<std::string> mimeType = pasteData->GetPrimaryMimeType();
374     if (mimeType != nullptr) {
375         ret.data = PasteBoardMallocCString(*mimeType);
376         if (ret.data == nullptr) {
377             ret.code = ERR_CODE_PARAM_INVALID;
378             return ret;
379         }
380     }
381     ret.code = SUCCESS_CODE;
382     LOGI("[PasteData] FfiOHOSPasteDataGetPrimaryMimeType success");
383 
384     return ret;
385 }
386 
VectorToCArrString(std::vector<std::string> &vec)387 static char **VectorToCArrString(std::vector<std::string> &vec)
388 {
389     char **result = new char *[vec.size()];
390     if (result == nullptr) {
391         return nullptr;
392     }
393     size_t temp = 0;
394     for (size_t i = 0; i < vec.size(); i++) {
395         result[i] = new char[vec[i].length() + 1];
396         if (result[i] == nullptr) {
397             break;
398         }
399         if (strcpy_s(result[i], vec[i].length() + 1, vec[i].c_str()) != 0) {
400             delete[] result[i];
401             result[i] = nullptr;
402             break;
403         }
404         temp++;
405     }
406     if (temp != vec.size()) {
407         for (size_t j = temp; j > 0; j--) {
408             delete[] result[j - 1];
409             result[j - 1] = nullptr;
410         }
411         delete[] result;
412         return nullptr;
413     }
414     return result;
415 }
416 
FfiOHOSPasteDataGetProperty(int64_t id, CPasteDataProperty *retPtr)417 int32_t FfiOHOSPasteDataGetProperty(int64_t id, CPasteDataProperty *retPtr)
418 {
419     LOGI("[PasteData] FfiOHOSPasteDataGetProperty start");
420     auto instance = FFIData::GetData<PasteDataImpl>(id);
421     if (!instance) {
422         LOGE("[PasteData] GetProperty: instance not exist %{public}" PRId64, id);
423         return ERR_INVALID_INSTANCE_CODE;
424     }
425 
426     auto pasteData = instance->GetRealPasteData();
427     if (pasteData == nullptr) {
428         LOGE("[PasteData] GetProperty: pasteData not exist");
429         return ERR_INVALID_INSTANCE_CODE;
430     }
431 
432     PasteDataProperty property = pasteData->GetProperty();
433     retPtr->tag = PasteBoardMallocCString(property.tag);
434     if (retPtr->tag == nullptr) {
435         return ERR_CODE_PARAM_INVALID;
436     }
437     retPtr->mimeTypes.head = VectorToCArrString(property.mimeTypes);
438     if (retPtr->mimeTypes.head == nullptr) {
439         free(retPtr->tag);
440         return ERR_CODE_PARAM_INVALID;
441     }
442     retPtr->mimeTypes.size = static_cast<int64_t>(property.mimeTypes.size());
443     retPtr->timestamp = property.timestamp;
444     retPtr->localOnly = property.localOnly;
445     retPtr->shareOption = property.shareOption;
446     LOGI("[PasteData] FfiOHOSPasteDataGetProperty success");
447 
448     return SUCCESS_CODE;
449 }
450 
CArrStringToVector(CArrString src)451 static std::vector<std::string> CArrStringToVector(CArrString src)
452 {
453     LOGI("CArrStringToVector start");
454     std::vector<std::string> res;
455     for (int64_t i = 0; i < src.size; i++) {
456         res.push_back(std::string(src.head[i]));
457     }
458     LOGI("CArrStringToVector end");
459     return res;
460 }
461 
FfiOHOSPasteDataSetProperty( int64_t id, CArrString mimeTypes, const char *tag, int64_t timestamp, bool localOnly, int32_t shareOption)462 int32_t FfiOHOSPasteDataSetProperty(
463     int64_t id, CArrString mimeTypes, const char *tag, int64_t timestamp, bool localOnly, int32_t shareOption)
464 {
465     LOGI("[PasteData] FfiOHOSPasteDataSetProperty start");
466     auto instance = FFIData::GetData<PasteDataImpl>(id);
467     if (!instance) {
468         LOGE("[PasteData] SetProperty: instance not exist %{public}" PRId64, id);
469         return ERR_INVALID_INSTANCE_CODE;
470     }
471     PasteDataProperty property;
472     property.mimeTypes = CArrStringToVector(mimeTypes);
473     property.tag = tag;
474     property.timestamp = timestamp;
475     property.localOnly = localOnly;
476     property.shareOption = static_cast<ShareOption>(shareOption);
477 
478     auto pasteData = instance->GetRealPasteData();
479     if (pasteData == nullptr) {
480         LOGE("[PasteData] SetProperty: pasteData not exist");
481         return ERR_INVALID_INSTANCE_CODE;
482     }
483 
484     pasteData->SetProperty(property);
485     LOGI("[PasteData] FfiOHOSPasteDataSetProperty success");
486 
487     return SUCCESS_CODE;
488 }
489 
FfiOHOSPasteDataGetTag(int64_t id)490 RetDataCString FfiOHOSPasteDataGetTag(int64_t id)
491 {
492     LOGI("[PasteData] FfiOHOSPasteDataGetTag start");
493     RetDataCString ret = { .code = ERR_INVALID_INSTANCE_CODE, .data = nullptr };
494     auto instance = FFIData::GetData<PasteDataImpl>(id);
495     if (!instance) {
496         LOGE("[PasteData] GetTag: instance not exist %{public}" PRId64, id);
497         return ret;
498     }
499 
500     auto pasteData = instance->GetRealPasteData();
501     if (pasteData == nullptr) {
502         LOGE("[PasteData] GetTag: pasteData not exist");
503         return ret;
504     }
505 
506     std::string tag = pasteData->GetTag();
507     if (!tag.empty()) {
508         ret.data = PasteBoardMallocCString(tag);
509         if (ret.data == nullptr) {
510             ret.code = ERR_CODE_PARAM_INVALID;
511             return ret;
512         }
513     }
514     ret.code = SUCCESS_CODE;
515     LOGI("[PasteData] FfiOHOSPasteDataGetTag success");
516 
517     return ret;
518 }
519 
FfiOHOSPasteDataHasType(int64_t id, const char *mimeTypes)520 RetDataBool FfiOHOSPasteDataHasType(int64_t id, const char *mimeTypes)
521 {
522     LOGI("[PasteData] FfiOHOSPasteDataHasType start");
523     RetDataBool ret = { .code = ERR_INVALID_INSTANCE_CODE, .data = false };
524     auto instance = FFIData::GetData<PasteDataImpl>(id);
525     if (!instance) {
526         LOGE("[PasteData] HasType: instance not exist %{public}" PRId64, id);
527         return ret;
528     }
529 
530     std::string types = mimeTypes;
531 
532     auto pasteData = instance->GetRealPasteData();
533     if (pasteData == nullptr) {
534         LOGE("[PasteData] HasType: pasteData not exist");
535         return ret;
536     }
537 
538     ret.data = pasteData->HasMimeType(types);
539     ret.code = SUCCESS_CODE;
540     LOGI("[PasteData] FfiOHOSPasteDataHasType success");
541 
542     return ret;
543 }
544 
FfiOHOSPasteDataAddRecord(int64_t id, int64_t recordId)545 int32_t FfiOHOSPasteDataAddRecord(int64_t id, int64_t recordId)
546 {
547     LOGI("[PasteData] FfiOHOSPasteDataAddRecord start");
548     auto instance = FFIData::GetData<PasteDataImpl>(id);
549     if (!instance) {
550         LOGE("[PasteData] AddRecord: instance not exist %{public}" PRId64, id);
551         return ERR_INVALID_INSTANCE_CODE;
552     }
553 
554     PasteDataRecord rec;
555     auto recordIntance = FFIData::GetData<PasteDataRecordImpl>(recordId);
556     if (!recordIntance) {
557         LOGE("[PasteData] AddRecord: instance not exist %{public}" PRId64, recordId);
558         return ERR_INVALID_INSTANCE_CODE;
559     }
560 
561     auto pasteData = instance->GetRealPasteData();
562     if (pasteData == nullptr) {
563         LOGE("[PasteData] AddRecord: pasteData not exist");
564         return ERR_INVALID_INSTANCE_CODE;
565     }
566 
567     pasteData->AddRecord(recordIntance->GetRealPasteDataRecord());
568     LOGI("[PasteData] FfiOHOSPasteDataAddRecord success");
569 
570     return SUCCESS_CODE;
571 }
572 
FfiOHOSPasteDataAddMimeTypeRecord(int64_t id, const char *mimeType, const char *value)573 int32_t FfiOHOSPasteDataAddMimeTypeRecord(int64_t id, const char *mimeType, const char *value)
574 {
575     LOGI("[PasteData] FfiOHOSPasteDataAddMimeTypeRecord start");
576     auto instance = FFIData::GetData<PasteDataImpl>(id);
577     if (!instance) {
578         LOGE("[PasteData] AddMimeTypeRecord: instance not exist %{public}" PRId64, id);
579         return ERR_INVALID_INSTANCE_CODE;
580     }
581 
582     std::string types = mimeType;
583     std::string realValue = value;
584 
585     auto pasteData = instance->GetRealPasteData();
586     if (pasteData == nullptr) {
587         LOGE("[PasteData] AddMimeTypeRecord: pasteData not exist");
588         return ERR_INVALID_INSTANCE_CODE;
589     }
590 
591     if (types == MIMETYPE_TEXT_HTML) {
592         pasteData->AddHtmlRecord(realValue);
593     } else if (types == MIMETYPE_TEXT_PLAIN) {
594         pasteData->AddTextRecord(realValue);
595     } else {
596         pasteData->AddUriRecord(OHOS::Uri(realValue));
597     }
598     LOGI("[PasteData] FfiOHOSPasteDataAddMimeTypeRecord success");
599 
600     return SUCCESS_CODE;
601 }
602 
FfiOHOSPasteDataAddPixelMapRecord(int64_t id, const char *mimeType, int64_t pixelMapId)603 int32_t FfiOHOSPasteDataAddPixelMapRecord(int64_t id, const char *mimeType, int64_t pixelMapId)
604 {
605     LOGI("[PasteData] FfiOHOSPasteDataAddPixelMapRecord start");
606     auto instance = FFIData::GetData<PasteDataImpl>(id);
607     if (!instance) {
608         LOGE("[PasteData] AddPixelMapRecord: instance not exist %{public}" PRId64, id);
609         return ERR_INVALID_INSTANCE_CODE;
610     }
611     auto pixelMapImpl = FFIData::GetData<PixelMapImpl>(pixelMapId);
612     if (pixelMapImpl == nullptr) {
613         return ERR_INVALID_INSTANCE_CODE;
614     }
615 
616     auto pixelMap = pixelMapImpl->GetRealPixelMap();
617     if (pixelMap == nullptr) {
618         LOGE("[PasteData] AddPixelMapRecord: PixelMap not exist");
619         return ERR_INVALID_INSTANCE_CODE;
620     }
621 
622     auto pasteData = instance->GetRealPasteData();
623     if (pasteData == nullptr) {
624         LOGE("[PasteData] AddPixelMapRecord: pasteData not exist");
625         return ERR_INVALID_INSTANCE_CODE;
626     }
627 
628     pasteData->AddPixelMapRecord(pixelMap);
629     LOGI("[PasteData] FfiOHOSPasteDataAddPixelMapRecord success");
630 
631     return SUCCESS_CODE;
632 }
633 
FfiOHOSPasteDataAddArrayRecord(int64_t id, const char *mimeType, uint8_t *buffPtr, int64_t bufferSize)634 int32_t FfiOHOSPasteDataAddArrayRecord(int64_t id, const char *mimeType, uint8_t *buffPtr, int64_t bufferSize)
635 {
636     LOGI("[PasteData] FfiOHOSPasteDataAddArrayRecord start");
637     auto instance = FFIData::GetData<PasteDataImpl>(id);
638     if (!instance) {
639         LOGE("[PasteData] AddArrayRecord: instance not exist %{public}" PRId64, id);
640         return ERR_INVALID_INSTANCE_CODE;
641     }
642 
643     std::string types = mimeType;
644     void *data = buffPtr;
645     size_t dataLen = static_cast<size_t>(bufferSize);
646 
647     auto pasteData = instance->GetRealPasteData();
648     if (pasteData == nullptr) {
649         LOGE("[PasteData] AddArrayRecord: pasteData not exist");
650         return ERR_INVALID_INSTANCE_CODE;
651     }
652 
653     pasteData->AddKvRecord(
654         types, std::vector<uint8_t>(reinterpret_cast<uint8_t *>(data), reinterpret_cast<uint8_t *>(data) + dataLen));
655     LOGI("[PasteData] FfiOHOSPasteDataAddArrayRecord success");
656 
657     return SUCCESS_CODE;
658 }
659 
FfiOHOSPasteDataGetMimeTypes(int64_t id)660 RetDataCArrString FfiOHOSPasteDataGetMimeTypes(int64_t id)
661 {
662     LOGI("[PasteData] FfiOHOSPasteDataAddArrayRecord start");
663     RetDataCArrString ret = { .code = ERR_INVALID_INSTANCE_CODE, .data = { .head = nullptr, .size = 0 } };
664     auto instance = FFIData::GetData<PasteDataImpl>(id);
665     if (!instance) {
666         LOGE("[PasteData] GetMimeTypes: instance not exist %{public}" PRId64, id);
667         return ret;
668     }
669 
670     auto pasteData = instance->GetRealPasteData();
671     if (pasteData == nullptr) {
672         LOGE("[PasteData] GetMimeTypes: pasteData not exist");
673         return ret;
674     }
675 
676     std::vector<std::string> mimeTypes = pasteData->GetMimeTypes();
677     ret.data.head = VectorToCArrString(mimeTypes);
678     if (ret.data.head == nullptr) {
679         ret.code = ERR_CODE_PARAM_INVALID;
680         return ret;
681     }
682     ret.data.size = static_cast<int64_t>(mimeTypes.size());
683     ret.code = SUCCESS_CODE;
684     LOGI("[PasteData] FfiOHOSPasteDataGetMimeTypes success");
685 
686     return ret;
687 }
688 
FfiOHOSPasteDataGetRecord(int64_t id, int32_t index, CPasteDataRecord *retPtr)689 RetDataI64 FfiOHOSPasteDataGetRecord(int64_t id, int32_t index, CPasteDataRecord *retPtr)
690 {
691     LOGI("[PasteData] FfiOHOSPasteDataGetRecord start");
692     RetDataI64 ret = { .code = ERR_INVALID_INSTANCE_CODE, .data = 0 };
693     auto instance = FFIData::GetData<PasteDataImpl>(id);
694     if (!instance) {
695         LOGE("[PasteData] GetRecord: instance not exist %{public}" PRId64, id);
696         return ret;
697     }
698 
699     auto pasteData = instance->GetRealPasteData();
700     if (pasteData == nullptr) {
701         LOGE("[PasteData] GetRecord: pasteData not exist");
702         return ret;
703     }
704 
705     if ((std::size_t)index >= pasteData->GetRecordCount()) {
706         LOGI("[PasteData] FfiOHOSPasteDataRemoveRecord index out of range.");
707         ret.code = OUT_OF_RANGE;
708         return ret;
709     }
710     std::shared_ptr<PasteDataRecord> record = pasteData->GetRecordAt((std::size_t)index);
711     if (record == nullptr) {
712         LOGE("[PasteData] FfiOHOSPasteDataRemoveRecord index out of range.");
713         ret.code = OUT_OF_RANGE;
714         return ret;
715     }
716 
717     FillCPasteDataRecord(retPtr, record);
718     auto existedRecordImpl = getCjPasteDataRecordImpl(record);
719     if (existedRecordImpl != nullptr) {
720         ret.data = existedRecordImpl->GetID();
721     } else {
722         auto pasteDataRecordImpl = FFI::FFIData::Create<PasteDataRecordImpl>(record);
723         if (!pasteDataRecordImpl) {
724             return ret;
725         }
726         ret.data = pasteDataRecordImpl->GetID();
727     }
728     ret.code = SUCCESS_CODE;
729     LOGI("[PasteData] FfiOHOSPasteDataGetRecord success");
730 
731     return ret;
732 }
733 
FfiOHOSPasteDataGetRecordCount(int64_t id)734 RetDataUI FfiOHOSPasteDataGetRecordCount(int64_t id)
735 {
736     LOGI("[PasteData] FfiOHOSPasteDataGetRecordCount start");
737     RetDataUI ret = { .code = ERR_INVALID_INSTANCE_CODE, .data = 0 };
738     auto instance = FFIData::GetData<PasteDataImpl>(id);
739     if (!instance) {
740         LOGE("[PasteData] GetRecordCount: instance not exist %{public}" PRId64, id);
741         return ret;
742     }
743 
744     auto pasteData = instance->GetRealPasteData();
745     if (pasteData == nullptr) {
746         LOGE("[PasteData] GetRecordCount: pasteData not exist");
747         return ret;
748     }
749 
750     ret.data = pasteData->GetRecordCount();
751     ret.code = SUCCESS_CODE;
752     LOGI("[PasteData] FfiOHOSPasteDataGetRecordCount success");
753 
754     return ret;
755 }
756 
FfiOHOSPasteDataRemoveRecord(int64_t id, int32_t index)757 int32_t FfiOHOSPasteDataRemoveRecord(int64_t id, int32_t index)
758 {
759     LOGI("[PasteData] FfiOHOSPasteDataRemoveRecord start");
760     auto instance = FFIData::GetData<PasteDataImpl>(id);
761     if (!instance) {
762         LOGE("[PasteData] RemoveRecord: instance not exist %{public}" PRId64, id);
763         return ERR_INVALID_INSTANCE_CODE;
764     }
765 
766     auto pasteData = instance->GetRealPasteData();
767     if (pasteData == nullptr) {
768         LOGE("[PasteData] RemoveRecord: pasteData not exist");
769         return ERR_INVALID_INSTANCE_CODE;
770     }
771 
772     if ((std::size_t)index >= pasteData->GetRecordCount()) {
773         LOGI("[PasteData] FfiOHOSPasteDataRemoveRecord index out of range.");
774         return OUT_OF_RANGE;
775     }
776     std::shared_ptr<PasteDataRecord> recordImpl = pasteData->GetRecordAt((std::size_t)index);
777     if (recordImpl != nullptr) {
778         auto existedRecordImpl = getCjPasteDataRecordImpl(recordImpl);
779         if (existedRecordImpl != nullptr) {
780             FFIData::Release(existedRecordImpl->GetID());
781             removeCjPasteDataRecordImpl(recordImpl);
782         }
783         pasteData->RemoveRecordAt(index);
784     }
785 
786     LOGI("[PasteData] FfiOHOSPasteDataRemoveRecord success");
787 
788     return SUCCESS_CODE;
789 }
790 
FfiOHOSPasteDataReplaceRecord(int64_t id, int64_t recordId, int32_t index)791 int32_t FfiOHOSPasteDataReplaceRecord(int64_t id, int64_t recordId, int32_t index)
792 {
793     LOGI("[PasteData] FfiOHOSPasteDataReplaceRecord start");
794     auto instance = FFIData::GetData<PasteDataImpl>(id);
795     if (!instance) {
796         LOGE("[PasteData] ReplaceRecord: instance not exist %{public}" PRId64, id);
797         return ERR_INVALID_INSTANCE_CODE;
798     }
799 
800     auto recordInstance = FFIData::GetData<PasteDataRecordImpl>(recordId);
801     if (!recordInstance) {
802         LOGE("[PasteData] ReplaceRecord: instance not exist %{public}" PRId64, recordId);
803         return ERR_INVALID_INSTANCE_CODE;
804     }
805 
806     auto pasteData = instance->GetRealPasteData();
807     if (pasteData == nullptr) {
808         LOGE("[PasteData] ReplaceRecord: pasteData not exist");
809         return ERR_INVALID_INSTANCE_CODE;
810     }
811 
812     if ((std::size_t)index >= pasteData->GetRecordCount()) {
813         LOGI("[PasteData] FfiOHOSPasteDataReplaceRecord index out of range.");
814         return OUT_OF_RANGE;
815     }
816     std::shared_ptr<PasteDataRecord> oldRecord = pasteData->GetRecordAt((std::size_t)index);
817     if (oldRecord != nullptr) {
818         auto existedRecordImpl = getCjPasteDataRecordImpl(oldRecord);
819         if (existedRecordImpl != nullptr) {
820             FFIData::Release(existedRecordImpl->GetID());
821             removeCjPasteDataRecordImpl(oldRecord);
822         }
823     }
824 
825     std::shared_ptr<PasteDataRecord> newRecord = recordInstance->GetRealPasteDataRecord();
826     addCjPasteDataRecordImpl(newRecord, recordInstance);
827     pasteData->ReplaceRecordAt(index, newRecord);
828     LOGI("[PasteData] FfiOHOSPasteDataReplaceRecord success");
829 
830     return SUCCESS_CODE;
831 }
832 
FfiOHOSGetSystemPasteboard()833 RetDataI64 FfiOHOSGetSystemPasteboard()
834 {
835     RetDataI64 ret;
836     LOGI("[SystemPasteboard] FfiOHOSGetSystemPasteboard start");
837     ret.code = SystemPasteboardImpl::GetSystemPasteboardImpl(ret.data);
838     LOGI("[SystemPasteboard] FfiOHOSGetSystemPasteboard success");
839     return ret;
840 }
841 
FfiOHOSSystemPasteboardSetData(int64_t id, int64_t pasteDataId)842 int32_t FfiOHOSSystemPasteboardSetData(int64_t id, int64_t pasteDataId)
843 {
844     LOGI("[SystemPasteboard] FfiOHOSSystemPasteboardSetData start");
845     auto instance = FFIData::GetData<SystemPasteboardImpl>(id);
846     if (!instance) {
847         LOGE("[SystemPasteboard] SetData: instance not exist %{public}" PRId64, id);
848         return ERR_INVALID_INSTANCE_CODE;
849     }
850     auto pasteDataInstance = FFIData::GetData<PasteDataImpl>(pasteDataId);
851     if (!pasteDataInstance) {
852         LOGE("[SystemPasteboard] SetData: instance not exist %{public}" PRId64, pasteDataId);
853         return ERR_INVALID_INSTANCE_CODE;
854     }
855     auto ret = instance->SetData(pasteDataInstance, pasteDataInstance->GetRealPasteData());
856     if (ret == SUCCESS_CODE) {
857         LOGI("[PasteData] FfiOHOSSystemPasteboardSetData success");
858     }
859 
860     return SUCCESS_CODE;
861 }
862 
FfiOHOSSystemPasteboardGetData(int64_t id)863 RetDataI64 FfiOHOSSystemPasteboardGetData(int64_t id)
864 {
865     RetDataI64 ret = { .code = ERR_INVALID_INSTANCE_CODE, .data = 0 };
866     LOGI("[SystemPasteboard] FfiOHOSSystemPasteboardGetData start");
867     auto instance = FFIData::GetData<SystemPasteboardImpl>(id);
868     if (!instance) {
869         LOGE("[SystemPasteboard] GetData: instance not exist %{public}" PRId64, id);
870         return ret;
871     }
872     std::shared_ptr<MiscServices::PasteData> pasteData = std::make_shared<PasteData>();
873     int32_t res = instance->GetData(*pasteData);
874     if (res != static_cast<int32_t>(PasteboardError::E_OK)) {
875         ret.code = res;
876         return ret;
877     }
878     auto pasteDataImpl = FFIData::Create<PasteDataImpl>(pasteData);
879     if (!pasteDataImpl) {
880         return ret;
881     }
882     ret.data = pasteDataImpl->GetID();
883     ret.code = SUCCESS_CODE;
884     LOGI("[SystemPasteboard] FfiOHOSSystemPasteboardGetData success");
885     return ret;
886 }
887 
FfiOHOSSystemPasteboardHasData(int64_t id)888 RetDataBool FfiOHOSSystemPasteboardHasData(int64_t id)
889 {
890     RetDataBool ret = { .code = ERR_INVALID_INSTANCE_CODE, .data = false };
891     LOGI("[SystemPasteboard] FfiOHOSSystemPasteboardHasData start");
892     auto instance = FFIData::GetData<SystemPasteboardImpl>(id);
893     if (!instance) {
894         LOGE("[SystemPasteboard] HasData: instance not exist %{public}" PRId64, id);
895         return ret;
896     }
897 
898     ret.data = instance->HasData();
899     ret.code = SUCCESS_CODE;
900     LOGI("[SystemPasteboard] FfiOHOSSystemPasteboardHasData success");
901     return ret;
902 }
903 
FfiOHOSSystemPasteboardClearData(int64_t id)904 FFI_EXPORT void FfiOHOSSystemPasteboardClearData(int64_t id)
905 {
906     LOGI("[SystemPasteboard] FfiOHOSSystemPasteboardClearData start");
907     auto instance = FFIData::GetData<SystemPasteboardImpl>(id);
908     if (!instance) {
909         LOGE("[SystemPasteboard] ClearData: instance not exist %{public}" PRId64, id);
910         return;
911     }
912     instance->ClearData();
913 
914     LOGI("[SystemPasteboard] FfiOHOSSystemPasteboardClearData success");
915 }
916 
FfiOHOSSystemPasteboardIsRemoteData(int64_t id)917 RetDataBool FfiOHOSSystemPasteboardIsRemoteData(int64_t id)
918 {
919     RetDataBool ret = { .code = ERR_INVALID_INSTANCE_CODE, .data = false };
920     LOGI("[SystemPasteboard] FfiOHOSSystemPasteboardIsRemoteData start");
921     auto instance = FFIData::GetData<SystemPasteboardImpl>(id);
922     if (!instance) {
923         LOGE("[SystemPasteboard] IsRemoteData: instance not exist %{public}" PRId64, id);
924         return ret;
925     }
926 
927     ret.data = instance->IsRemoteData();
928     ret.code = SUCCESS_CODE;
929     LOGI("[SystemPasteboard] FfiOHOSSystemPasteboardIsRemoteData success");
930     return ret;
931 }
932 
FfiOHOSSystemPasteboardHasDataType(int64_t id, const char *mimeType)933 RetDataBool FfiOHOSSystemPasteboardHasDataType(int64_t id, const char *mimeType)
934 {
935     RetDataBool ret = { .code = ERR_INVALID_INSTANCE_CODE, .data = false };
936     LOGI("[SystemPasteboard] FfiOHOSSystemPasteboardHasDataType start");
937     auto instance = FFIData::GetData<SystemPasteboardImpl>(id);
938     if (!instance) {
939         LOGE("[SystemPasteboard] HasDataType: instance not exist %{public}" PRId64, id);
940         return ret;
941     }
942 
943     std::string types = mimeType;
944     ret.data = instance->HasDataType(types);
945     ret.code = SUCCESS_CODE;
946     LOGI("[SystemPasteboard] FfiOHOSSystemPasteboardHasDataType success");
947     return ret;
948 }
949 
FfiOHOSSystemPasteboardGetDataSource(int64_t id)950 RetDataCString FfiOHOSSystemPasteboardGetDataSource(int64_t id)
951 {
952     LOGI("[PasteData] FfiOHOSSystemPasteboardGetDataSource start");
953     RetDataCString ret = { .code = ERR_INVALID_INSTANCE_CODE, .data = nullptr };
954     auto instance = FFIData::GetData<SystemPasteboardImpl>(id);
955     if (!instance) {
956         LOGE("[SystemPasteboard] GetDataSource: instance not exist %{public}" PRId64, id);
957         return ret;
958     }
959     std::string res = instance->GetDataSource();
960     ret.data = PasteBoardMallocCString(res);
961     if (ret.data == nullptr) {
962         ret.code = ERR_CODE_PARAM_INVALID;
963         return ret;
964     }
965     ret.code = SUCCESS_CODE;
966     LOGI("[PasteData] FfiOHOSSystemPasteboardGetDataSource success");
967 
968     return ret;
969 }
970 }
971 } // namespace CJSystemapi
972 } // namespace OHOS
973