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