• 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     auto task = [](void* ptr) ->void {
66         auto ctx = reinterpret_cast<LibN::NAsyncContextCallback *>(ptr);
67         if (ctx == nullptr) {
68             HILOGE("failed to get ctx.");
69             return;
70         }
71         HILOGI("BackupRestoreCallback destruct delete ctx");
72         if (bool(ctx->cb_)) {
73             ctx->cb_.CleanJsEnv();
74         }
75         delete ctx;
76     };
77     uint64_t handleId = 0;
78     auto ret = napi_send_cancelable_event(env_, task, ptr.get(), napi_eprio_high, &handleId, "destructor");
79     if (ret != napi_status::napi_ok) {
80         HILOGE("failed to napi_send_cancelable_event, ret:%{public}d, name:%{public}s.", ret, "destructor");
81         if (bool(ctx_->cb_)) {
82             ctx_->cb_.CleanJsEnv();
83         }
84         return;
85     }
86     ptr.release();
87     ctx_ = nullptr;
88     HILOGI("BackupRestoreCallback destruct end");
89 }
90 
operator bool() const91 BackupRestoreCallback::operator bool() const
92 {
93     return bool(ctx_->cb_);
94 }
95 
DoCallJsMethod(napi_env env,void * data,InputArgsParser argParser)96 static void DoCallJsMethod(napi_env env, void *data, InputArgsParser argParser)
97 {
98     HILOGI("Start execute DoCallJsMethod");
99     napi_handle_scope scope = nullptr;
100     napi_open_handle_scope(env, &scope);
101     if (scope == nullptr) {
102         HILOGE("scope is nullptr");
103         return;
104     }
105     auto ctx = static_cast<LibN::NAsyncContextCallback *>(data);
106     if (ctx == nullptr) {
107         HILOGE("This pointer address is empty");
108         napi_close_handle_scope(env, scope);
109         return;
110     }
111     vector<napi_value> argv = {};
112     if (argParser != nullptr) {
113         if (!argParser(env, argv)) {
114             HILOGE("failed to get params.");
115             napi_close_handle_scope(env, scope);
116             return;
117         }
118     }
119     napi_value global = nullptr;
120     napi_get_global(env, &global);
121     if (!bool(ctx->cb_)) {
122         HILOGE("Failed to get ref.");
123         napi_close_handle_scope(env, scope);
124         return;
125     }
126     napi_value callback = ctx->cb_.Deref(env).val_;
127     napi_value result = nullptr;
128     napi_status status = napi_call_function(env, global, callback, argv.size(), argv.data(), &result);
129     if (status != napi_ok) {
130         HILOGE("Failed to call function for %{public}d.", status);
131     }
132     napi_close_handle_scope(env, scope);
133     HILOGI("End execute DoCallJsMethod");
134 }
135 
CallJsMethod(InputArgsParser argParser)136 void BackupRestoreCallback::CallJsMethod(InputArgsParser argParser)
137 {
138     HILOGI("call BackupRestoreCallback CallJsMethod begin.");
139     auto workArgs = make_shared<WorkArgs>();
140     if (workArgs == nullptr) {
141         HILOGE("failed to new workArgs or uv_work_t.");
142         return;
143     }
144     workArgs->ptr = this;
145     workArgs->argParser = argParser;
146     HILOGI("Will execute current js method");
147     auto task = [](void* ptr) ->void {
148         auto workArgs = reinterpret_cast<WorkArgs *>(ptr);
149         do {
150             if (workArgs == nullptr) {
151                 HILOGE("failed to get workArgs.");
152                 break;
153             }
154             DoCallJsMethod(workArgs->ptr->env_, workArgs->ptr->ctx_, workArgs->argParser);
155         } while (false);
156         HILOGI("will notify current thread info");
157         std::unique_lock<std::mutex> lock(workArgs->callbackMutex);
158         workArgs->isReady.store(true);
159         workArgs->callbackCondition.notify_all();
160     };
161     uint64_t handleId = 0;
162     auto ret = napi_send_cancelable_event(env_, task, workArgs.get(), napi_eprio_high, &handleId, "jsmethod");
163     if (ret != napi_status::napi_ok) {
164         HILOGE("failed to napi_send_cancelable_event, ret:%{public}d, name:%{public}s.", ret, "jsmethod");
165         return;
166     }
167     std::unique_lock<std::mutex> lock(workArgs->callbackMutex);
168     HILOGI("Wait execute callback method end");
169     workArgs->callbackCondition.wait(lock, [workArgs]() { return workArgs->isReady.load(); });
170     HILOGI("call BackupRestoreCallback CallJsMethod end.");
171 }
172 } // namespace OHOS::FileManagement::Backup