• 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 
RemoveAllCallback(int32_t eventType)85 bool MotionEventNapi::RemoveAllCallback(int32_t eventType)
86 {
87     FI_HILOGD("RemoveAllCallback in, 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     if (iter->second == nullptr) {
94         FI_HILOGE("listener is nullptr");
95         return false;
96     }
97     if (iter->second->onRefSets.empty()) {
98         FI_HILOGE("onRefSets is empty");
99         return false;
100     }
101     for (auto it = iter->second->onRefSets.begin(); it != iter->second->onRefSets.end();) {
102         if (*it == nullptr) {
103             ++it;
104             continue;
105         }
106         napi_status status = napi_delete_reference(env_, *it);
107         if (status != napi_ok) {
108             FI_HILOGE("napi_delete_reference failed");
109             ++it;
110             continue;
111         }
112         it = iter->second->onRefSets.erase(it);
113     }
114     if (iter->second->onRefSets.empty()) {
115         FI_HILOGE("onRefSets is empty");
116         events_.erase(iter);
117     }
118     return true;
119 }
120 
RemoveCallback(int32_t eventType,napi_value handler)121 bool MotionEventNapi::RemoveCallback(int32_t eventType, napi_value handler)
122 {
123     FI_HILOGD("RemoveCallback in, event:%{public}d", eventType);
124     auto iter = events_.find(eventType);
125     if (iter == events_.end()) {
126         FI_HILOGE("EventType %{public}d not found", eventType);
127         return false;
128     }
129     if (iter->second == nullptr) {
130         FI_HILOGE("listener is nullptr");
131         return false;
132     }
133     if (iter->second->onRefSets.empty()) {
134         FI_HILOGE("onRefSets is empty");
135         return false;
136     }
137     for (auto it = iter->second->onRefSets.begin(); it != iter->second->onRefSets.end();) {
138         if (*it == nullptr) {
139             ++it;
140             continue;
141         }
142         napi_value deleteHandler;
143         napi_status status = napi_get_reference_value(env_, *it, &deleteHandler);
144         if (status != napi_ok) {
145             FI_HILOGE("napi_get_reference_value failed");
146             ++it;
147             continue;
148         }
149         if (IsSameValue(env_, handler, deleteHandler)) {
150             status = napi_delete_reference(env_, *it);
151             if (status != napi_ok) {
152                 FI_HILOGE("napi_delete_reference failed");
153                 ++it;
154                 continue;
155             }
156             iter->second->onRefSets.erase(it++);
157             break;
158         }
159         ++it;
160     }
161     if (iter->second->onRefSets.empty()) {
162         events_.erase(eventType);
163     }
164     return true;
165 }
166 
InsertRef(std::shared_ptr<MotionEventListener> listener,const napi_value & handler)167 bool MotionEventNapi::InsertRef(std::shared_ptr<MotionEventListener> listener, const napi_value &handler)
168 {
169     if (listener == nullptr) {
170         FI_HILOGE("listener is nullptr");
171         return false;
172     }
173     bool hasHandler = false;
174     for (auto item : listener->onRefSets) {
175         napi_value onHandler = nullptr;
176         napi_status status = napi_get_reference_value(env_, item, &onHandler);
177         if (status != napi_ok) {
178             FI_HILOGE("napi_get_reference_value failed");
179             status = napi_delete_reference(env_, item);
180             if (status != napi_ok) {
181                 FI_HILOGE("napi_delete_reference failed");
182                 continue;
183             }
184             continue;
185         }
186         if (IsSameValue(env_, handler, onHandler)) {
187             hasHandler = true;
188             break;
189         }
190     }
191     if (hasHandler) {
192         FI_HILOGD("napi repeat subscribe");
193         return true;
194     }
195     napi_ref onHandlerRef = nullptr;
196     napi_status status = napi_create_reference(env_, handler, 1, &(onHandlerRef));
197     if (status != napi_ok) {
198         FI_HILOGE("napi_create_reference failed");
199         return false;
200     }
201 
202     FI_HILOGD("Insert new ref");
203     auto ret = listener->onRefSets.insert(onHandlerRef);
204     if (!ret.second) {
205         FI_HILOGE("Failed to insert");
206         return false;
207     }
208     FI_HILOGD("ref size %{public}zu", listener->onRefSets.size());
209     return true;
210 }
211 
OnEventOperatingHand(int32_t eventType,size_t argc,const MotionEvent & event)212 void MotionEventNapi::OnEventOperatingHand(int32_t eventType, size_t argc, const MotionEvent &event)
213 {
214     FI_HILOGD("eventType: %{public}d", eventType);
215     auto typeIter = events_.find(eventType);
216     if (typeIter == events_.end()) {
217         FI_HILOGE("eventType: %{public}d not found", eventType);
218         return;
219     }
220     for (auto item : typeIter->second->onRefSets) {
221         napi_value handler = nullptr;
222         napi_status ret = napi_get_reference_value(env_, item, &handler);
223         if (ret != napi_ok) {
224             FI_HILOGE("napi_get_reference_value for %{public}d failed, status: %{public}d", eventType, ret);
225             return;
226         }
227         ConvertOperatingHandData(handler, argc, event);
228     }
229 }
230 
ConvertOperatingHandData(napi_value handler,size_t argc,const MotionEvent & event)231 void MotionEventNapi::ConvertOperatingHandData(napi_value handler, size_t argc, const MotionEvent &event)
232 {
233     napi_value result;
234     napi_status ret = napi_create_int32(env_, event.status, &result);
235     if (ret != napi_ok) {
236         FI_HILOGE("napi_create_int32 failed");
237         return;
238     }
239     napi_value callResult = nullptr;
240     ret = napi_call_function(env_, nullptr, handler, argc, &result, &callResult);
241     if (ret != napi_ok) {
242         FI_HILOGE("napi_call_function ret %{public}d", ret);
243         return;
244     }
245 }
246 
CreateIntData(napi_env env,napi_value motionValue,napi_value result,std::string name,int32_t value)247 void MotionEventNapi::CreateIntData(napi_env env, napi_value motionValue, napi_value result, std::string name,
248     int32_t value)
249 {
250     napi_status ret = napi_create_int32(env, value, &motionValue);
251     if (ret != napi_ok) {
252         FI_HILOGE("napi_create_int32 failed");
253         return;
254     }
255 
256     ret = napi_set_named_property(env, result, name.c_str(), motionValue);
257     if (ret != napi_ok) {
258         FI_HILOGE("napi_set_named_property failed");
259         return;
260     }
261 }
262 
IsSameValue(const napi_env & env,const napi_value & lhs,const napi_value & rhs)263 bool MotionEventNapi::IsSameValue(const napi_env &env, const napi_value &lhs, const napi_value &rhs)
264 {
265     FI_HILOGD("Enter");
266     bool result = false;
267     napi_status status = napi_strict_equals(env, lhs, rhs, &result);
268     if (status != napi_ok) {
269         FI_HILOGE("napi_strict_equals failed");
270         return result;
271     }
272     return result;
273 }
274 
CheckEvents(int32_t eventType)275 bool MotionEventNapi::CheckEvents(int32_t eventType)
276 {
277     FI_HILOGD("Enter");
278     auto typeIter = events_.find(eventType);
279     if (typeIter == events_.end()) {
280         FI_HILOGD("eventType not find");
281         return true;
282     }
283     if (typeIter->second->onRefSets.empty()) {
284         return true;
285     }
286     return false;
287 }
288 #endif
289 } // namespace Msdp
290 } // namespace OHOS
291