• 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 "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 }