1 /*
2 * Copyright (C) 2022 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 "napi_notify_callback.h"
17
18 #include <memory>
19
20 #include "n_val.h"
21 #include "uv.h"
22
23 using namespace OHOS::FileManagement::LibN;
24 namespace OHOS {
25 namespace FileAccessFwk {
26 namespace {
27 const int ARGS_ONE = 1;
28 }
29
NapiNotifyCallback(napi_env env,napi_value callback)30 NapiNotifyCallback::NapiNotifyCallback(napi_env env, napi_value callback)
31 {
32 env_ = env;
33 napi_create_reference(env_, callback, 1, &callback_);
34 napi_get_uv_event_loop(env_, &loop_);
35 }
36
~NapiNotifyCallback()37 NapiNotifyCallback::~NapiNotifyCallback()
38 {
39 napi_delete_reference(env_, callback_);
40 }
41
OnNotify(const NotifyMessage & message)42 int NapiNotifyCallback::OnNotify(const NotifyMessage& message)
43 {
44 uv_work_t* work = new uv_work_t();
45 if (work == nullptr) {
46 HILOG_ERROR("failed to new uv_work_t");
47 return EINVAL;
48 }
49 CallbackParam* param = new CallbackParam(this, message);
50 if (param == nullptr) {
51 HILOG_ERROR("failed to new param");
52 delete work;
53 return EINVAL;
54 }
55 work->data = param;
56 int ret = uv_queue_work(loop_, work,
57 [](uv_work_t *work) {},
58 [](uv_work_t *work, int status) {
59 CallbackParam *param = reinterpret_cast<CallbackParam *>(work->data);
60 napi_handle_scope scope = nullptr;
61 // 打开handle scope用于管理napi_value的生命周期,否则会内存泄漏
62 napi_open_handle_scope(param->callback_->env_, &scope);
63 if (scope == nullptr) {
64 HILOG_ERROR("napi_open_handle_scope failed");
65 return;
66 }
67
68 NVal napiNotifyMessage = NVal::CreateObject(param->callback_->env_);
69 napiNotifyMessage.AddProp("deviceType",
70 NVal::CreateInt32(param->callback_->env_, param->message_.deviceType).val_);
71 napiNotifyMessage.AddProp("notifyType",
72 NVal::CreateInt32(param->callback_->env_, param->message_.notifyType).val_);
73 napiNotifyMessage.AddProp("srcUri",
74 NVal::CreateUTF8String(param->callback_->env_, param->message_.srcUri).val_);
75 napiNotifyMessage.AddProp("dstUri",
76 NVal::CreateUTF8String(param->callback_->env_, param->message_.dstUri).val_);
77
78 napi_value callback = nullptr;
79 napi_value args[ARGS_ONE] = {napiNotifyMessage.val_};
80 napi_get_reference_value(param->callback_->env_, param->callback_->callback_, &callback);
81 napi_value global = nullptr;
82 napi_get_global(param->callback_->env_, &global);
83 napi_value result = nullptr;
84 napi_status ret = napi_call_function(param->callback_->env_, global, callback, ARGS_ONE, args, &result);
85 if (ret != napi_ok) {
86 HILOG_ERROR("Notify failed, status:%{public}d.", ret);
87 }
88 // 关闭handle scope释放napi_value
89 napi_close_handle_scope(param->callback_->env_, scope);
90 delete param;
91 delete work;
92 });
93 if (ret != 0) {
94 delete (CallbackParam *)(work->data);
95 work->data = nullptr;
96 delete work;
97 work = nullptr;
98 return E_NOTIFY;
99 }
100
101 return ERR_OK;
102 }
103 } // namespace FileAccessFwk
104 } // namespace OHOS