1 /*
2 * Copyright (C) 2023-2023 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 * Description: supply napi callback realization for interfaces.
15 * Author: zhangjingnan
16 * Create: 2023-4-11
17 */
18
19 #include <memory>
20 #include "cast_engine_log.h"
21 #include "napi_callback.h"
22
23 namespace OHOS {
24 namespace CastEngine {
25 namespace CastEngineClient {
26 DEFINE_CAST_ENGINE_LABEL("Cast-Napi-Callback");
27
NapiCallback(napi_env env)28 NapiCallback::NapiCallback(napi_env env) : env_(env)
29 {
30 if (env != nullptr) {
31 NAPI_CALL_RETURN_VOID(env, napi_get_uv_event_loop(env, &loop_));
32 }
33 }
34
~NapiCallback()35 NapiCallback::~NapiCallback()
36 {
37 CLOGD("no memory leak for queue-callback");
38 env_ = nullptr;
39 }
40
GetEnv() const41 napi_env NapiCallback::GetEnv() const
42 {
43 return env_;
44 }
45
AfterWorkCallback(uv_work_t *work, int status)46 void NapiCallback::AfterWorkCallback(uv_work_t *work, int status)
47 {
48 std::shared_ptr<DataContext> context(static_cast<DataContext *>(work->data), [work](DataContext *ptr) {
49 delete ptr;
50 delete work;
51 });
52
53 int argc = 0;
54 napi_handle_scope scope = nullptr;
55 napi_open_handle_scope(context->env, &scope);
56 napi_value argv[ARGC_MAX] = { nullptr };
57 if (context->getter) {
58 argc = ARGC_MAX;
59 context->getter(context->env, argc, argv);
60 }
61
62 napi_value undefined = nullptr;
63 if (napi_get_undefined(context->env, &undefined) != napi_ok) {
64 CLOGE("napi_get_undefined failed");
65 napi_close_handle_scope(context->env, scope);
66 return;
67 }
68 napi_value callback = nullptr;
69 if (napi_get_reference_value(context->env, context->method, &callback) != napi_ok) {
70 CLOGE("napi_get_reference_value failed");
71 napi_close_handle_scope(context->env, scope);
72 return;
73 }
74 napi_value callResult = nullptr;
75 if (napi_call_function(context->env, undefined, callback, argc, argv, &callResult) != napi_ok) {
76 CLOGE("napi_call_function failed");
77 }
78 napi_close_handle_scope(context->env, scope);
79 }
80
Call(napi_ref method, NapiArgsGetter getter)81 void NapiCallback::Call(napi_ref method, NapiArgsGetter getter)
82 {
83 CLOGD("Start to have JS call");
84 if (loop_ == nullptr) {
85 CLOGE("loop_ is nullptr");
86 return;
87 }
88 if (method == nullptr) {
89 CLOGE("method is nullptr");
90 return;
91 }
92
93 auto *work = new (std::nothrow) uv_work_t;
94 if (work == nullptr) {
95 CLOGE("no memory for uv_work_t");
96 return;
97 }
98
99 work->data = new DataContext { env_, method, std::move(getter) };
100 int res = uv_queue_work(
101 loop_, work, [](uv_work_t *work) {}, AfterWorkCallback);
102 if (res != 0) {
103 CLOGE("uv queue work failed");
104 delete work;
105 return;
106 }
107 }
108 } // namespace CastEngineClient
109 } // namespace CastEngine
110 } // namespace OHOS