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_hisysevent_listener.h"
17 
18 #include "hilog/log.h"
19 #include "napi_hisysevent_util.h"
20 
21 #undef LOG_DOMAIN
22 #define LOG_DOMAIN 0xD002D08
23 
24 #undef LOG_TAG
25 #define LOG_TAG "NAPI_HISYSEVENT_LISTENER"
26 
27 namespace OHOS {
28 namespace HiviewDFX {
29 namespace {
30 constexpr char ON_EVENT_ATTR[] = "onEvent";
31 constexpr char ON_SERVICE_DIED_ATTR[] = "onServiceDied";
32 constexpr size_t ON_EVENT_PARAM_COUNT = 1;
33 constexpr size_t ON_SERVICE_DIED_PARAM_COUNT = 0;
34 }
35 
NapiHiSysEventListener(CallbackContext * context)36 NapiHiSysEventListener::NapiHiSysEventListener(CallbackContext* context)
37 {
38     callbackContext = context;
39     jsCallbackManager = std::make_shared<JsCallbackManager>();
40 }
41 
~NapiHiSysEventListener()42 NapiHiSysEventListener::~NapiHiSysEventListener()
43 {
44     if (jsCallbackManager != nullptr) {
45         jsCallbackManager->Release();
46     }
47     if (callbackContext->threadId == getproctid()) {
48         napi_delete_reference(callbackContext->env, callbackContext->ref);
49     }
50     delete callbackContext;
51 }
52 
OnEvent(const std::string & domain,const std::string & eventName,const int eventType,const std::string & eventDetail)53 void NapiHiSysEventListener::OnEvent(const std::string& domain, const std::string& eventName, const int eventType,
54     const std::string& eventDetail)
55 {
56     jsCallbackManager->Add(callbackContext,
57         [this, domain, eventName, eventType, eventDetail] (const napi_env env, const napi_ref ref, pid_t threadId) {
58             if (threadId != getproctid()) {
59                 return;
60             }
61             napi_value sysEventInfo = nullptr;
62             NapiHiSysEventUtil::CreateHiSysEventInfoJsObject(env, eventDetail, sysEventInfo);
63             napi_value argv[ON_EVENT_PARAM_COUNT] = {sysEventInfo};
64             napi_value listener = nullptr;
65             napi_status status = napi_get_reference_value(env, ref, &listener);
66             if (status != napi_ok) {
67                 HILOG_ERROR(LOG_CORE, "failed to get JS reference of event listener.");
68             }
69             napi_value onEvent = NapiHiSysEventUtil::GetPropertyByName(env, listener, ON_EVENT_ATTR);
70             napi_value ret = nullptr;
71             status = napi_call_function(env, listener, onEvent, ON_EVENT_PARAM_COUNT, argv, &ret);
72             if (status != napi_ok) {
73                 HILOG_ERROR(LOG_CORE, "failed to call onEvent JS function.");
74             }
75         });
76 }
77 
OnServiceDied()78 void NapiHiSysEventListener::OnServiceDied()
79 {
80     jsCallbackManager->Add(callbackContext,
81         [this] (const napi_env env, const napi_ref ref, pid_t threadId) {
82             if (threadId != getproctid()) {
83                 return;
84             }
85             napi_value listener = nullptr;
86             napi_status status = napi_get_reference_value(env, ref, &listener);
87             if (status != napi_ok) {
88                 HILOG_ERROR(LOG_CORE, "failed to get JS reference of event listener.");
89             }
90             napi_value onServiceDied = NapiHiSysEventUtil::GetPropertyByName(env, listener, ON_SERVICE_DIED_ATTR);
91             napi_value ret = nullptr;
92             status = napi_call_function(env, listener, onServiceDied, ON_SERVICE_DIED_PARAM_COUNT,
93                 nullptr, &ret);
94             if (status != napi_ok) {
95                 HILOG_ERROR(LOG_CORE, "failed to call onServiceDied JS function.");
96             }
97         });
98 }
99 } // HiviewDFX
100 } // OHOS