• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "napi_app_event_watcher.h"
16 
17 #include "hiappevent_base.h"
18 #include "hilog/log.h"
19 #include "napi_util.h"
20 #include "uv.h"
21 
22 namespace OHOS {
23 namespace HiviewDFX {
24 namespace {
25 const HiLogLabel LABEL = { LOG_CORE, HIAPPEVENT_DOMAIN, "Napi_HiAppEvent_Watcher" };
26 constexpr size_t CALLBACK_PARAM_NUM = 3;
27 
SafeDeleteWork(uv_work_t * work)28 void SafeDeleteWork(uv_work_t* work)
29 {
30     if (work != nullptr) {
31         delete work;
32     }
33 }
34 }
OnTriggerContext()35 OnTriggerContext::OnTriggerContext()
36 {
37     env = nullptr;
38     onTrigger = nullptr;
39     holder = nullptr;
40     row = 0;
41     size = 0;
42 }
43 
~OnTriggerContext()44 OnTriggerContext::~OnTriggerContext()
45 {
46     if (onTrigger != nullptr) {
47         napi_delete_reference(env, onTrigger);
48     }
49     if (holder != nullptr) {
50         napi_delete_reference(env, holder);
51     }
52 }
53 
NapiAppEventWatcher(const std::string & name,const std::map<std::string,unsigned int> & filters,TriggerCondition cond)54 NapiAppEventWatcher::NapiAppEventWatcher(const std::string& name, const std::map<std::string, unsigned int>& filters,
55     TriggerCondition cond) : AppEventWatcher(name, filters, cond), context_(nullptr)
56 {}
57 
~NapiAppEventWatcher()58 NapiAppEventWatcher::~NapiAppEventWatcher()
59 {
60     HiLog::Debug(LABEL, "start to destroy NapiAppEventWatcher object");
61     if (context_ == nullptr) {
62         return;
63     }
64 
65     uv_loop_t* loop = nullptr;
66     napi_get_uv_event_loop(context_->env, &loop);
67     uv_work_t* work = new(std::nothrow) uv_work_t();
68     work->data = (void*)context_;
69     uv_queue_work_with_qos(
70         loop,
71         work,
72         [](uv_work_t* work) {},
73         [](uv_work_t* work, int status) {
74             OnTriggerContext* context = (OnTriggerContext*)work->data;
75             HiLog::Debug(LABEL, "start to destroy OnTriggerContext object");
76             delete context;
77             SafeDeleteWork(work);
78         },
79         uv_qos_default);
80 }
81 
InitHolder(const napi_env env,const napi_value holder)82 void NapiAppEventWatcher::InitHolder(const napi_env env, const napi_value holder)
83 {
84     if (context_ == nullptr) {
85         context_ = new(std::nothrow) OnTriggerContext();
86     }
87     context_->env = env;
88     context_->holder = NapiUtil::CreateReference(env, holder);
89 }
90 
OnTrigger(int row,int size)91 void NapiAppEventWatcher::OnTrigger(int row, int size)
92 {
93     HiLog::Debug(LABEL, "onTrigger start");
94     if (context_ == nullptr) {
95         HiLog::Error(LABEL, "onTrigger context is null");
96         return;
97     }
98     context_->row = row;
99     context_->size = size;
100 
101     uv_loop_t* loop = nullptr;
102     napi_get_uv_event_loop(context_->env, &loop);
103     uv_work_t* work = new(std::nothrow) uv_work_t();
104     work->data = (void*)context_;
105     uv_queue_work_with_qos(
106         loop,
107         work,
108         [] (uv_work_t* work) {},
109         [] (uv_work_t* work, int status) {
110             auto context = (OnTriggerContext*)work->data;
111             napi_handle_scope scope = nullptr;
112             napi_open_handle_scope(context->env, &scope);
113             if (scope == nullptr) {
114                 HiLog::Error(LABEL, "failed to open handle scope");
115                 SafeDeleteWork(work);
116                 return;
117             }
118             napi_value callback = NapiUtil::GetReferenceValue(context->env, context->onTrigger);
119             if (callback == nullptr) {
120                 HiLog::Error(LABEL, "failed to get callback from the context");
121                 SafeDeleteWork(work);
122                 napi_close_handle_scope(context->env, scope);
123                 return;
124             }
125             napi_value argv[CALLBACK_PARAM_NUM] = {
126                 NapiUtil::CreateInt32(context->env, context->row),
127                 NapiUtil::CreateInt32(context->env, context->size),
128                 NapiUtil::GetReferenceValue(context->env, context->holder)
129             };
130             napi_value ret = nullptr;
131             if (napi_call_function(context->env, nullptr, callback, CALLBACK_PARAM_NUM, argv, &ret) != napi_ok) {
132                 HiLog::Error(LABEL, "failed to call onTrigger function");
133             }
134             napi_close_handle_scope(context->env, scope);
135             SafeDeleteWork(work);
136         },
137         uv_qos_default);
138 }
139 
InitTrigger(const napi_env env,const napi_value triggerFunc)140 void NapiAppEventWatcher::InitTrigger(const napi_env env, const napi_value triggerFunc)
141 {
142     HiLog::Debug(LABEL, "start to init OnTrigger");
143     if (context_ == nullptr) {
144         context_ = new(std::nothrow) OnTriggerContext();
145     }
146     context_->env = env;
147     context_->onTrigger = NapiUtil::CreateReference(env, triggerFunc);
148 }
149 } // namespace HiviewDFX
150 } // namespace OHOS
151