• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "motion_event_napi.h"
17 
18 #include "fi_log.h"
19 
20 #undef LOG_TAG
21 #define LOG_TAG "DeviceMotionEvent"
22 
23 namespace OHOS {
24 namespace Msdp {
MotionEventNapi(napi_env env,napi_value thisVar)25 MotionEventNapi::MotionEventNapi(napi_env env, napi_value thisVar)
26 {
27     env_ = env;
28     thisVarRef_ = nullptr;
29     napi_create_reference(env, thisVar, 1, &thisVarRef_);
30 }
31 
~MotionEventNapi()32 MotionEventNapi::~MotionEventNapi()
33 {
34     events_.clear();
35     if (env_ != nullptr && thisVarRef_ != nullptr) {
36         napi_delete_reference(env_, thisVarRef_);
37     }
38 }
39 
40 #ifdef MOTION_ENABLE
AddCallback(int32_t eventType,napi_value handler)41 bool MotionEventNapi::AddCallback(int32_t eventType, napi_value handler)
42 {
43     FI_HILOGD("Enter");
44     auto iter = events_.find(eventType);
45     if (iter == events_.end()) {
46         FI_HILOGD("found event:%{public}d", eventType);
47         std::shared_ptr<MotionEventListener> listener = std::make_shared<MotionEventListener>();
48         std::set<napi_ref> onRefSets;
49         listener->onRefSets = onRefSets;
50         napi_ref onHandlerRef = nullptr;
51         napi_status status = napi_create_reference(env_, handler, 1, &onHandlerRef);
52         if (status != napi_ok) {
53             FI_HILOGE("napi_create_reference failed");
54             return false;
55         }
56 
57         auto ret = listener->onRefSets.insert(onHandlerRef);
58         if (!ret.second) {
59             FI_HILOGE("Failed to insert refs");
60             return false;
61         }
62 
63         events_.insert(std::make_pair(eventType, listener));
64         FI_HILOGD("Insert finish");
65         return true;
66     }
67     FI_HILOGD("found event: %{public}d", eventType);
68     if (iter->second == nullptr) {
69         FI_HILOGE("listener is nullptr");
70         return false;
71     }
72     if (iter->second->onRefSets.empty()) {
73         FI_HILOGE("Refs is empty()");
74         return false;
75     }
76 
77     FI_HILOGD("Check type: %{public}d same handle", eventType);
78     if (!InsertRef(iter->second, handler)) {
79         FI_HILOGE("Failed to insert ref");
80         return false;
81     }
82     return true;
83 }
84 
RemoveCallback(int32_t eventType)85 bool MotionEventNapi::RemoveCallback(int32_t eventType)
86 {
87     FI_HILOGD("Enter, event:%{public}d", eventType);
88     auto iter = events_.find(eventType);
89     if (iter == events_.end()) {
90         FI_HILOGE("EventType %{public}d not found", eventType);
91         return false;
92     }
93 
94     if (iter->second == nullptr) {
95         FI_HILOGE("listener is nullptr");
96         return false;
97     }
98 
99     if (iter->second->onRefSets.empty()) {
100         FI_HILOGE("Refs is empty");
101         return false;
102     }
103 
104     for (auto it = iter->second->onRefSets.begin(); it != iter->second->onRefSets.end();) {
105         if (*it == nullptr) {
106             ++it;
107             continue;
108         }
109         napi_status status = napi_delete_reference(env_, *it);
110         if (status != napi_ok) {
111             FI_HILOGE("napi_delete_reference failed");
112             ++it;
113             continue;
114         }
115         it = iter->second->onRefSets.erase(it);
116     }
117     if (iter->second->onRefSets.empty()) {
118         FI_HILOGE("onRefSets is empty");
119         events_.erase(iter);
120     }
121     return true;
122 }
123 
InsertRef(std::shared_ptr<MotionEventListener> listener,const napi_value & handler)124 bool MotionEventNapi::InsertRef(std::shared_ptr<MotionEventListener> listener, const napi_value &handler)
125 {
126     if (listener == nullptr) {
127         FI_HILOGE("listener is nullptr");
128         return false;
129     }
130     for (auto item : listener->onRefSets) {
131         napi_value onHandler = nullptr;
132         napi_status status = napi_get_reference_value(env_, item, &onHandler);
133         if (status != napi_ok) {
134             FI_HILOGE("napi_get_reference_value failed");
135             status = napi_delete_reference(env_, item);
136             if (status != napi_ok) {
137                 FI_HILOGE("napi_delete_reference failed");
138                 continue;
139             }
140             continue;
141         }
142 
143         if (IsSameValue(env_, handler, onHandler)) {
144             continue;
145         }
146 
147         napi_ref onHandlerRef = nullptr;
148         status = napi_create_reference(env_, handler, 1, &(onHandlerRef));
149         if (status != napi_ok) {
150             FI_HILOGE("napi_create_reference failed");
151             return false;
152         }
153 
154         FI_HILOGD("Insert new ref");
155         auto ret = listener->onRefSets.insert(onHandlerRef);
156         if (!ret.second) {
157             FI_HILOGE("Failed to insert");
158             return false;
159         }
160     }
161     FI_HILOGD("ref size %{public}zu", listener->onRefSets.size());
162     return true;
163 }
164 
OnEventOperatingHand(int32_t eventType,size_t argc,const MotionEvent & event)165 void MotionEventNapi::OnEventOperatingHand(int32_t eventType, size_t argc, const MotionEvent &event)
166 {
167     FI_HILOGD("eventType: %{public}d", eventType);
168     auto typeIter = events_.find(eventType);
169     if (typeIter == events_.end()) {
170         FI_HILOGE("eventType: %{public}d not found", eventType);
171         return;
172     }
173     for (auto item : typeIter->second->onRefSets) {
174         napi_value handler = nullptr;
175         napi_status ret = napi_get_reference_value(env_, item, &handler);
176         if (ret != napi_ok) {
177             FI_HILOGE("napi_get_reference_value for %{public}d failed, status: %{public}d", eventType, ret);
178             return;
179         }
180         ConvertOperatingHandData(handler, argc, event);
181     }
182 }
183 
ConvertOperatingHandData(napi_value handler,size_t argc,const MotionEvent & event)184 void MotionEventNapi::ConvertOperatingHandData(napi_value handler, size_t argc, const MotionEvent &event)
185 {
186     napi_value result;
187     napi_status ret = napi_create_int32(env_, event.status, &result);
188     if (ret != napi_ok) {
189         FI_HILOGE("napi_create_int32 failed");
190         return;
191     }
192     napi_value callResult = nullptr;
193     ret = napi_call_function(env_, nullptr, handler, argc, &result, &callResult);
194     if (ret != napi_ok) {
195         FI_HILOGE("napi_call_function ret %{public}d", ret);
196         return;
197     }
198 }
199 
CreateIntData(napi_env env,napi_value motionValue,napi_value result,std::string name,int32_t value)200 void MotionEventNapi::CreateIntData(napi_env env, napi_value motionValue, napi_value result, std::string name,
201     int32_t value)
202 {
203     napi_status ret = napi_create_int32(env, value, &motionValue);
204     if (ret != napi_ok) {
205         FI_HILOGE("napi_create_int32 failed");
206         return;
207     }
208 
209     ret = napi_set_named_property(env, result, name.c_str(), motionValue);
210     if (ret != napi_ok) {
211         FI_HILOGE("napi_set_named_property failed");
212         return;
213     }
214 }
215 
IsSameValue(const napi_env & env,const napi_value & lhs,const napi_value & rhs)216 bool MotionEventNapi::IsSameValue(const napi_env &env, const napi_value &lhs, const napi_value &rhs)
217 {
218     FI_HILOGD("Enter");
219     bool result = false;
220     napi_status status = napi_strict_equals(env, lhs, rhs, &result);
221     if (status != napi_ok) {
222         FI_HILOGE("napi_strict_equals failed");
223         return result;
224     }
225     return result;
226 }
227 
CheckEvents(int32_t eventType)228 bool MotionEventNapi::CheckEvents(int32_t eventType)
229 {
230     FI_HILOGD("Enter");
231     auto typeIter = events_.find(eventType);
232     if (typeIter == events_.end()) {
233         FI_HILOGD("eventType not find");
234         return true;
235     }
236     if (typeIter->second->onRefSets.empty()) {
237         return true;
238     }
239     return false;
240 }
241 #endif
242 } // namespace Msdp
243 } // namespace OHOS
244