1 /*
2 * Copyright (c) 2025 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 <ani.h>
17 #include <array>
18 #include <iostream>
19 #include <map>
20 #include <unordered_map>
21 #include <memory>
22 #include <thread>
23 #include "pasteboard_error.h"
24 #include "pasteboard_hilog.h"
25 #include "pasteboard_client.h"
26 #include "pasteboard_js_err.h"
27 #include "common/block_object.h"
28 #include "ani_common_want.h"
29 #include "image_ani_utils.h"
30 #include "pasteboard_ani_utils.h"
31 #include "unified_meta.h"
32
33 using namespace OHOS::MiscServices;
34
35 constexpr size_t SYNC_TIMEOUT = 3500;
36 constexpr size_t MIMETYPE_MAX_LEN = 1024;
37
ThrowBusinessError(ani_env * env,int errCode,std::string && errMsg)38 static void ThrowBusinessError(ani_env *env, int errCode, std::string&& errMsg)
39 {
40 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "into ThrowBusinessError.");
41 if (env == nullptr) {
42 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "into ThrowBusinessError. env is null, return.");
43 return;
44 }
45 static const char *errorClsName = "L@ohos/base/BusinessError;";
46 ani_class cls {};
47 if (env->FindClass(errorClsName, &cls) != ANI_OK) {
48 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "findClass BusinessError failed.");
49 return;
50 }
51 ani_method ctor;
52 if (env->Class_FindMethod(cls, "<ctor>", ":V", &ctor) != ANI_OK) {
53 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "find method BusinessError.constructor failed.");
54 return;
55 }
56 ani_object errorObject;
57 if (env->Object_New(cls, ctor, &errorObject) != ANI_OK) {
58 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "create BusinessError object failed.");
59 return;
60 }
61 ani_double aniErrCode = static_cast<ani_double>(errCode);
62 ani_string errMsgStr;
63 if (env->String_NewUTF8(errMsg.c_str(), errMsg.size(), &errMsgStr) != ANI_OK) {
64 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "convert errMsg to ani_string failed.");
65 return;
66 }
67 if (env->Object_SetFieldByName_Double(errorObject, "code", aniErrCode) != ANI_OK) {
68 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "set error code failed.");
69 return;
70 }
71 if (env->Object_SetPropertyByName_Ref(errorObject, "message", errMsgStr) != ANI_OK) {
72 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "set error message failed.");
73 return;
74 }
75 ani_status flag = env->ThrowError(static_cast<ani_error>(errorObject));
76 if (flag != ANI_OK) {
77 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "ThrowError failed, flag: %{public}d.", flag);
78 } else {
79 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_JS_ANI, "flag: %{public}d.", flag);
80 }
81 return;
82 }
83
GetNullObject(ani_env * env)84 ani_object GetNullObject(ani_env *env)
85 {
86 if (env == nullptr) {
87 return nullptr;
88 }
89 ani_ref ref;
90 if (env->GetNull(&ref) != ANI_OK) {
91 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "env->GetNull failed.");
92 return NULL;
93 }
94 return static_cast<ani_object>(ref);
95 }
96
Create(ani_env * env,std::shared_ptr<PasteData> & ptrPasteData)97 ani_object Create([[maybe_unused]] ani_env *env, std::shared_ptr<PasteData> &ptrPasteData)
98 {
99 if (env == nullptr) {
100 return nullptr;
101 }
102 static const char *className = "L@ohos/pasteboard/PasteDataImpl;";
103 ani_class cls;
104 if (ANI_OK != env->FindClass(className, &cls)) {
105 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "create failed.");
106 return nullptr;
107 }
108
109 auto shareptrPasteData = new SharedPtrHolder<PasteData>(ptrPasteData);
110 ani_object obj = NativeObjectWrapper<SharedPtrHolder<PasteData>>::Wrap(env, cls, shareptrPasteData);
111 if (obj == nullptr) {
112 delete shareptrPasteData;
113 return nullptr;
114 }
115 return obj;
116 }
117
UnwrapAndGetPasteDataPtr(ani_env * env,ani_object object)118 PasteData* UnwrapAndGetPasteDataPtr([[maybe_unused]] ani_env *env, [[maybe_unused]] ani_object object)
119 {
120 if (env == nullptr) {
121 return nullptr;
122 }
123 auto shareptrPasteData = NativeObjectWrapper<SharedPtrHolder<PasteData>>::Unwrap(env, object);
124 if (shareptrPasteData == nullptr) {
125 return nullptr;
126 }
127 return shareptrPasteData->Get().get();
128 }
129
CreateObjectFromClass(ani_env * env,const char * className)130 ani_object CreateObjectFromClass([[maybe_unused]] ani_env *env, const char* className)
131 {
132 if (env == nullptr || className == nullptr) {
133 return nullptr;
134 }
135 ani_object obj = nullptr;
136 ani_class cls;
137 if (ANI_OK != env->FindClass(className, &cls)) {
138 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[CreateObjectFromClass] Not found class.");
139 return obj;
140 }
141 ani_method ctor;
142 if (ANI_OK != env->Class_FindMethod(cls, "<ctor>", nullptr, &ctor)) {
143 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[CreateObjectFromClass] get ctor failed.");
144 return obj;
145 }
146 if (ANI_OK != env->Object_New(cls, ctor, &obj)) {
147 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[CreateObjectFromClass] Create Object failed.");
148 return obj;
149 }
150
151 return obj;
152 }
153
GetStdStringFromUnion(ani_env * env,ani_object union_obj)154 std::string GetStdStringFromUnion([[maybe_unused]] ani_env *env, ani_object union_obj)
155 {
156 if (env == nullptr) {
157 return "";
158 }
159 UnionAccessor unionAccessor(env, union_obj);
160 ani_string str;
161 if (!unionAccessor.IsInstanceOf("Lstd/core/String;")) {
162 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[GetStdStringFromUnion] union_obj is not string!");
163 ThrowBusinessError(env, static_cast<int32_t>(JSErrorCode::INVALID_PARAMETERS),
164 "The type of mimeType must be string.");
165 return "";
166 }
167 if (!unionAccessor.TryConvert<ani_string>(str)) {
168 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI,
169 "[GetStdStringFromUnion] try to convert union object to ani_string failed!");
170 return "";
171 }
172
173 return ANIUtils_ANIStringToStdString(env, str);
174 }
175
GetArrayBuffer(ani_env * env,ani_object unionObj,std::vector<uint8_t> & vec)176 bool GetArrayBuffer([[maybe_unused]] ani_env *env, ani_object unionObj, std::vector<uint8_t> &vec)
177 {
178 if (env == nullptr) {
179 return false;
180 }
181 std::string classname("Lescompat/ArrayBuffer;");
182 bool isArrayBuffer = ANIUtils_UnionIsInstanceOf(env, unionObj, classname);
183 if (!isArrayBuffer) {
184 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI,
185 "[getArrayBuffer] Failed: is not arraybuffer.");
186 return false;
187 }
188
189 void* data;
190 size_t length;
191 if (ANI_OK != env->ArrayBuffer_GetInfo(static_cast<ani_arraybuffer>(unionObj), &data, &length)) {
192 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI,
193 "[getArrayBuffer] Failed: env->ArrayBuffer_GetInfo().");
194 return false;
195 }
196
197 auto pVal = static_cast<uint8_t*>(data);
198 vec.assign(pVal, pVal + length);
199
200 return true;
201 }
202
CheckMimeType(ani_env * env,std::string & mimeType)203 bool CheckMimeType(ani_env *env, std::string &mimeType)
204 {
205 if (env == nullptr) {
206 return false;
207 }
208 if (mimeType.size() == 0) {
209 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "The length of mimeType is 0.");
210 ThrowBusinessError(env, static_cast<int32_t>(JSErrorCode::INVALID_PARAMETERS),
211 "The length of mimeType is 0.");
212 return false;
213 }
214
215 if (mimeType.size() > MIMETYPE_MAX_LEN) {
216 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI,
217 "The length of mimeType cannot be greater than 1024 bytes.");
218 ThrowBusinessError(env, static_cast<int32_t>(JSErrorCode::INVALID_PARAMETERS),
219 "The length of mimeType cannot be greater than 1024 bytes.");
220 return false;
221 }
222
223 return true;
224 }
225
GetEnumItem(ani_env * env,ani_int shareOption)226 static ani_enum_item GetEnumItem(ani_env *env, ani_int shareOption)
227 {
228 if (env == nullptr) {
229 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[GetEnumItem] env is null.");
230 return nullptr;
231 }
232 ani_namespace ns;
233 const char *nameSpaceName = "L@ohos/pasteboard/pasteboard;";
234 if (ANI_OK != env->FindNamespace(nameSpaceName, &ns)) {
235 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[GetEnumItem] Not found namespace: %{public}s", nameSpaceName);
236 return nullptr;
237 }
238
239 ani_enum enumType;
240 const char *enumName = "LShareOption;";
241 if (ANI_OK != env->Namespace_FindEnum(ns, enumName, &enumType)) {
242 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[GetEnumItem] Find Enum failed: %{public}s", enumName);
243 return nullptr;
244 }
245
246 ani_enum_item enumItem;
247 if (ANI_OK != env->Enum_GetEnumItemByIndex(enumType, shareOption, &enumItem)) {
248 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[GetEnumItem] Enum_GetEnumItemByIndex failed.");
249 return nullptr;
250 }
251
252 return enumItem;
253 }
254
GetRecordCount(ani_env * env,ani_object object)255 static ani_double GetRecordCount([[maybe_unused]] ani_env *env, [[maybe_unused]] ani_object object)
256 {
257 if (env == nullptr) {
258 return 0;
259 }
260 PasteData* pPasteData = UnwrapAndGetPasteDataPtr(env, object);
261 if (pPasteData == nullptr) {
262 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[GetRecordCount] pPasteData is null.");
263 return 0;
264 }
265
266 return pPasteData->GetRecordCount();
267 }
268
AddRecordByPasteDataRecord(ani_env * env,ani_object object,ani_object record)269 static void AddRecordByPasteDataRecord([[maybe_unused]] ani_env *env, [[maybe_unused]] ani_object object,
270 ani_object record)
271 {
272 if (env == nullptr) {
273 return;
274 }
275 ani_ref uri;
276 if (ANI_OK != env->Object_GetPropertyByName_Ref(static_cast<ani_object>(record), "uri", &uri)) {
277 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[AddRecord] Object_GetPropertyByName_Ref failed.");
278 return;
279 }
280
281 auto uri_str = ANIUtils_ANIStringToStdString(env, static_cast<ani_string>(uri));
282
283 PasteData* pPasteData = UnwrapAndGetPasteDataPtr(env, object);
284 if (pPasteData == nullptr) {
285 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[AddRecord] pPasteData is null.");
286 return;
287 }
288
289 PasteDataRecord::Builder builder("");
290 builder.SetUri(std::make_shared<OHOS::Uri>(OHOS::Uri(uri_str)));
291 std::shared_ptr<PasteDataRecord> result = builder.Build();
292 if (result == nullptr) {
293 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[AddRecord] result is null.");
294 return;
295 }
296 pPasteData->AddRecord(*(result.get()));
297 }
298
ProcessStrValueOfRecord(ani_env * env,ani_object union_obj,std::string mimeType,PasteData * pPasteData)299 static void ProcessStrValueOfRecord([[maybe_unused]] ani_env *env, ani_object union_obj, std::string mimeType,
300 PasteData *pPasteData)
301 {
302 if (env == nullptr) {
303 return;
304 }
305 if (pPasteData == nullptr) {
306 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI,
307 "[ProcessStrValueOfRecord] pPasteData is null.");
308 return;
309 }
310
311 auto value_str = GetStdStringFromUnion(env, union_obj);
312 if (mimeType == MIMETYPE_TEXT_HTML) {
313 pPasteData->AddHtmlRecord(value_str);
314 } else if (mimeType == MIMETYPE_TEXT_PLAIN) {
315 pPasteData->AddTextRecord(value_str);
316 } else {
317 pPasteData->AddUriRecord(OHOS::Uri(value_str));
318 }
319 }
320
AddRecordByTypeValue(ani_env * env,ani_object object,ani_string type,ani_object union_obj)321 static void AddRecordByTypeValue([[maybe_unused]] ani_env *env, [[maybe_unused]] ani_object object,
322 ani_string type, ani_object union_obj)
323 {
324 if (env == nullptr) {
325 return;
326 }
327 auto mimeType = ANIUtils_ANIStringToStdString(env, static_cast<ani_string>(type));
328 if (!CheckMimeType(env, mimeType)) {
329 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI,
330 "[AddRecordByTypeValue] minetype length is error. %{public}s", mimeType.c_str());
331 return;
332 }
333
334 PasteData* pPasteData = UnwrapAndGetPasteDataPtr(env, object);
335 if (pPasteData == nullptr) {
336 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[AddRecordByTypeValue] pPasteData is null.");
337 return;
338 }
339
340 if (mimeType == MIMETYPE_PIXELMAP) {
341 OHOS::Media::PixelMap* rawPixelMap = OHOS::Media::ImageAniUtils::GetPixelMapFromEnv(env, union_obj);
342 if (rawPixelMap == nullptr) {
343 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[AddRecordByTypeValue] GetPixelMapFromEnv failed.");
344 return;
345 }
346 auto pixelMap = std::shared_ptr<OHOS::Media::PixelMap>(rawPixelMap);
347 pPasteData->AddPixelMapRecord(pixelMap);
348 return;
349 } else if (mimeType == MIMETYPE_TEXT_WANT) {
350 OHOS::AAFwk::Want want;
351 if (!OHOS::AppExecFwk::UnwrapWant(env, union_obj, want)) {
352 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[AddRecordByTypeValue] UnwrapWant failed.");
353 return;
354 }
355 pPasteData->AddWantRecord(std::make_shared<OHOS::AAFwk::Want>(want));
356 return;
357 }
358
359 if (mimeType == MIMETYPE_TEXT_HTML || mimeType == MIMETYPE_TEXT_PLAIN || mimeType == MIMETYPE_TEXT_URI) {
360 ProcessStrValueOfRecord(env, union_obj, mimeType, pPasteData);
361 return;
362 }
363
364 std::vector<uint8_t> vec;
365 vec.clear();
366 if (!GetArrayBuffer(env, union_obj, vec)) {
367 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[AddRecordByTypeValue] getArrayBuffer failed.");
368 return;
369 }
370 pPasteData->AddKvRecord(mimeType, vec);
371
372 return;
373 }
374
SetNamedPropertyByStr(ani_env * env,ani_class cls,const char * propertyName,std::string propertyValue,ani_object & obj)375 static void SetNamedPropertyByStr(ani_env *env, ani_class cls, const char *propertyName, std::string propertyValue,
376 ani_object &obj)
377 {
378 if (env == nullptr || propertyName == nullptr) {
379 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[SetNamedPropertyByStr] env or propertyName is null.");
380 return;
381 }
382 ani_string propertyAniStr = {};
383 env->String_NewUTF8(propertyValue.c_str(), propertyValue.length(), &propertyAniStr);
384
385 ani_method propertySetter;
386 if (ANI_OK != env->Class_FindMethod(cls, propertyName, nullptr, &propertySetter)) {
387 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI,
388 "[SetNamedPropertyByStr] Class_FindMethod failed: %{public}s.", propertyName);
389 return;
390 }
391 if (ANI_OK != env->Object_CallMethod_Void(obj, propertySetter, propertyAniStr)) {
392 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI,
393 "[SetNamedPropertyByStr] Object_CallMethod_Void failed: %{public}s.", propertyName);
394 return;
395 }
396 }
397
FillPasteDataRecordObject(ani_env * env,std::shared_ptr<PasteDataRecord> recordFromBottom,ani_object & obj)398 static void FillPasteDataRecordObject(ani_env *env, std::shared_ptr<PasteDataRecord> recordFromBottom, ani_object &obj)
399 {
400 if (env == nullptr || recordFromBottom == nullptr) {
401 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[FillPasteDataRecordObject] env or recordFromBottom is null.");
402 return;
403 }
404
405 ani_class cls;
406 if (ANI_OK != env->FindClass("L@ohos/pasteboard/PasteDataRecordImpl;", &cls)) {
407 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[FillPasteDataRecordObject] Not found class.");
408 return;
409 }
410
411 auto mimeType = recordFromBottom->GetMimeType();
412 SetNamedPropertyByStr(env, cls, "<set>mimeType", mimeType, obj);
413
414 auto plainTextPtr = recordFromBottom->GetPlainTextV0();
415 if (plainTextPtr != nullptr) {
416 SetNamedPropertyByStr(env, cls, "<set>plainText", *plainTextPtr.get(), obj);
417 }
418
419 auto uriPtr = recordFromBottom->GetUriV0();
420 if (uriPtr != nullptr) {
421 SetNamedPropertyByStr(env, cls, "<set>uri", uriPtr->ToString(), obj);
422 }
423 }
424
GetRecord(ani_env * env,ani_object object,ani_double index)425 static ani_object GetRecord([[maybe_unused]] ani_env *env, [[maybe_unused]] ani_object object,
426 [[maybe_unused]] ani_double index)
427 {
428 if (env == nullptr) {
429 return nullptr;
430 }
431 PasteData* pPasteData = UnwrapAndGetPasteDataPtr(env, object);
432 if (pPasteData == nullptr) {
433 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[GetRecord] pPasteData is null.");
434 return GetNullObject(env);
435 }
436
437 if (index >= pPasteData->GetRecordCount() || index < 0) {
438 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[GetRecord] index is out of range.");
439 ThrowBusinessError(env, static_cast<int32_t>(JSErrorCode::OUT_OF_RANGE),
440 "index out of range.");
441 return GetNullObject(env);
442 }
443
444 std::shared_ptr<PasteDataRecord> recordFromBottom = pPasteData->GetRecordAt(static_cast<std::size_t>(index));
445 if (recordFromBottom == nullptr) {
446 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[GetRecord] recordFromBottom is null.");
447 return GetNullObject(env);
448 }
449
450 ani_object record = CreateObjectFromClass(env, "L@ohos/pasteboard/PasteDataRecordImpl;");
451 if (record == nullptr) {
452 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[GetRecord] CreateObjectFromClass failed.");
453 return GetNullObject(env);
454 }
455 FillPasteDataRecordObject(env, recordFromBottom, record);
456
457 return record;
458 }
459
SetProperty(ani_env * env,ani_object object,ani_object property)460 static void SetProperty([[maybe_unused]] ani_env *env, [[maybe_unused]] ani_object object, ani_object property)
461 {
462 if (env == nullptr) {
463 return;
464 }
465 PasteData* pPasteData = UnwrapAndGetPasteDataPtr(env, object);
466 if (pPasteData == nullptr) {
467 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[SetProperty] pPasteData is null.");
468 return;
469 }
470
471 ani_ref shareOption;
472 if (ANI_OK != env->Object_GetPropertyByName_Ref(static_cast<ani_object>(property), "shareOption", &shareOption)) {
473 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[SetProperty] Object_GetPropertyByName_Ref failed.");
474 return;
475 }
476 ani_int shareOptionValue;
477 if (ANI_OK != env->EnumItem_GetValue_Int(static_cast<ani_enum_item>(shareOption), &shareOptionValue)) {
478 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[SetProperty] EnumItem_GetValue_Int failed.");
479 return;
480 }
481 ani_int localOnlyValue = shareOptionValue == ShareOption::CrossDevice ? false : true;
482 pPasteData->SetLocalOnly(localOnlyValue);
483 pPasteData->SetShareOption(static_cast<ShareOption>(shareOptionValue));
484
485 ani_ref tag;
486 if (ANI_OK != env->Object_GetPropertyByName_Ref(static_cast<ani_object>(property), "tag", &tag)) {
487 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[SetProperty] Object_GetPropertyByName_Ref failed.");
488 return;
489 }
490 auto tag_str = ANIUtils_ANIStringToStdString(env, static_cast<ani_string>(tag));
491 pPasteData->SetTag(tag_str);
492
493 return;
494 }
495
SetNamedPropertyByEnumInt(ani_env * env,ani_class cls,const char * propertyName,ani_int shareOpionValue,ani_object & obj)496 static void SetNamedPropertyByEnumInt(ani_env *env, ani_class cls, const char *propertyName, ani_int shareOpionValue,
497 ani_object &obj)
498 {
499 if (env == nullptr || propertyName == nullptr) {
500 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[SetNamedPropertyByEnumInt] env or propertyName is null.");
501 return;
502 }
503 ani_enum_item enumItem = GetEnumItem(env, shareOpionValue);
504 if (enumItem == nullptr) {
505 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[SetNamedPropertyByEnumInt] Class_FindMethod failed.");
506 return;
507 }
508 ani_method shareOptionSetter;
509 if (ANI_OK != env->Class_FindMethod(cls, propertyName, nullptr, &shareOptionSetter)) {
510 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[SetNamedPropertyByEnumInt] Class_FindMethod failed.");
511 return;
512 }
513 if (ANI_OK != env->Object_CallMethod_Void(obj, shareOptionSetter, enumItem)) {
514 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[SetNamedPropertyByEnumInt] Object_CallMethod_Void failed.");
515 return;
516 }
517 }
518
FillPasteDataPropertyObject(ani_env * env,PasteDataProperty & property,ani_object & obj)519 static void FillPasteDataPropertyObject(ani_env *env, PasteDataProperty &property, ani_object &obj)
520 {
521 if (env == nullptr) {
522 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[FillPasteDataPropertyObject] env is null.");
523 return;
524 }
525
526 ani_class cls;
527 if (ANI_OK != env->FindClass("L@ohos/pasteboard/PasteDataPropertyImpl;", &cls)) {
528 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[FillPasteDataPropertyObject] Not found class.");
529 return;
530 }
531
532 ani_int shareOpionValue = property.shareOption;
533 SetNamedPropertyByEnumInt(env, cls, "<set>shareOption", shareOpionValue, obj);
534 SetNamedPropertyByStr(env, cls, "<set>tag", property.tag, obj);
535
536 ani_double timestampValue = property.timestamp;
537 ani_method timestampSetter;
538 if (ANI_OK != env->Class_FindMethod(cls, "<set>timestamp", nullptr, ×tampSetter)) {
539 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[FillPasteDataPropertyObject] Class_FindMethod failed.");
540 return;
541 }
542 if (ANI_OK != env->Object_CallMethod_Void(obj, timestampSetter, timestampValue)) {
543 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[FillPasteDataPropertyObject] Object_CallMethod_Void failed.");
544 return;
545 }
546 }
547
GetProperty(ani_env * env,ani_object object)548 static ani_object GetProperty([[maybe_unused]] ani_env *env, [[maybe_unused]] ani_object object)
549 {
550 if (env == nullptr) {
551 return nullptr;
552 }
553 PasteData* pPasteData = UnwrapAndGetPasteDataPtr(env, object);
554 if (pPasteData == nullptr) {
555 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[GetProperty] pPasteData is null.");
556 return GetNullObject(env);
557 }
558
559 PasteDataProperty property = pPasteData->GetProperty();
560
561 ani_object propertyToAbove = CreateObjectFromClass(env, "L@ohos/pasteboard/PasteDataPropertyImpl;");
562 if (propertyToAbove == nullptr) {
563 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[GetProperty] CreateObjectFromClass failed.");
564 return GetNullObject(env);
565 }
566 FillPasteDataPropertyObject(env, property, propertyToAbove);
567
568 return propertyToAbove;
569 }
570
CreateHtmlData(ani_env * env,ani_object union_obj)571 static ani_object CreateHtmlData([[maybe_unused]] ani_env *env, ani_object union_obj)
572 {
573 if (env == nullptr) {
574 return nullptr;
575 }
576 auto value_str = GetStdStringFromUnion(env, union_obj);
577 auto ptr = PasteboardClient::GetInstance()->CreateHtmlData(value_str);
578 if (ptr == nullptr) {
579 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[CreateHtmlData] CreateHtmlData failed.");
580 return GetNullObject(env);
581 }
582 ani_object PasteDataImpl = Create(env, ptr);
583
584 return PasteDataImpl;
585 }
586
CreatePlainTextData(ani_env * env,ani_object union_obj)587 static ani_object CreatePlainTextData([[maybe_unused]] ani_env *env, ani_object union_obj)
588 {
589 if (env == nullptr) {
590 return nullptr;
591 }
592 auto value_str = GetStdStringFromUnion(env, union_obj);
593 auto ptr = PasteboardClient::GetInstance()->CreatePlainTextData(value_str);
594 if (ptr == nullptr) {
595 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[CreatePlainTextData] CreatePlainTextData failed.");
596 return GetNullObject(env);
597 }
598 ani_object PasteDataImpl = Create(env, ptr);
599
600 return PasteDataImpl;
601 }
602
CreateUriData(ani_env * env,ani_object union_obj)603 static ani_object CreateUriData([[maybe_unused]] ani_env *env, ani_object union_obj)
604 {
605 if (env == nullptr) {
606 return nullptr;
607 }
608 auto value_str = GetStdStringFromUnion(env, union_obj);
609 auto ptr = PasteboardClient::GetInstance()->CreateUriData(OHOS::Uri(value_str));
610 if (ptr == nullptr) {
611 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[CreateUriData] CreateUriData failed.");
612 return GetNullObject(env);
613 }
614 ani_object PasteDataImpl = Create(env, ptr);
615
616 return PasteDataImpl;
617 }
618
CreatePixelMapData(ani_env * env,ani_object union_obj)619 static ani_object CreatePixelMapData([[maybe_unused]] ani_env *env, ani_object union_obj)
620 {
621 if (env == nullptr) {
622 return nullptr;
623 }
624 OHOS::Media::PixelMap* rawPixelMap = OHOS::Media::ImageAniUtils::GetPixelMapFromEnv(env, union_obj);
625 if (rawPixelMap == nullptr) {
626 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[CreatePixelMapData] GetPixelMapFromEnv failed.");
627 return GetNullObject(env);
628 }
629
630 auto pixelMap = std::shared_ptr<OHOS::Media::PixelMap>(rawPixelMap);
631 auto ptr = PasteboardClient::GetInstance()->CreatePixelMapData(pixelMap);
632 if (ptr == nullptr) {
633 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[CreatePixelMapData] CreatePixelMapData failed.");
634 return GetNullObject(env);
635 }
636 ani_object PasteDataImpl = Create(env, ptr);
637
638 return PasteDataImpl;
639 }
640
CreateWantData(ani_env * env,ani_object union_obj)641 static ani_object CreateWantData([[maybe_unused]] ani_env *env, ani_object union_obj)
642 {
643 if (env == nullptr) {
644 return nullptr;
645 }
646 OHOS::AAFwk::Want want;
647 bool ret = OHOS::AppExecFwk::UnwrapWant(env, union_obj, want);
648 if (!ret) {
649 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[CreateWantData] UnwrapWant failed.");
650 return GetNullObject(env);
651 }
652
653 auto ptr = PasteboardClient::GetInstance()->CreateWantData(std::make_shared<OHOS::AAFwk::Want>(want));
654 if (ptr == nullptr) {
655 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[CreateWantData] CreateWantData failed.");
656 return GetNullObject(env);
657 }
658 ani_object PasteDataImpl = Create(env, ptr);
659
660 return PasteDataImpl;
661 }
662
ProcessSpecialMimeType(ani_env * env,ani_object union_obj,std::string type)663 ani_object ProcessSpecialMimeType([[maybe_unused]] ani_env *env, ani_object union_obj, std::string type)
664 {
665 if (env == nullptr) {
666 return nullptr;
667 }
668 if (type == "text/html") {
669 return CreateHtmlData(env, union_obj);
670 } else if (type == "text/plain") {
671 return CreatePlainTextData(env, union_obj);
672 } else if (type == "text/uri") {
673 return CreateUriData(env, union_obj);
674 } else if (type == "pixelMap") {
675 return CreatePixelMapData(env, union_obj);
676 } else if (type == "text/want") {
677 return CreateWantData(env, union_obj);
678 }
679
680 return nullptr;
681 }
682
CreateDataTypeValue(ani_env * env,ani_string type,ani_object union_obj)683 static ani_object CreateDataTypeValue([[maybe_unused]] ani_env *env, ani_string type, ani_object union_obj)
684 {
685 if (env == nullptr) {
686 return nullptr;
687 }
688 auto type_str = ANIUtils_ANIStringToStdString(env, static_cast<ani_string>(type));
689 if (!CheckMimeType(env, type_str)) {
690 return GetNullObject(env);
691 }
692 if (type_str == "text/html" || type_str == "text/plain" ||
693 type_str == "text/uri" || type_str == "pixelMap" || type_str == "text/want") {
694 return ProcessSpecialMimeType(env, union_obj, type_str);
695 }
696
697 std::string classname("Lescompat/ArrayBuffer;");
698 bool isArrayBuffer = ANIUtils_UnionIsInstanceOf(env, union_obj, classname);
699 if (!isArrayBuffer) {
700 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[CreateDataTypeValue] not ArrayBuffer.");
701 return GetNullObject(env);
702 }
703
704 void* data;
705 size_t length;
706 if (ANI_OK != env->ArrayBuffer_GetInfo(static_cast<ani_arraybuffer>(union_obj), &data, &length)) {
707 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI,
708 "[CreateDataTypeValue] Failed: env->ArrayBuffer_GetInfo().");
709 return GetNullObject(env);
710 }
711
712 auto pVal = static_cast<uint8_t*>(data);
713 std::vector<uint8_t> vec(pVal, pVal + length);
714
715 auto ptr = PasteboardClient::GetInstance()->CreateKvData(type_str, vec);
716 if (ptr == nullptr) {
717 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[CreateDataTypeValue] CreateKvData failed.");
718 return GetNullObject(env);
719 }
720 ani_object PasteDataImpl = Create(env, ptr);
721
722 return PasteDataImpl;
723 }
724
ParsekeyValAndProcess(ani_env * env,ani_ref key_value,ani_object value_obj,std::shared_ptr<std::vector<std::pair<std::string,std::shared_ptr<EntryValue>>>> result)725 bool ParsekeyValAndProcess([[maybe_unused]] ani_env *env, ani_ref key_value, ani_object value_obj,
726 std::shared_ptr<std::vector<std::pair<std::string, std::shared_ptr<EntryValue>>>> result)
727 {
728 if (env == nullptr) {
729 return false;
730 }
731 std::string keyStr = ANIUtils_ANIStringToStdString(env, static_cast<ani_string>(key_value));
732 if (!CheckMimeType(env, keyStr)) {
733 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI,
734 "[ParsekeyValAndProcess] keyStr is empty or length is more than 1024 bytes.");
735 return false;
736 }
737
738 std::shared_ptr<EntryValue> entryValue = std::make_shared<EntryValue>();
739 std::vector<uint8_t> vec;
740 vec.clear();
741 if (GetArrayBuffer(env, value_obj, vec)) {
742 *entryValue = std::vector<uint8_t>(vec.begin(), vec.end());
743 result->emplace_back(std::make_pair(keyStr, entryValue));
744 return true;
745 }
746
747 if (keyStr == "pixelMap") {
748 OHOS::Media::PixelMap* rawPixelMap = OHOS::Media::ImageAniUtils::GetPixelMapFromEnv(env, value_obj);
749 if (rawPixelMap == nullptr) {
750 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[ParsekeyValAndProcess] GetPixelMapFromEnv failed.");
751 return false;
752 }
753 *entryValue = std::shared_ptr<OHOS::Media::PixelMap>(rawPixelMap);
754 } else if (keyStr == "text/want") {
755 OHOS::AAFwk::Want want;
756 if (!OHOS::AppExecFwk::UnwrapWant(env, value_obj, want)) {
757 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[ParsekeyValAndProcess] UnwrapWant failed.");
758 return false;
759 }
760 *entryValue = std::make_shared<OHOS::AAFwk::Want>(want);
761 } else {
762 auto value_str = GetStdStringFromUnion(env, value_obj);
763 if (value_str.length() == 0) {
764 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[ParsekeyValAndProcess] value_str is null.");
765 return false;
766 }
767 *entryValue = value_str;
768 }
769
770 result->emplace_back(std::make_pair(keyStr, entryValue));
771
772 return true;
773 }
774
ForEachMapEntry(ani_env * env,ani_object map_object,std::shared_ptr<std::vector<std::pair<std::string,std::shared_ptr<EntryValue>>>> typeValueVector)775 bool ForEachMapEntry(ani_env *env, ani_object map_object,
776 std::shared_ptr<std::vector<std::pair<std::string, std::shared_ptr<EntryValue>>>> typeValueVector)
777 {
778 if (env == nullptr) {
779 return false;
780 }
781 ani_ref keys;
782 if (ANI_OK != env->Object_CallMethodByName_Ref(map_object, "keys", ":Lescompat/IterableIterator;", &keys)) {
783 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[forEachMapEntry] Failed to get keys iterator.");
784 return false;
785 }
786
787 bool success = true;
788 while (success) {
789 ani_ref next;
790 ani_boolean done = false;
791 if (ANI_OK != env->Object_CallMethodByName_Ref(
792 static_cast<ani_object>(keys), "next", nullptr, &next)) {
793 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[forEachMapEntry] Failed to get next key.");
794 success = false;
795 break;
796 }
797
798 if (ANI_OK != env->Object_GetFieldByName_Boolean(
799 static_cast<ani_object>(next), "done", &done)) {
800 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[forEachMapEntry] Failed to check iterator done.");
801 success = false;
802 break;
803 }
804 if (done) {
805 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_JS_ANI, "[forEachMapEntry] done break.");
806 break;
807 }
808
809 ani_ref key_value;
810 if (ANI_OK != env->Object_GetFieldByName_Ref(static_cast<ani_object>(next),
811 "value", &key_value)) {
812 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[forEachMapEntry] Failed to get key value.");
813 success = false;
814 break;
815 }
816
817 ani_ref value_obj;
818 if (ANI_OK != env->Object_CallMethodByName_Ref(map_object, "$_get", nullptr,
819 &value_obj, key_value)) {
820 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_NAPI, "[forEachMapEntry] Failed to get value for key.");
821 success = false;
822 break;
823 }
824 ParsekeyValAndProcess(env, key_value, static_cast<ani_object>(value_obj), typeValueVector);
825 }
826 return success;
827 }
828
CreateDataRecord(ani_env * env,ani_object map_object)829 static ani_object CreateDataRecord([[maybe_unused]] ani_env *env, ani_object map_object)
830 {
831 if (env == nullptr) {
832 return nullptr;
833 }
834 std::shared_ptr<std::vector<std::pair<std::string, std::shared_ptr<EntryValue>>>> typeValueVector =
835 std::make_shared<std::vector<std::pair<std::string, std::shared_ptr<EntryValue>>>>();
836 ForEachMapEntry(env, map_object, typeValueVector);
837 if (typeValueVector == nullptr || typeValueVector->empty()) {
838 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[CreateDataRecord] typeValueVector is null or empty.");
839 return GetNullObject(env);
840 }
841
842 std::shared_ptr<std::map<std::string, std::shared_ptr<EntryValue>>> typeValueMap =
843 std::make_shared<std::map<std::string, std::shared_ptr<EntryValue>>>();
844 for (const auto &item : *typeValueVector) {
845 typeValueMap->emplace(item.first, item.second);
846 }
847 auto ptr = PasteboardClient::GetInstance()->CreateMultiTypeData(std::move(typeValueMap),
848 typeValueVector->begin()->first);
849 if (ptr == nullptr) {
850 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[CreateDataRecord] CreateMultiTypeData failed.");
851 return GetNullObject(env);
852 }
853
854 ani_object PasteDataImpl = Create(env, ptr);
855 return PasteDataImpl;
856 }
857
GetSystemPasteboard(ani_env * env)858 static ani_object GetSystemPasteboard([[maybe_unused]] ani_env *env)
859 {
860 if (env == nullptr) {
861 return nullptr;
862 }
863 ani_object systemPasteboard = nullptr;
864 static const char *className = "L@ohos/pasteboard/SystemPasteboardImpl;";
865 ani_class cls;
866 if (ANI_OK != env->FindClass(className, &cls)) {
867 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[GetSystemPasteboard] Not found classname.");
868 return systemPasteboard;
869 }
870
871 ani_method ctor;
872 if (ANI_OK != env->Class_FindMethod(cls, "<ctor>", nullptr, &ctor)) {
873 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[GetSystemPasteboard] get ctor failed.");
874 return systemPasteboard;
875 }
876
877 if (ANI_OK != env->Object_New(cls, ctor, &systemPasteboard)) {
878 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[GetSystemPasteboard] Create Object failed.");
879 return systemPasteboard;
880 }
881
882 return systemPasteboard;
883 }
884
HasDataType(ani_env * env,ani_object object,ani_string mimeType)885 static ani_boolean HasDataType([[maybe_unused]] ani_env *env, [[maybe_unused]] ani_object object, ani_string mimeType)
886 {
887 if (env == nullptr) {
888 return false;
889 }
890 auto mimeType_str = ANIUtils_ANIStringToStdString(env, static_cast<ani_string>(mimeType));
891
892 auto block = std::make_shared<OHOS::BlockObject<std::shared_ptr<int>>>(SYNC_TIMEOUT);
893 std::thread thread([block, mimeType_str]() {
894 auto ret = PasteboardClient::GetInstance()->HasDataType(mimeType_str);
895 std::shared_ptr<int> value = std::make_shared<int>(static_cast<int>(ret));
896 block->SetValue(value);
897 });
898 thread.detach();
899 auto value = block->GetValue();
900 if (value == nullptr) {
901 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[HasDataType] time out. ");
902 ThrowBusinessError(env, static_cast<int32_t>(JSErrorCode::REQUEST_TIME_OUT), "request timed out.");
903 return false;
904 }
905
906 return *value;
907 }
908
SetData(ani_env * env,ani_object object,ani_object pasteData)909 static ani_int SetData([[maybe_unused]] ani_env *env, [[maybe_unused]] ani_object object, ani_object pasteData)
910 {
911 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_ANI, "SetData is called!");
912 int32_t ret = static_cast<int32_t>(PasteboardError::INVALID_DATA_ERROR);
913 auto data = UnwrapAndGetPasteDataPtr(env, pasteData);
914 if (data == nullptr) {
915 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "PasteData is null.");
916 return ret;
917 }
918
919 std::map<uint32_t, std::shared_ptr<OHOS::UDMF::EntryGetter>> entryGetters;
920 for (auto record : data->AllRecords()) {
921 if (record != nullptr && record->GetEntryGetter() != nullptr) {
922 entryGetters.emplace(record->GetRecordId(), record->GetEntryGetter());
923 }
924 }
925 ret = PasteboardClient::GetInstance()->SetPasteData(*data, nullptr, entryGetters);
926 if (ret == static_cast<int>(PasteboardError::E_OK)) {
927 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_JS_ANI, "SetPasteData successfully.");
928 } else if (ret == static_cast<int>(PasteboardError::PROHIBIT_COPY)) {
929 ThrowBusinessError(env, static_cast<int32_t>(PasteboardError::PROHIBIT_COPY),
930 "The system prohibits copying.");
931 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "The system prohibits copying.");
932 } else if (ret == static_cast<int>(PasteboardError::TASK_PROCESSING)) {
933 ThrowBusinessError(env, static_cast<int32_t>(PasteboardError::TASK_PROCESSING),
934 "Another setData is being processed.");
935 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "Another setData is being processed.");
936 }
937
938 return ret;
939 }
940
ClearData(ani_env * env)941 static void ClearData([[maybe_unused]] ani_env *env)
942 {
943 PasteboardClient::GetInstance()->Clear();
944 }
945
GetDataSync(ani_env * env,ani_object object)946 static ani_object GetDataSync([[maybe_unused]] ani_env *env, [[maybe_unused]] ani_object object)
947 {
948 if (env == nullptr) {
949 return nullptr;
950 }
951 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_ANI, "GetDataSync called.");
952 auto pasteData = std::make_shared<PasteData>();
953 auto block = std::make_shared<OHOS::BlockObject<std::shared_ptr<int32_t>>>(SYNC_TIMEOUT);
954 std::thread thread([block, pasteData]() mutable {
955 auto ret = PasteboardClient::GetInstance()->GetPasteData(*pasteData);
956 std::shared_ptr<int32_t> value = std::make_shared<int32_t>(ret);
957 block->SetValue(value);
958 });
959 thread.detach();
960 auto value = block->GetValue();
961 if (value == nullptr) {
962 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "time out, GetDataSync failed.");
963 ThrowBusinessError(env, static_cast<int32_t>(JSErrorCode::REQUEST_TIME_OUT), "request timed out.");
964 return GetNullObject(env);
965 }
966 ani_object pasteDataObj = Create(env, pasteData);
967
968 return pasteDataObj;
969 }
970
GetDataSource(ani_env * env,ani_object object)971 static ani_string GetDataSource([[maybe_unused]] ani_env *env, [[maybe_unused]] ani_object object)
972 {
973 if (env == nullptr) {
974 return nullptr;
975 }
976 std::string bundleName;
977 auto block = std::make_shared<OHOS::BlockObject<std::shared_ptr<int>>>(SYNC_TIMEOUT);
978 std::thread thread([block, &bundleName]() mutable {
979 auto ret = PasteboardClient::GetInstance()->GetDataSource(bundleName);
980 std::shared_ptr<int> value = std::make_shared<int>(ret);
981 block->SetValue(value);
982 });
983 thread.detach();
984
985 auto value = block->GetValue();
986 if (value == nullptr) {
987 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "time out, GetDataSource failed.");
988 ThrowBusinessError(env, static_cast<int32_t>(JSErrorCode::REQUEST_TIME_OUT), "request timed out.");
989 return nullptr;
990 }
991
992 if (*value != static_cast<int>(PasteboardError::E_OK)) {
993 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "GetDataSource, failed, ret = %{public}d.", *value);
994 return nullptr;
995 }
996
997 ani_string aniStr = nullptr;
998 if (ANI_OK != env->String_NewUTF8(bundleName.data(), bundleName.size(), &aniStr)) {
999 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "Unsupported ANI_VERSION_1");
1000 return nullptr;
1001 }
1002
1003 return aniStr;
1004 }
1005
ANI_Constructor_Namespace(ani_env * env)1006 ANI_EXPORT ani_status ANI_Constructor_Namespace(ani_env *env)
1007 {
1008 if (env == nullptr) {
1009 return ANI_ERROR;
1010 }
1011 ani_namespace ns;
1012 static const char *nameSpaceName = "L@ohos/pasteboard/pasteboard;";
1013 if (ANI_OK != env->FindNamespace(nameSpaceName, &ns)) {
1014 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI,
1015 "[ANI_Constructor_Namespace] Not found namespace: %s", nameSpaceName);
1016 return ANI_NOT_FOUND;
1017 }
1018
1019 std::array methods = {
1020 ani_native_function {"createDataTypeValue", nullptr, reinterpret_cast<void *>(CreateDataTypeValue)},
1021 ani_native_function {"createDataRecord", nullptr, reinterpret_cast<void *>(CreateDataRecord)},
1022 ani_native_function {"getSystemPasteboard", nullptr, reinterpret_cast<void *>(GetSystemPasteboard)},
1023 };
1024
1025 if (ANI_OK != env->Namespace_BindNativeFunctions(ns, methods.data(), methods.size())) {
1026 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI,
1027 "[ANI_Constructor_Namespace] Cannot bind native methods to %s.", nameSpaceName);
1028 return ANI_ERROR;
1029 };
1030
1031 return ANI_OK;
1032 }
1033
ANI_Constructor_PasteData(ani_env * env)1034 ANI_EXPORT ani_status ANI_Constructor_PasteData(ani_env *env)
1035 {
1036 if (env == nullptr) {
1037 return ANI_ERROR;
1038 }
1039 static const char *className = "L@ohos/pasteboard/PasteDataImpl;";
1040 ani_class cls;
1041 if (ANI_OK != env->FindClass(className, &cls)) {
1042 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[ANI_Constructor_PasteData] Not found %s.", className);
1043 return ANI_NOT_FOUND;
1044 }
1045
1046 std::array methods = {
1047 ani_native_function {"addRecordByPasteDataRecord",
1048 nullptr, reinterpret_cast<void *>(AddRecordByPasteDataRecord)},
1049 ani_native_function {"addRecordByTypeValue", nullptr, reinterpret_cast<void *>(AddRecordByTypeValue)},
1050 ani_native_function {"getRecordCount", nullptr, reinterpret_cast<void *>(GetRecordCount)},
1051 ani_native_function {"getRecord", nullptr, reinterpret_cast<void *>(GetRecord)},
1052 ani_native_function {"setProperty", nullptr, reinterpret_cast<void *>(SetProperty)},
1053 ani_native_function {"getProperty", nullptr, reinterpret_cast<void *>(GetProperty)},
1054 };
1055
1056 if (ANI_OK != env->Class_BindNativeMethods(cls, methods.data(), methods.size())) {
1057 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI,
1058 "[ANI_Constructor_PasteData] Cannot bind native methods to %s.", className);
1059 return ANI_ERROR;
1060 };
1061
1062 return ANI_OK;
1063 }
1064
ANI_Constructor_SystemPasteboard(ani_env * env)1065 ANI_EXPORT ani_status ANI_Constructor_SystemPasteboard(ani_env *env)
1066 {
1067 if (env == nullptr) {
1068 return ANI_ERROR;
1069 }
1070 static const char *className = "L@ohos/pasteboard/SystemPasteboardImpl;";
1071 ani_class cls;
1072 if (ANI_OK != env->FindClass(className, &cls)) {
1073 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[ANI_Constructor_SystemPasteboard] Not found %s.", className);
1074 return ANI_NOT_FOUND;
1075 }
1076
1077 std::array methods = {
1078 ani_native_function {"hasDataType", nullptr, reinterpret_cast<void *>(HasDataType)},
1079 ani_native_function {"nativeSetData", nullptr, reinterpret_cast<void *>(SetData)},
1080 ani_native_function {"nativeClearData", nullptr, reinterpret_cast<void *>(ClearData)},
1081 ani_native_function {"getDataSync", nullptr, reinterpret_cast<void *>(GetDataSync)},
1082 ani_native_function {"getDataSource", nullptr, reinterpret_cast<void *>(GetDataSource)},
1083 };
1084
1085 if (ANI_OK != env->Class_BindNativeMethods(cls, methods.data(), methods.size())) {
1086 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI,
1087 "[ANI_Constructor_SystemPasteboard] Cannot bind native methods to %s.", className);
1088 return ANI_ERROR;
1089 };
1090
1091 return ANI_OK;
1092 }
1093
BindCleanerclassMethods(ani_env * env)1094 static ani_status BindCleanerclassMethods(ani_env *env)
1095 {
1096 if (env == nullptr) {
1097 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[BindCleanerclassMethods] env is null.");
1098 return ANI_ERROR;
1099 }
1100
1101 static const char *className = "L@ohos/pasteboard/Cleaner;";
1102 ani_class cleanerCls;
1103 ani_status status = env->FindClass(className, &cleanerCls);
1104 if (ANI_OK != status) {
1105 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI,
1106 "[BindCleanerclassMethods] Not found ohos/pasteboard/Cleaner. status:%{public}d.", status);
1107 return ANI_NOT_FOUND;
1108 }
1109 return NativePtrCleaner(env).Bind(cleanerCls);
1110 }
1111
ANI_Constructor(ani_vm * vm,uint32_t * result)1112 ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result)
1113 {
1114 if (vm == nullptr || result == nullptr) {
1115 return ANI_ERROR;
1116 }
1117 ani_env *env;
1118 if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env)) {
1119 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI, "[ANI_Constructor] Unsupported ANI_VERSION_1.");
1120 return ANI_ERROR;
1121 }
1122
1123 ani_status namespaceStatus = ANI_Constructor_Namespace(env);
1124 if (namespaceStatus != ANI_OK) {
1125 return namespaceStatus;
1126 }
1127
1128 ani_status pasteDataStatus = ANI_Constructor_PasteData(env);
1129 if (pasteDataStatus != ANI_OK) {
1130 return pasteDataStatus;
1131 }
1132
1133 ani_status systemboardStatus = ANI_Constructor_SystemPasteboard(env);
1134 if (systemboardStatus != ANI_OK) {
1135 return systemboardStatus;
1136 }
1137
1138 if (ANI_OK != BindCleanerclassMethods(env)) {
1139 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_ANI,
1140 "[ANI_Constructor_PasteData]BindCleanerclassMethods failed.");
1141 return ANI_ERROR;
1142 }
1143
1144 *result = ANI_VERSION_1;
1145 return ANI_OK;
1146 }
1147