• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 #include <thread>
16 #include <uv.h>
17 
18 #include "common/block_object.h"
19 #include "napi_common.h"
20 #include "pasteboard_common.h"
21 #include "pasteboard_js_err.h"
22 #include "pasteboard_hilog.h"
23 #include "systempasteboard_napi.h"
24 #include "pasteboard_error.h"
25 using namespace OHOS::MiscServices;
26 using namespace OHOS::Media;
27 
28 namespace OHOS {
29 namespace MiscServicesNapi {
30 static thread_local napi_ref g_systemPasteboard = nullptr;
31 thread_local std::map<napi_ref, std::shared_ptr<PasteboardObserverInstance>> SystemPasteboardNapi::observers_;
32 constexpr size_t MAX_ARGS = 6;
33 const std::string STRING_UPDATE = "update";
PasteboardObserverInstance(const napi_env & env,const napi_ref & ref)34 PasteboardObserverInstance::PasteboardObserverInstance(const napi_env &env, const napi_ref &ref)
35     : env_(env), ref_(ref)
36 {
37     stub_ = new (std::nothrow) PasteboardObserverInstance::PasteboardObserverImpl();
38 }
39 
~PasteboardObserverInstance()40 PasteboardObserverInstance::~PasteboardObserverInstance()
41 {
42     napi_delete_reference(env_, ref_);
43 }
44 
GetStub()45 sptr<PasteboardObserverInstance::PasteboardObserverImpl> PasteboardObserverInstance::GetStub()
46 {
47     return stub_;
48 }
49 
UvQueueWorkOnPasteboardChanged(uv_work_t * work,int status)50 void UvQueueWorkOnPasteboardChanged(uv_work_t *work, int status)
51 {
52     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_JS_NAPI, "UvQueueWorkOnPasteboardChanged start");
53     if (work == nullptr) {
54         return;
55     }
56     PasteboardDataWorker *pasteboardDataWorker = (PasteboardDataWorker *)work->data;
57     if (pasteboardDataWorker == nullptr || pasteboardDataWorker->observer == nullptr) {
58         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_JS_NAPI, "pasteboardDataWorker or ref is null");
59         delete work;
60         work = nullptr;
61         return;
62     }
63 
64     auto env = pasteboardDataWorker->observer->GetEnv();
65     auto ref = pasteboardDataWorker->observer->GetRef();
66 
67     napi_handle_scope scope = nullptr;
68     napi_open_handle_scope(env, &scope);
69     if (scope == nullptr) {
70         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_NAPI, "scope null");
71         return;
72     }
73     napi_value undefined = nullptr;
74     napi_get_undefined(env, &undefined);
75 
76     napi_value callback = nullptr;
77     napi_value resultOut = nullptr;
78     napi_get_reference_value(env, ref, &callback);
79     napi_value result = NapiGetNull(env);
80     napi_call_function(env, undefined, callback, 0, &result, &resultOut);
81 
82     napi_close_handle_scope(env, scope);
83     delete pasteboardDataWorker;
84     pasteboardDataWorker = nullptr;
85     delete work;
86 }
87 
OnPasteboardChanged()88 void PasteboardObserverInstance::OnPasteboardChanged()
89 {
90     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_JS_NAPI, "OnPasteboardChanged is called!");
91     uv_loop_s *loop = nullptr;
92     napi_get_uv_event_loop(env_, &loop);
93     if (loop == nullptr) {
94         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_JS_NAPI, "loop instance is nullptr");
95         return;
96     }
97 
98     uv_work_t *work = new (std::nothrow) uv_work_t;
99     if (work == nullptr) {
100         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_JS_NAPI, "work is null");
101         return;
102     }
103     PasteboardDataWorker *pasteboardDataWorker = new (std::nothrow) PasteboardDataWorker();
104     if (pasteboardDataWorker == nullptr) {
105         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_JS_NAPI, "pasteboardDataWorker is null");
106         delete work;
107         work = nullptr;
108         return;
109     }
110     pasteboardDataWorker->observer = shared_from_this();
111 
112     work->data = (void *)pasteboardDataWorker;
113 
114     int ret = uv_queue_work(
115         loop, work, [](uv_work_t *work) {}, UvQueueWorkOnPasteboardChanged);
116     if (ret != 0) {
117         delete pasteboardDataWorker;
118         pasteboardDataWorker = nullptr;
119         delete work;
120         work = nullptr;
121     }
122     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_JS_NAPI, "OnPasteboardChanged end");
123 }
124 
CheckAgrsOfOnAndOff(napi_env env,bool CheckArgsCount,napi_value * argv,size_t argc)125 bool SystemPasteboardNapi::CheckAgrsOfOnAndOff(napi_env env, bool CheckArgsCount, napi_value *argv, size_t argc)
126 {
127     if (!CheckExpression(
128         env, CheckArgsCount, JSErrorCode::INVALID_PARAMETERS, "Parameter error. Wrong number of arguments.")
129         || !CheckArgsType(env, argv[0], napi_string, "Parameter error. The type of mimeType must be string.")) {
130         return false;
131     }
132     std::string mimeType;
133     bool ret = GetValue(env, argv[0], mimeType);
134     if (!ret) {
135         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_NAPI, "GetValue failed");
136         return false;
137     }
138     if (!CheckExpression(env, mimeType == STRING_UPDATE, JSErrorCode::INVALID_PARAMETERS,
139         "Parameter error. The value of type must be update")) {
140         return false;
141     }
142     return true;
143 }
144 
On(napi_env env,napi_callback_info info)145 napi_value SystemPasteboardNapi::On(napi_env env, napi_callback_info info)
146 {
147     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_JS_NAPI, "SystemPasteboardNapi on() is called!");
148     size_t argc = MAX_ARGS;
149     napi_value argv[MAX_ARGS] = { 0 };
150     napi_value thisVar = 0;
151     void *data = nullptr;
152     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
153     // on(type: 'update', callback: () => void) has 2 args
154     if (!CheckAgrsOfOnAndOff(env, argc >= 2, argv, argc)
155         || !CheckArgsType(env, argv[1], napi_function, "Parameter error. The type of callback must be function.")) {
156         return nullptr;
157     }
158 
159     napi_value result = nullptr;
160     napi_get_undefined(env, &result);
161     auto observer = GetObserver(env, argv[1]);
162     if (observer != nullptr) {
163         return result;
164     }
165     napi_ref ref = nullptr;
166     napi_create_reference(env, argv[1], 1, &ref);
167     observer = std::make_shared<PasteboardObserverInstance>(env, ref);
168     observer->GetStub()->SetObserverWrapper(observer);
169     PasteboardClient::GetInstance()->AddPasteboardChangedObserver(observer->GetStub());
170     observers_[ref] = observer;
171     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_JS_NAPI, "SystemPasteboardNapi on() is end!");
172     return result;
173 }
174 
Off(napi_env env,napi_callback_info info)175 napi_value SystemPasteboardNapi::Off(napi_env env, napi_callback_info info)
176 {
177     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_JS_NAPI, "SystemPasteboardNapi off () is called!");
178     size_t argc = MAX_ARGS;
179     napi_value argv[MAX_ARGS] = { 0 };
180     napi_value thisVar = 0;
181     void *data = nullptr;
182     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
183     // off(type: 'update', callback?: () => void) has at least 1 arg
184     if (!CheckAgrsOfOnAndOff(env, argc >= 1, argv, argc)) {
185         return nullptr;
186     }
187 
188     std::shared_ptr<PasteboardObserverInstance> observer = nullptr;
189     // 1: is the observer parameter
190     if (argc > 1) {
191         if (!CheckArgsType(env, argv[1], napi_function, "Parameter error. The type of callback must be function.")) {
192             return nullptr;
193         }
194         observer = GetObserver(env, argv[1]);
195     }
196 
197     DeleteObserver(observer);
198     napi_value result = nullptr;
199     napi_get_undefined(env, &result);
200     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_JS_NAPI, "SystemPasteboardNapi off () is called!");
201     return result;
202 }
203 
Clear(napi_env env,napi_callback_info info)204 napi_value SystemPasteboardNapi::Clear(napi_env env, napi_callback_info info)
205 {
206     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_JS_NAPI, "Clear is called!");
207     auto context = std::make_shared<AsyncCall::Context>();
208     auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
209         // clear has 0 or 1 args
210         if (argc > 0
211             && !CheckArgsType(env, argv[0], napi_function, "Parameter error. The type of callback must be function.")) {
212             return napi_invalid_arg;
213         }
214         return napi_ok;
215     };
216     auto exec = [context](AsyncCall::Context *ctx) {
217         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "exec Clear");
218         PasteboardClient::GetInstance()->Clear();
219     };
220     context->SetAction(std::move(input));
221     // 0: the AsyncCall at the first position;
222     AsyncCall asyncCall(env, info, context, 0);
223     return asyncCall.Call(env, exec);
224 }
225 
ClearData(napi_env env,napi_callback_info info)226 napi_value SystemPasteboardNapi::ClearData(napi_env env, napi_callback_info info)
227 {
228     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_JS_NAPI, "ClearData is called!");
229     return Clear(env, info);
230 }
231 
HasPasteData(napi_env env,napi_callback_info info)232 napi_value SystemPasteboardNapi::HasPasteData(napi_env env, napi_callback_info info)
233 {
234     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_JS_NAPI, "HasPasteData is called!");
235     auto context = std::make_shared<HasContextInfo>();
236     auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
237         // hasPasteData has 0 or 1 args
238         if (argc > 0
239             && !CheckArgsType(env, argv[0], napi_function, "Parameter error. The type of callback must be function.")) {
240             return napi_invalid_arg;
241         }
242         return napi_ok;
243     };
244     auto output = [context](napi_env env, napi_value *result) -> napi_status {
245         napi_status status = napi_get_boolean(env, context->hasPasteData, result);
246         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "napi_get_boolean status = %{public}d", status);
247         return status;
248     };
249     auto exec = [context](AsyncCall::Context *ctx) {
250         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "exec HasPasteData");
251         context->hasPasteData = PasteboardClient::GetInstance()->HasPasteData();
252         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "HasPasteData result = %{public}d", context->hasPasteData);
253         context->status = napi_ok;
254     };
255     context->SetAction(std::move(input), std::move(output));
256     // 0: the AsyncCall at the first position;
257     AsyncCall asyncCall(env, info, context, 0);
258     return asyncCall.Call(env, exec);
259 }
260 
HasData(napi_env env,napi_callback_info info)261 napi_value SystemPasteboardNapi::HasData(napi_env env, napi_callback_info info)
262 {
263     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_JS_NAPI, "HasData is called!");
264     return HasPasteData(env, info);
265 }
266 
GetDataCommon(std::shared_ptr<GetContextInfo> & context)267 void SystemPasteboardNapi::GetDataCommon(std::shared_ptr<GetContextInfo> &context)
268 {
269     auto input = [](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
270         // 1: GetPasteData has 0 or 1 args
271         if (argc > 0
272             && !CheckArgsType(env, argv[0], napi_function, "Parameter error. The type of callback must be function.")) {
273             return napi_invalid_arg;
274         }
275         return napi_ok;
276     };
277 
278     auto output = [context](napi_env env, napi_value *result) -> napi_status {
279         napi_value instance = nullptr;
280         PasteDataNapi::NewInstance(env, instance);
281         PasteDataNapi *obj = nullptr;
282         napi_status ret = napi_unwrap(env, instance, reinterpret_cast<void **>(&obj));
283         if ((ret == napi_ok) || (obj != nullptr)) {
284             obj->value_ = context->pasteData;
285         } else {
286             return napi_generic_failure;
287         }
288         *result = instance;
289         return napi_ok;
290     };
291     context->SetAction(std::move(input), std::move(output));
292 }
293 
GetPasteData(napi_env env,napi_callback_info info)294 napi_value SystemPasteboardNapi::GetPasteData(napi_env env, napi_callback_info info)
295 {
296     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_JS_NAPI, "GetPasteData is called!");
297 
298     auto context = std::make_shared<GetContextInfo>();
299     context->pasteData = std::make_shared<PasteData>();
300     GetDataCommon(context);
301 
302     auto exec = [context](AsyncCall::Context *ctx) {
303         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "GetPasteData Begin");
304         PasteboardClient::GetInstance()->GetPasteData(*context->pasteData);
305         context->status = napi_ok;
306         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "GetPasteData End");
307     };
308 
309     // 0: the AsyncCall at the first position;
310     AsyncCall asyncCall(env, info, context, 0);
311     return asyncCall.Call(env, exec);
312 }
313 
GetData(napi_env env,napi_callback_info info)314 napi_value SystemPasteboardNapi::GetData(napi_env env, napi_callback_info info)
315 {
316     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_JS_NAPI, "GetData is called!");
317 
318     auto context = std::make_shared<GetContextInfo>();
319     context->pasteData = std::make_shared<PasteData>();
320     GetDataCommon(context);
321 
322     auto exec = [context](AsyncCall::Context *ctx) {
323         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "GetData Begin");
324         int32_t ret = PasteboardClient::GetInstance()->GetPasteData(*context->pasteData);
325         if (ret == static_cast<int32_t>(PasteboardError::E_IS_BEGING_PROCESSED)) {
326             context->SetErrInfo(ret, "Another getData is being processed");
327         } else {
328             context->status = napi_ok;
329         }
330         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "GetData End");
331     };
332     // 0: the AsyncCall at the first position;
333     AsyncCall asyncCall(env, info, context, 0);
334     return asyncCall.Call(env, exec);
335 }
336 
SetDataCommon(std::shared_ptr<SetContextInfo> & context)337 void SystemPasteboardNapi::SetDataCommon(std::shared_ptr<SetContextInfo> &context)
338 {
339     auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
340         // setData has 1 or 2 args
341         if (!CheckExpression(
342                 env, argc > 0, JSErrorCode::INVALID_PARAMETERS, "Parameter error. Wrong number of arguments.")
343             || !CheckExpression(env, PasteDataNapi::IsPasteData(env, argv[0]), JSErrorCode::INVALID_PARAMETERS,
344                 "Parameter error. The Type of data must be pasteData.")) {
345             return napi_invalid_arg;
346         }
347         if (argc > 1
348             && !CheckArgsType(env, argv[1], napi_function, "Parameter error. The type of callback must be function.")) {
349             return napi_invalid_arg;
350         }
351         PasteDataNapi *pasteData = nullptr;
352         napi_unwrap(env, argv[0], reinterpret_cast<void **>(&pasteData));
353         if (pasteData != nullptr) {
354             context->obj = pasteData->value_;
355         }
356         return napi_ok;
357     };
358     context->SetAction(std::move(input));
359 }
360 
SetPasteData(napi_env env,napi_callback_info info)361 napi_value SystemPasteboardNapi::SetPasteData(napi_env env, napi_callback_info info)
362 {
363     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_JS_NAPI, "SetPasteData is called!");
364     auto context = std::make_shared<SetContextInfo>();
365     SetDataCommon(context);
366 
367     auto exec = [context](AsyncCall::Context *ctx) {
368         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_JS_NAPI, "exec SetPasteData");
369         if (context->obj != nullptr) {
370             PasteboardClient::GetInstance()->SetPasteData(*(context->obj));
371             context->obj = nullptr;
372         }
373         context->status = napi_ok;
374     };
375     // 1: the AsyncCall at the second position
376     AsyncCall asyncCall(env, info, context, 1);
377     return asyncCall.Call(env, exec);
378 }
379 
SetData(napi_env env,napi_callback_info info)380 napi_value SystemPasteboardNapi::SetData(napi_env env, napi_callback_info info)
381 {
382     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_JS_NAPI, "SetData is called!");
383     auto context = std::make_shared<SetContextInfo>();
384     SetDataCommon(context);
385 
386     auto exec = [context](AsyncCall::Context *ctx) {
387         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_JS_NAPI, "exec SetPasteData");
388         int32_t ret = static_cast<int32_t>(PasteboardError::E_ERROR);
389         if (context->obj != nullptr) {
390             ret = PasteboardClient::GetInstance()->SetPasteData(*(context->obj));
391             context->obj = nullptr;
392         }
393         if (ret == static_cast<int>(PasteboardError::E_OK)) {
394             context->status = napi_ok;
395         } else if (ret == static_cast<int>(PasteboardError::E_COPY_FORBIDDEN)) {
396             context->SetErrInfo(ret, "The system prohibits copying");
397         } else if (ret == static_cast<int>(PasteboardError::E_IS_BEGING_PROCESSED)) {
398             context->SetErrInfo(ret, "Another setData is being processed");
399         }
400         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "exec context->status[%{public}d]", context->status);
401     };
402     // 1: the AsyncCall at the second position
403     AsyncCall asyncCall(env, info, context, 1);
404     return asyncCall.Call(env, exec);
405 }
406 
SystemPasteboardInit(napi_env env,napi_value exports)407 napi_value SystemPasteboardNapi::SystemPasteboardInit(napi_env env, napi_value exports)
408 {
409     napi_status status = napi_ok;
410     napi_property_descriptor descriptors[] = {
411         DECLARE_NAPI_FUNCTION("on", On),
412         DECLARE_NAPI_FUNCTION("off", Off),
413         DECLARE_NAPI_FUNCTION("clear", Clear),
414         DECLARE_NAPI_FUNCTION("getPasteData", GetPasteData),
415         DECLARE_NAPI_FUNCTION("hasPasteData", HasPasteData),
416         DECLARE_NAPI_FUNCTION("setPasteData", SetPasteData),
417         DECLARE_NAPI_FUNCTION("clearData", ClearData),
418         DECLARE_NAPI_FUNCTION("getData", GetData),
419         DECLARE_NAPI_FUNCTION("hasData", HasData),
420         DECLARE_NAPI_FUNCTION("setData", SetData),
421     };
422     napi_value constructor;
423     napi_define_class(env, "SystemPasteboard", NAPI_AUTO_LENGTH, New, nullptr,
424         sizeof(descriptors) / sizeof(napi_property_descriptor), descriptors, &constructor);
425     if (status != napi_ok) {
426         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_NAPI, "Failed to define class at SystemPasteboardInit");
427         return nullptr;
428     }
429     napi_create_reference(env, constructor, 1, &g_systemPasteboard);
430     status = napi_set_named_property(env, exports, "SystemPasteboard", constructor);
431     if (status != napi_ok) {
432         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_NAPI, "Set property failed when SystemPasteboardInit");
433         return nullptr;
434     }
435     return exports;
436 }
437 
SystemPasteboardNapi()438 SystemPasteboardNapi::SystemPasteboardNapi() : env_(nullptr), wrapper_(nullptr)
439 {
440     value_ = std::make_shared<PasteDataNapi>();
441 }
442 
~SystemPasteboardNapi()443 SystemPasteboardNapi::~SystemPasteboardNapi()
444 {
445     napi_delete_reference(env_, wrapper_);
446 }
447 
Destructor(napi_env env,void * nativeObject,void * finalize_hint)448 void SystemPasteboardNapi::Destructor(napi_env env, void *nativeObject, void *finalize_hint)
449 {
450     SystemPasteboardNapi *obj = static_cast<SystemPasteboardNapi *>(nativeObject);
451     delete obj;
452 }
453 
New(napi_env env,napi_callback_info info)454 napi_value SystemPasteboardNapi::New(napi_env env, napi_callback_info info)
455 {
456     size_t argc = MAX_ARGS;
457     napi_value argv[MAX_ARGS] = { 0 };
458     napi_value thisVar = nullptr;
459     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
460     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "proc.");
461     // get native object
462     SystemPasteboardNapi *obj = new (std::nothrow) SystemPasteboardNapi();
463     if (!obj) {
464         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_NAPI, "New obj is null");
465         return nullptr;
466     }
467     obj->env_ = env;
468     NAPI_CALL(env, napi_wrap(env, thisVar, obj, SystemPasteboardNapi::Destructor,
469                        nullptr, // finalize_hint
470                        &obj->wrapper_));
471     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "end.");
472     return thisVar;
473 }
474 
NewInstance(napi_env env,napi_value & instance)475 napi_status SystemPasteboardNapi::NewInstance(napi_env env, napi_value &instance)
476 {
477     napi_status status;
478 
479     napi_value constructor;
480     status = napi_get_reference_value(env, g_systemPasteboard, &constructor);
481     if (status != napi_ok) {
482         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_NAPI, "get reference failed");
483         return status;
484     }
485 
486     status = napi_new_instance(env, constructor, 0, nullptr, &instance);
487     if (status != napi_ok) {
488         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_NAPI, "new instance failed");
489         return status;
490     }
491     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_JS_NAPI, "new instance ok");
492 
493     return napi_ok;
494 }
495 
GetObserver(napi_env env,napi_value observer)496 std::shared_ptr<PasteboardObserverInstance> SystemPasteboardNapi::GetObserver(napi_env env, napi_value observer)
497 {
498     PASTEBOARD_HILOGE(PASTEBOARD_MODULE_JS_NAPI, "GetObserver start");
499     for (auto &[refKey, observerValue] : observers_) {
500         napi_value callback = nullptr;
501         napi_get_reference_value(env, refKey, &callback);
502         bool isEqual = false;
503         napi_strict_equals(env, observer, callback, &isEqual);
504         if (isEqual) {
505             return observerValue;
506         }
507     }
508     return nullptr;
509 }
510 
DeleteObserver(const std::shared_ptr<PasteboardObserverInstance> & observer)511 void SystemPasteboardNapi::DeleteObserver(const std::shared_ptr<PasteboardObserverInstance> &observer)
512 {
513     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_JS_NAPI, "observer == null: %{public}d, size: %{public}zu",
514         observer == nullptr, observers_.size());
515     std::vector<std::shared_ptr<PasteboardObserverInstance>> observers;
516     {
517         for (auto it = observers_.begin(); it != observers_.end();) {
518             observers.push_back(it->second);
519             observers_.erase(it++);
520             if (it->second == observer) {
521                 break;
522             }
523         }
524     }
525     for (auto &delObserver : observers) {
526         PasteboardClient::GetInstance()->RemovePasteboardChangedObserver(delObserver->GetStub());
527     }
528 }
529 
OnPasteboardChanged()530 void PasteboardObserverInstance::PasteboardObserverImpl::OnPasteboardChanged()
531 {
532     std::shared_ptr<PasteboardObserverInstance> observerInstance(wrapper_.lock());
533     if (observerInstance == nullptr) {
534         PASTEBOARD_HILOGW(PASTEBOARD_MODULE_JS_NAPI, "expired callback");
535         return;
536     }
537     observerInstance->OnPasteboardChanged();
538 }
539 
SetObserverWrapper(const std::shared_ptr<PasteboardObserverInstance> & observerInstance)540 void PasteboardObserverInstance::PasteboardObserverImpl::SetObserverWrapper(
541     const std::shared_ptr<PasteboardObserverInstance>& observerInstance)
542 {
543     wrapper_ = observerInstance;
544 }
545 } // namespace MiscServicesNapi
546 } // namespace OHOS