• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024-2024 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 
16 #include "uv.h"
17 #include "native_reference.h"
18 #include "native_value.h"
19 #include "b_error/b_error.h"
20 #include "general_callbacks.h"
21 
22 namespace OHOS::FileManagement::Backup {
23 using namespace std;
24 
RemoveCallbackRef()25 void GeneralCallbacks::RemoveCallbackRef()
26 {
27     HILOGI("Called RemoveCallbackRef");
28     onFileReady.CleanRef();
29     onBundleBegin.CleanRef();
30     onBundleEnd.CleanRef();
31     onAllBundlesEnd.CleanRef();
32     onBackupServiceDied.CleanRef();
33     onResultReport.CleanRef();
34     onProcess.CleanRef();
35 }
36 
CleanRef()37 void BackupRestoreCallback::CleanRef()
38 {
39     HILOGI("BackupRestoreCallback CleanRef");
40     if (!ctx_) {
41         HILOGE("BackupRestoreCallback ctx is nullptr");
42         return;
43     }
44     if (!bool(ctx_->cb_)) {
45         HILOGE("BackupRestoreCallback ref is nullptr");
46         return;
47     }
48     ctx_->cb_.DeleteJsEnv();
49 }
50 
BackupRestoreCallback(napi_env env,LibN::NVal thisPtr,LibN::NVal cb)51 BackupRestoreCallback::BackupRestoreCallback(napi_env env, LibN::NVal thisPtr, LibN::NVal cb) : env_(env)
52 {
53     ctx_ = new LibN::NAsyncContextCallback(thisPtr, cb);
54 }
55 
~BackupRestoreCallback()56 BackupRestoreCallback::~BackupRestoreCallback()
57 {
58     HILOGI("BackupRestoreCallback destruct start");
59     if (!ctx_) {
60         HILOGE("BackupRestoreCallback ctx is nullptr");
61         return;
62     }
63 
64     unique_ptr<LibN::NAsyncContextCallback> ptr(ctx_);
65     uv_loop_s *loop = nullptr;
66     napi_status status = napi_get_uv_event_loop(env_, &loop);
67     if (status != napi_ok) {
68         HILOGE("Failed to get uv event loop");
69         ptr->cb_.CleanJsEnv();
70         return;
71     }
72 
73     auto work = make_unique<uv_work_t>();
74     if (work == nullptr) {
75         HILOGE("Failed to new uv_work_t");
76         return;
77     }
78     work->data = static_cast<void *>(ctx_);
79 
80     auto task = [work {work.get()}]() {
81         if (work == nullptr) {
82             HILOGE("failed to get work.");
83             return;
84         }
85         LibN::NAsyncContextCallback *ctx = static_cast<LibN::NAsyncContextCallback *>(work->data);
86         HILOGI("BackupRestoreCallback destruct delete ctx");
87         delete ctx;
88         delete work;
89     };
90     auto ret = napi_send_event(env_, task, napi_eprio_high);
91     if (ret != napi_status::napi_ok) {
92         HILOGE("Failed to call napi_send_event, ret:%{public}d, status:%{public}d", ret, status);
93         return;
94     }
95     ptr.release();
96     work.release();
97     ctx_ = nullptr;
98     HILOGI("BackupRestoreCallback destruct end");
99 }
100 
operator bool() const101 BackupRestoreCallback::operator bool() const
102 {
103     return bool(ctx_->cb_);
104 }
105 
DoCallJsMethod(napi_env env,void * data,InputArgsParser argParser)106 static void DoCallJsMethod(napi_env env, void *data, InputArgsParser argParser)
107 {
108     HILOGI("Start execute DoCallJsMethod");
109     napi_handle_scope scope = nullptr;
110     napi_open_handle_scope(env, &scope);
111     if (scope == nullptr) {
112         HILOGE("scope is nullptr");
113         return;
114     }
115     auto ctx = static_cast<LibN::NAsyncContextCallback *>(data);
116     if (ctx == nullptr) {
117         HILOGE("This pointer address is empty");
118         napi_close_handle_scope(env, scope);
119         return;
120     }
121     vector<napi_value> argv = {};
122     if (argParser != nullptr) {
123         if (!argParser(env, argv)) {
124             HILOGE("failed to get params.");
125             napi_close_handle_scope(env, scope);
126             return;
127         }
128     }
129     napi_value global = nullptr;
130     napi_get_global(env, &global);
131     napi_value callback = ctx->cb_.Deref(env).val_;
132     if (!bool(ctx->cb_)) {
133         HILOGE("Failed to get ref.");
134         napi_close_handle_scope(env, scope);
135         return;
136     }
137     napi_value result = nullptr;
138     napi_status status = napi_call_function(env, global, callback, argv.size(), argv.data(), &result);
139     if (status != napi_ok) {
140         HILOGE("Failed to call function for %{public}d.", status);
141     }
142     napi_close_handle_scope(env, scope);
143     HILOGI("End execute DoCallJsMethod");
144 }
145 
CallJsMethod(InputArgsParser argParser)146 void BackupRestoreCallback::CallJsMethod(InputArgsParser argParser)
147 {
148     HILOGI("call BackupRestoreCallback CallJsMethod begin.");
149     uv_loop_s *loop = nullptr;
150     napi_status status = napi_get_uv_event_loop(env_, &loop);
151     if (status != napi_ok) {
152         HILOGE("failed to get uv event loop.");
153         return;
154     }
155     auto workArgs = make_shared<WorkArgs>();
156     auto work = make_unique<uv_work_t>();
157     if (workArgs == nullptr || work == nullptr) {
158         HILOGE("failed to new workArgs or uv_work_t.");
159         return;
160     }
161     workArgs->ptr = this;
162     workArgs->argParser = argParser;
163     work->data = reinterpret_cast<void *>(workArgs.get());
164     HILOGI("Will execute current js method");
165     auto task = [work {work.get()}]() {
166         if (work == nullptr) {
167             HILOGE("failed to get work.");
168             return;
169         }
170         HILOGI("AsyncWork Enter, %{public}zu", (size_t)work);
171         auto workArgs = reinterpret_cast<WorkArgs *>(work->data);
172         do {
173             if (workArgs == nullptr) {
174                 HILOGE("failed to get workArgs.");
175                 break;
176             }
177             DoCallJsMethod(workArgs->ptr->env_, workArgs->ptr->ctx_, workArgs->argParser);
178         } while (false);
179         HILOGI("will notify current thread info");
180         std::unique_lock<std::mutex> lock(workArgs->callbackMutex);
181         workArgs->isReady.store(true);
182         workArgs->callbackCondition.notify_all();
183         delete work;
184     };
185     auto ret = napi_send_event(env_, task, napi_eprio_high);
186     if (ret != napi_status::napi_ok) {
187         HILOGE("failed to napi_send_event, ret:%{public}d.", ret);
188         work.reset();
189         return;
190     }
191     std::unique_lock<std::mutex> lock(workArgs->callbackMutex);
192     HILOGI("Wait execute callback method end");
193     workArgs->callbackCondition.wait(lock, [workArgs]() { return workArgs->isReady.load(); });
194     work.release();
195     HILOGI("call BackupRestoreCallback CallJsMethod end.");
196 }
197 } // namespace OHOS::FileManagement::Backup