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 <uv.h>
16
17 #include "bundle_status_callback.h"
18
19 #include "napi/native_common.h"
20
BundleStatusCallback(napi_env env,napi_ref addedCallback,napi_ref updatedCallback,napi_ref removeCallback)21 BundleStatusCallback::BundleStatusCallback(napi_env env, napi_ref addedCallback,
22 napi_ref updatedCallback,
23 napi_ref removeCallback)
24 : env_(env), addedCallback_(addedCallback),
25 updatedCallback_(updatedCallback), removeCallback_(removeCallback) {}
26
~BundleStatusCallback()27 BundleStatusCallback::~BundleStatusCallback()
28 {
29 uv_loop_s* loop = nullptr;
30 napi_get_uv_event_loop(env_, &loop);
31 uv_work_t* work = new uv_work_t;
32 DelRefCallbackInfo* delRefCallbackInfo = new DelRefCallbackInfo {
33 .env_ = env_,
34 .addedCallback_ = addedCallback_,
35 .updatedCallback_ = updatedCallback_,
36 .removeCallback_ = removeCallback_,
37 };
38 if (work == nullptr || delRefCallbackInfo == nullptr) {
39 return;
40 }
41 work->data = reinterpret_cast<void*>(delRefCallbackInfo);
42 int ret = uv_queue_work(
43 loop, work, [](uv_work_t* work) {},
44 [](uv_work_t* work, int status) {
45 // JS Thread
46 DelRefCallbackInfo* delRefCallbackInfo = reinterpret_cast<DelRefCallbackInfo*>(work->data);
47 if (delRefCallbackInfo == nullptr) {
48 return;
49 }
50 napi_delete_reference(delRefCallbackInfo->env_, delRefCallbackInfo->addedCallback_);
51 napi_delete_reference(delRefCallbackInfo->env_, delRefCallbackInfo->updatedCallback_);
52 napi_delete_reference(delRefCallbackInfo->env_, delRefCallbackInfo->removeCallback_);
53 delete delRefCallbackInfo;
54 delRefCallbackInfo = nullptr;
55 delete work;
56 work = nullptr;
57 });
58 if (ret != 0) {
59 delete delRefCallbackInfo;
60 delete work;
61 }
62 }
63
OnBundleAdded(const std::string & bundleName,const int userId)64 void BundleStatusCallback::OnBundleAdded(const std::string& bundleName, const int userId)
65 {
66 uv_loop_s* loop = nullptr;
67 napi_get_uv_event_loop(env_, &loop);
68 uv_work_t* work = new uv_work_t;
69 AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo {
70 .env_ = env_,
71 .callback_ = addedCallback_,
72 .bundleName_ = bundleName,
73 .userId_ = userId,
74 };
75 if (work == nullptr || asyncCallbackInfo == nullptr) {
76 return;
77 }
78 work->data = reinterpret_cast<void*>(asyncCallbackInfo);
79 int ret = uv_queue_work(
80 loop, work, [](uv_work_t* work) {},
81 [](uv_work_t* work, int status) {
82 // JS Thread
83 AsyncCallbackInfo* asyncCallbackInfo = reinterpret_cast<AsyncCallbackInfo*>(work->data);
84 if (asyncCallbackInfo == nullptr) {
85 return;
86 }
87 std::unique_ptr<AsyncCallbackInfo> callbackPtr {asyncCallbackInfo};
88 napi_handle_scope scope = nullptr;
89 napi_open_handle_scope(asyncCallbackInfo->env_, &scope);
90 if (scope == nullptr) {
91 return;
92 }
93 napi_value callback = nullptr;
94 napi_value placeHolder = nullptr;
95 napi_value result[2] = { 0 };
96 napi_get_reference_value(asyncCallbackInfo->env_, asyncCallbackInfo->callback_, &callback);
97 napi_create_string_utf8(
98 asyncCallbackInfo->env_, asyncCallbackInfo->bundleName_.c_str(), NAPI_AUTO_LENGTH, &result[0]);
99 napi_create_uint32(asyncCallbackInfo->env_, asyncCallbackInfo->userId_, &result[1]);
100 napi_call_function(
101 asyncCallbackInfo->env_, nullptr, callback, sizeof(result) / sizeof(result[0]), result, &placeHolder);
102 napi_close_handle_scope(asyncCallbackInfo->env_, scope);
103 if (work != nullptr) {
104 delete work;
105 work = nullptr;
106 }
107 });
108 if (ret != 0) {
109 delete asyncCallbackInfo;
110 delete work;
111 }
112 }
113
OnBundleUpdated(const std::string & bundleName,const int userId)114 void BundleStatusCallback::OnBundleUpdated(const std::string& bundleName, const int userId)
115 {
116 uv_loop_s* loop = nullptr;
117 napi_get_uv_event_loop(env_, &loop);
118 uv_work_t* work = new uv_work_t;
119 AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo {
120 .env_ = env_,
121 .callback_ = updatedCallback_,
122 .bundleName_ = bundleName,
123 .userId_ = userId,
124 };
125 if (work == nullptr || asyncCallbackInfo == nullptr) {
126 return;
127 }
128 work->data = reinterpret_cast<void*>(asyncCallbackInfo);
129 int ret = uv_queue_work(
130 loop, work, [](uv_work_t* work) {},
131 [](uv_work_t* work, int status) {
132 AsyncCallbackInfo* asyncCallbackInfo = reinterpret_cast<AsyncCallbackInfo*>(work->data);
133 if (asyncCallbackInfo == nullptr) {
134 return;
135 }
136 std::unique_ptr<AsyncCallbackInfo> callbackPtr {asyncCallbackInfo};
137 napi_handle_scope scope = nullptr;
138 napi_open_handle_scope(asyncCallbackInfo->env_, &scope);
139 if (scope == nullptr) {
140 return;
141 }
142 napi_value callback = nullptr;
143 napi_value placeHolder = nullptr;
144 napi_value result[2] = { 0 };
145 napi_get_reference_value(asyncCallbackInfo->env_, asyncCallbackInfo->callback_, &callback);
146 napi_create_string_utf8(
147 asyncCallbackInfo->env_, asyncCallbackInfo->bundleName_.c_str(), NAPI_AUTO_LENGTH, &result[0]);
148 napi_create_uint32(asyncCallbackInfo->env_, asyncCallbackInfo->userId_, &result[1]);
149 napi_call_function(
150 asyncCallbackInfo->env_, nullptr, callback, sizeof(result) / sizeof(result[0]), result, &placeHolder);
151 napi_close_handle_scope(asyncCallbackInfo->env_, scope);
152 if (work != nullptr) {
153 delete work;
154 work = nullptr;
155 }
156 });
157 if (ret != 0) {
158 if (asyncCallbackInfo != nullptr) {
159 delete asyncCallbackInfo;
160 }
161 if (work != nullptr) {
162 delete work;
163 }
164 }
165 }
166
OnBundleRemoved(const std::string & bundleName,const int userId)167 void BundleStatusCallback::OnBundleRemoved(const std::string& bundleName, const int userId)
168 {
169 uv_loop_s* loop = nullptr;
170 napi_get_uv_event_loop(env_, &loop);
171 uv_work_t* work = new uv_work_t;
172 AsyncCallbackInfo* asyncCallbackInfo = new AsyncCallbackInfo {
173 .env_ = env_,
174 .callback_ = removeCallback_,
175 .bundleName_ = bundleName,
176 .userId_ = userId,
177 };
178 if (work == nullptr || asyncCallbackInfo == nullptr) {
179 return;
180 }
181 work->data = reinterpret_cast<void*>(asyncCallbackInfo);
182 int ret = uv_queue_work(
183 loop, work, [](uv_work_t* work) {},
184 [](uv_work_t* work, int status) {
185 // JS Thread
186 AsyncCallbackInfo* asyncCallbackInfo = reinterpret_cast<AsyncCallbackInfo*>(work->data);
187 if (asyncCallbackInfo == nullptr) {
188 return;
189 }
190 std::unique_ptr<AsyncCallbackInfo> callbackPtr {asyncCallbackInfo};
191 napi_handle_scope scope = nullptr;
192 napi_open_handle_scope(asyncCallbackInfo->env_, &scope);
193 if (scope == nullptr) {
194 return;
195 }
196 napi_value callback = nullptr;
197 napi_value placeHolder = nullptr;
198 napi_value result[2] = { 0 };
199 napi_get_reference_value(asyncCallbackInfo->env_, asyncCallbackInfo->callback_, &callback);
200 napi_create_string_utf8(
201 asyncCallbackInfo->env_, asyncCallbackInfo->bundleName_.c_str(), NAPI_AUTO_LENGTH, &result[0]);
202 napi_create_uint32(asyncCallbackInfo->env_, asyncCallbackInfo->userId_, &result[1]);
203 napi_call_function(
204 asyncCallbackInfo->env_, nullptr, callback, sizeof(result) / sizeof(result[0]), result, &placeHolder);
205 napi_close_handle_scope(asyncCallbackInfo->env_, scope);
206 if (work != nullptr) {
207 delete work;
208 work = nullptr;
209 }
210 });
211 if (ret != 0) {
212 delete asyncCallbackInfo;
213 delete work;
214 }
215 }