1 /*
2 * Copyright (c) 2022-2023 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 "dm_native_event.h"
17
18 #include "dm_log.h"
19
20 using namespace OHOS::DistributedHardware;
21
DmNativeEvent(napi_env env, napi_value thisVar)22 DmNativeEvent::DmNativeEvent(napi_env env, napi_value thisVar)
23 {
24 env_ = env;
25 thisVarRef_ = nullptr;
26 napi_create_reference(env, thisVar, 1, &thisVarRef_);
27 }
28
~DmNativeEvent()29 DmNativeEvent::~DmNativeEvent()
30 {
31 for (auto iter = eventMap_.begin(); iter != eventMap_.end(); iter++) {
32 auto listener = iter->second;
33 CHECK_NULL_VOID(listener);
34 napi_delete_reference(env_, listener->handlerRef);
35 }
36 eventMap_.clear();
37 napi_delete_reference(env_, thisVarRef_);
38 }
39
On(std::string &eventType, napi_value handler)40 void DmNativeEvent::On(std::string &eventType, napi_value handler)
41 {
42 LOGI("DmNativeEvent On in for event: %{public}s", eventType.c_str());
43 std::lock_guard<std::mutex> autoLock(lock_);
44 auto listener = std::make_shared<DmEventListener>();
45 listener->eventType = eventType;
46 napi_create_reference(env_, handler, 1, &listener->handlerRef);
47 eventMap_[eventType] = listener;
48 }
49
Off(std::string &eventType)50 void DmNativeEvent::Off(std::string &eventType)
51 {
52 LOGI("DmNativeEvent Off in for event: %{public}s", eventType.c_str());
53 napi_handle_scope scope = nullptr;
54 napi_open_handle_scope(env_, &scope);
55 if (scope == nullptr) {
56 LOGE("scope is nullptr");
57 return;
58 }
59
60 std::lock_guard<std::mutex> autoLock(lock_);
61 auto iter = eventMap_.find(eventType);
62 if (iter == eventMap_.end()) {
63 LOGE("eventType %{public}s not find", eventType.c_str());
64 napi_close_handle_scope(env_, scope);
65 return;
66 }
67 auto listener = iter->second;
68 napi_delete_reference(env_, listener->handlerRef);
69 eventMap_.erase(eventType);
70 napi_close_handle_scope(env_, scope);
71 }
72
OnEvent(const std::string &eventType, size_t argc, const napi_value *argv)73 void DmNativeEvent::OnEvent(const std::string &eventType, size_t argc, const napi_value *argv)
74 {
75 LOGI("OnEvent for %{public}s", eventType.c_str());
76 napi_handle_scope scope = nullptr;
77 napi_open_handle_scope(env_, &scope);
78 if (scope == nullptr) {
79 LOGE("scope is nullptr");
80 return;
81 }
82
83 std::lock_guard<std::mutex> autoLock(lock_);
84 auto iter = eventMap_.find(eventType);
85 if (iter == eventMap_.end()) {
86 LOGE("eventType %{public}s not find", eventType.c_str());
87 napi_close_handle_scope(env_, scope);
88 return;
89 }
90 auto listener = iter->second;
91 napi_value thisVar = nullptr;
92 napi_status status = napi_get_reference_value(env_, thisVarRef_, &thisVar);
93 if (status != napi_ok) {
94 LOGE("napi_get_reference_value thisVar for %{public}s failed, status = %{public}d", eventType.c_str(), status);
95 napi_close_handle_scope(env_, scope);
96 return;
97 }
98
99 napi_value handler = nullptr;
100 status = napi_get_reference_value(env_, listener->handlerRef, &handler);
101 if (status != napi_ok) {
102 LOGE("napi_get_reference_value handler for %{public}s failed, status = %{public}d", eventType.c_str(), status);
103 napi_close_handle_scope(env_, scope);
104 return;
105 }
106
107 napi_value callResult = nullptr;
108 status = napi_call_function(env_, thisVar, handler, argc, argv, &callResult);
109 if (status != napi_ok) {
110 LOGE("napi_call_function for %{public}s failed, status = %{public}d", eventType.c_str(), status);
111 napi_close_handle_scope(env_, scope);
112 return;
113 }
114 napi_close_handle_scope(env_, scope);
115 }
116