1 /*
2  * Copyright (c) 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 "ui_observer_listener.h"
17 #include <cstdint>
18 
19 #include "core/pipeline/pipeline_base.h"
20 #include "frameworks/bridge/declarative_frontend/engine/jsi/jsi_types.h"
21 #include "frameworks/bridge/declarative_frontend/engine/jsi/jsi_declarative_engine.h"
22 #include "core/interfaces/native/node/node_api.h"
23 #include "core/components_ng/common_napi_utils/common_napi_utils.h"
24 #include "frameworks/base/geometry/dimension.h"
25 
26 namespace OHOS::Ace::Napi {
27 namespace {
28 constexpr char NAV_BAR[] = "navBar";
29 constexpr int32_t PARAM_SIZE_TWO = 2;
30 constexpr int32_t PARAM_SIZE_SIX = 6;
31 }
32 
OnNavigationStateChange(const NG::NavDestinationInfo & info)33 void UIObserverListener::OnNavigationStateChange(const NG::NavDestinationInfo& info)
34 {
35     if (!env_ || !callback_) {
36         TAG_LOGW(AceLogTag::ACE_OBSERVER,
37             "Handle navDestination state change failed, runtime or callback function invalid!");
38         return;
39     }
40     napi_handle_scope scope = nullptr;
41     auto status = napi_open_handle_scope(env_, &scope);
42     if (status != napi_ok) {
43         return;
44     }
45     napi_value callback = nullptr;
46     napi_get_reference_value(env_, callback_, &callback);
47     napi_value argv[] = { CreateNavDestinationInfoObj(info) };
48     napi_call_function(env_, nullptr, callback, 1, argv, nullptr);
49     napi_close_handle_scope(env_, scope);
50 }
51 
OnScrollEventStateChange(const std::string & id,int32_t uniqueId,NG::ScrollEventType eventType,float offset)52 void UIObserverListener::OnScrollEventStateChange(
53     const std::string& id, int32_t uniqueId, NG::ScrollEventType eventType, float offset)
54 {
55     if (!env_ || !callback_) {
56         TAG_LOGW(AceLogTag::ACE_OBSERVER,
57             "Handle scrollEvent state change failed, runtime or callback function invalid!");
58         return;
59     }
60     napi_value callback = nullptr;
61     napi_get_reference_value(env_, callback_, &callback);
62     napi_value objValue = nullptr;
63     napi_create_object(env_, &objValue);
64     napi_value scrollId = nullptr;
65     napi_value frameNodeId = nullptr;
66     napi_value scrollEventType = nullptr;
67     napi_value scrollOffset = nullptr;
68     napi_create_string_utf8(env_, id.c_str(), id.length(), &scrollId);
69     napi_create_int32(env_, uniqueId, &frameNodeId);
70     napi_create_int32(env_, static_cast<int32_t>(eventType), &scrollEventType);
71     napi_create_double(env_, offset, &scrollOffset);
72     napi_set_named_property(env_, objValue, "id", scrollId);
73     napi_set_named_property(env_, objValue, "uniqueId", frameNodeId);
74     napi_set_named_property(env_, objValue, "scrollEvent", scrollEventType);
75     napi_set_named_property(env_, objValue, "offset", scrollOffset);
76     napi_value argv[] = { objValue };
77     napi_call_function(env_, nullptr, callback, 1, argv, nullptr);
78 }
79 
OnRouterPageStateChange(const NG::RouterPageInfoNG & pageInfo)80 void UIObserverListener::OnRouterPageStateChange(const NG::RouterPageInfoNG& pageInfo)
81 {
82     if (!env_ || !callback_) {
83         TAG_LOGW(AceLogTag::ACE_OBSERVER,
84             "Handle router page state change failed, runtime or callback function invalid!");
85         return;
86     }
87     napi_handle_scope scope = nullptr;
88     auto status = napi_open_handle_scope(env_, &scope);
89     if (status != napi_ok) {
90         return;
91     }
92     napi_value callback = nullptr;
93     napi_get_reference_value(env_, callback_, &callback);
94     napi_value objValue = nullptr;
95     napi_create_object(env_, &objValue);
96     napi_value napiCtx = pageInfo.context;
97     napi_value napiIndex = nullptr;
98     napi_value napiName = nullptr;
99     napi_value napiPath = nullptr;
100     napi_value napiState = nullptr;
101     napi_value napiPageId = nullptr;
102     napi_create_int32(env_, pageInfo.index, &napiIndex);
103     napi_create_string_utf8(env_, pageInfo.name.c_str(), pageInfo.name.length(), &napiName);
104     napi_create_string_utf8(env_, pageInfo.path.c_str(), pageInfo.path.length(), &napiPath);
105     napi_create_int32(env_, static_cast<int32_t>(pageInfo.state), &napiState);
106     napi_create_string_utf8(env_, pageInfo.pageId.c_str(), pageInfo.pageId.length(), &napiPageId);
107     napi_set_named_property(env_, objValue, "context", napiCtx);
108     napi_set_named_property(env_, objValue, "index", napiIndex);
109     napi_set_named_property(env_, objValue, "name", napiName);
110     napi_set_named_property(env_, objValue, "path", napiPath);
111     napi_set_named_property(env_, objValue, "state", napiState);
112     napi_set_named_property(env_, objValue, "pageId", napiPageId);
113     napi_value argv[] = { objValue };
114     napi_call_function(env_, nullptr, callback, 1, argv, nullptr);
115     napi_close_handle_scope(env_, scope);
116 }
117 
OnDensityChange(double density)118 void UIObserverListener::OnDensityChange(double density)
119 {
120     if (!env_ || !callback_) {
121         TAG_LOGW(AceLogTag::ACE_OBSERVER,
122             "Handle density change failed, runtime or callback function invalid!");
123         return;
124     }
125     napi_value callback = nullptr;
126     napi_get_reference_value(env_, callback_, &callback);
127     napi_value objValue = nullptr;
128     napi_create_object(env_, &objValue);
129     napi_value napiDensity = nullptr;
130     napi_create_double(env_, density, &napiDensity);
131     napi_set_named_property(env_, objValue, "density", napiDensity);
132     napi_value argv[] = { objValue };
133     napi_call_function(env_, nullptr, callback, 1, argv, nullptr);
134 }
135 
OnDrawOrLayout()136 void UIObserverListener::OnDrawOrLayout()
137 {
138     if (!env_ || !callback_) {
139         return;
140     }
141     napi_value callback = nullptr;
142     napi_get_reference_value(env_, callback_, &callback);
143     napi_value objValue = nullptr;
144     napi_create_object(env_, &objValue);
145     napi_value argv[] = { objValue };
146     napi_call_function(env_, nullptr, callback, 1, argv, nullptr);
147 }
148 
OnNavDestinationSwitch(const NG::NavDestinationSwitchInfo & switchInfo)149 void UIObserverListener::OnNavDestinationSwitch(const NG::NavDestinationSwitchInfo& switchInfo)
150 {
151     if (!env_ || !callback_) {
152         TAG_LOGW(AceLogTag::ACE_OBSERVER,
153             "Handle navDestination switch failed, runtime or callback function invalid!");
154         return;
155     }
156     napi_handle_scope scope = nullptr;
157     auto status = napi_open_handle_scope(env_, &scope);
158     if (status != napi_ok) {
159         return;
160     }
161     napi_value callback = nullptr;
162     napi_get_reference_value(env_, callback_, &callback);
163     napi_value argv[] = { CreateNavDestinationSwitchInfoObj(switchInfo) };
164     napi_call_function(env_, nullptr, callback, 1, argv, nullptr);
165     napi_close_handle_scope(env_, scope);
166 }
167 
CreateNavDestinationSwitchInfoObj(const NG::NavDestinationSwitchInfo & switchInfo)168 napi_value UIObserverListener::CreateNavDestinationSwitchInfoObj(const NG::NavDestinationSwitchInfo& switchInfo)
169 {
170     napi_value objValue = nullptr;
171     napi_create_object(env_, &objValue);
172     napi_value napiOperation = nullptr;
173     napi_value napiFrom = nullptr;
174     if (switchInfo.from.has_value()) {
175         napiFrom = CreateNavDestinationInfoObj(switchInfo.from.value());
176     } else {
177         napi_create_string_utf8(env_, NAV_BAR, NAPI_AUTO_LENGTH, &napiFrom);
178     }
179     napi_value napiTo = nullptr;
180     if (switchInfo.to.has_value()) {
181         napiTo = CreateNavDestinationInfoObj(switchInfo.to.value());
182     } else {
183         napi_create_string_utf8(env_, NAV_BAR, NAPI_AUTO_LENGTH, &napiTo);
184     }
185     napi_create_int32(env_, static_cast<int32_t>(switchInfo.operation), &napiOperation);
186     napi_set_named_property(env_, objValue, "context", switchInfo.context);
187     napi_set_named_property(env_, objValue, "from", napiFrom);
188     napi_set_named_property(env_, objValue, "to", napiTo);
189     napi_set_named_property(env_, objValue, "operation", napiOperation);
190     return objValue;
191 }
192 
OnWillClick(const GestureEvent & gestureEventInfo,const ClickInfo & clickInfo,const RefPtr<NG::FrameNode> frameNode)193 void UIObserverListener::OnWillClick(
194     const GestureEvent& gestureEventInfo, const ClickInfo& clickInfo, const RefPtr<NG::FrameNode> frameNode)
195 {
196     if (!env_ || !callback_) {
197         TAG_LOGW(AceLogTag::ACE_OBSERVER,
198             "Handle density change failed, runtime or callback function invalid!");
199         return;
200     }
201     napi_handle_scope scope = nullptr;
202     auto status = napi_open_handle_scope(env_, &scope);
203     if (status != napi_ok) {
204         return;
205     }
206 
207     napi_value callback = nullptr;
208     napi_get_reference_value(env_, callback_, &callback);
209 
210     napi_value objValueClickEvent = nullptr;
211     napi_create_object(env_, &objValueClickEvent);
212 
213     AddBaseEventInfo(objValueClickEvent, clickInfo);
214     AddGestureEventInfoOne(objValueClickEvent, gestureEventInfo);
215     AddGestureEventInfoTwo(objValueClickEvent, gestureEventInfo);
216     AddGestureEventInfoThree(objValueClickEvent, gestureEventInfo);
217     AddClickEventInfoOne(objValueClickEvent, clickInfo);
218     AddClickEventInfoTwo(objValueClickEvent, clickInfo);
219 
220     napi_value objValueFrameNode = nullptr;
221     napi_create_object(env_, &objValueFrameNode);
222 
223     auto container = Container::Current();
224     CHECK_NULL_VOID(container);
225     auto frontEnd = container->GetFrontend();
226     CHECK_NULL_VOID(frontEnd);
227     auto nodeId = frameNode->GetId();
228     objValueFrameNode = frontEnd->GetFrameNodeValueByNodeId(nodeId);
229 
230     napi_value argv[] = { objValueClickEvent, objValueFrameNode };
231     napi_call_function(env_, nullptr, callback, PARAM_SIZE_TWO, argv, nullptr);
232     napi_close_handle_scope(env_, scope);
233 }
234 
OnDidClick(const GestureEvent & gestureEventInfo,const ClickInfo & clickInfo,const RefPtr<NG::FrameNode> frameNode)235 void UIObserverListener::OnDidClick(
236     const GestureEvent& gestureEventInfo, const ClickInfo& clickInfo, const RefPtr<NG::FrameNode> frameNode)
237 {
238     if (!env_ || !callback_) {
239         TAG_LOGW(AceLogTag::ACE_OBSERVER,
240             "Handle density change failed, runtime or callback function invalid!");
241         return;
242     }
243     napi_handle_scope scope = nullptr;
244     auto status = napi_open_handle_scope(env_, &scope);
245     if (status != napi_ok) {
246         return;
247     }
248 
249     napi_value callback = nullptr;
250     napi_get_reference_value(env_, callback_, &callback);
251 
252     napi_value objValueClickEvent = nullptr;
253     napi_create_object(env_, &objValueClickEvent);
254 
255     AddBaseEventInfo(objValueClickEvent, clickInfo);
256     AddGestureEventInfoOne(objValueClickEvent, gestureEventInfo);
257     AddGestureEventInfoTwo(objValueClickEvent, gestureEventInfo);
258     AddGestureEventInfoThree(objValueClickEvent, gestureEventInfo);
259     AddClickEventInfoOne(objValueClickEvent, clickInfo);
260     AddClickEventInfoTwo(objValueClickEvent, clickInfo);
261 
262     napi_value objValueFrameNode = nullptr;
263     napi_create_object(env_, &objValueFrameNode);
264 
265     auto container = Container::Current();
266     CHECK_NULL_VOID(container);
267     auto frontEnd = container->GetFrontend();
268     CHECK_NULL_VOID(frontEnd);
269     auto nodeId = frameNode->GetId();
270     objValueFrameNode = frontEnd->GetFrameNodeValueByNodeId(nodeId);
271 
272     napi_value argv[] = { objValueClickEvent, objValueFrameNode };
273     napi_call_function(env_, nullptr, callback, PARAM_SIZE_TWO, argv, nullptr);
274     napi_close_handle_scope(env_, scope);
275 }
276 
OnTabContentStateChange(const NG::TabContentInfo & tabContentInfo)277 void UIObserverListener::OnTabContentStateChange(const NG::TabContentInfo& tabContentInfo)
278 {
279     if (!env_ || !callback_) {
280         TAG_LOGW(AceLogTag::ACE_OBSERVER,
281             "Handle tabContent state change failed, runtime or callback function invalid!");
282         return;
283     }
284     napi_value callback = nullptr;
285     napi_get_reference_value(env_, callback_, &callback);
286     napi_value objValue = nullptr;
287     napi_value param1 = nullptr;
288     napi_value param2 = nullptr;
289     napi_value param3 = nullptr;
290     napi_value param4 = nullptr;
291     napi_value param5 = nullptr;
292     napi_value param6 = nullptr;
293     napi_create_string_utf8(env_, tabContentInfo.tabContentId.c_str(), tabContentInfo.tabContentId.length(), &param1);
294     napi_create_int32(env_, tabContentInfo.tabContentUniqueId, &param2);
295     napi_create_int32(env_, static_cast<int32_t>(tabContentInfo.state), &param3);
296     napi_create_int32(env_, tabContentInfo.index, &param4);
297     napi_create_string_utf8(env_, tabContentInfo.id.c_str(), tabContentInfo.id.length(), &param5);
298     napi_create_int32(env_, tabContentInfo.uniqueId, &param6);
299     const char *keys[] = {
300         "tabContentId",
301         "tabContentUniqueId",
302         "state",
303         "index",
304         "id",
305         "uniqueId",
306     };
307     const napi_value values[] = {
308         param1,
309         param2,
310         param3,
311         param4,
312         param5,
313         param6,
314     };
315     napi_create_object_with_named_properties(env_, &objValue, PARAM_SIZE_SIX, keys, values);
316     napi_value argv[] = { objValue };
317     napi_call_function(env_, nullptr, callback, 1, argv, nullptr);
318 }
319 
GetValueType(napi_env env,napi_value value)320 napi_valuetype UIObserverListener::GetValueType(napi_env env, napi_value value)
321 {
322     if (value == nullptr) {
323         return napi_undefined;
324     }
325 
326     napi_valuetype valueType = napi_undefined;
327     NAPI_CALL_BASE(env, napi_typeof(env, value, &valueType), napi_undefined);
328     return valueType;
329 }
330 
GetNamedProperty(napi_env env,napi_value object,const std::string & propertyName)331 napi_value UIObserverListener::GetNamedProperty(napi_env env, napi_value object, const std::string& propertyName)
332 {
333     if (GetValueType(env, object) != napi_object) {
334         napi_value undefined = nullptr;
335         NAPI_CALL(env, napi_get_undefined(env, &undefined));
336         return undefined;
337     }
338 
339     napi_value value = nullptr;
340     NAPI_CALL(env, napi_get_named_property(env, object, propertyName.c_str(), &value));
341     return value;
342 }
343 
AddBaseEventInfo(napi_value objValueClickEvent,const ClickInfo & clickInfo)344 void UIObserverListener::AddBaseEventInfo(napi_value objValueClickEvent, const ClickInfo& clickInfo)
345 {
346     napi_handle_scope scope = nullptr;
347     auto status = napi_open_handle_scope(env_, &scope);
348     if (status != napi_ok) {
349         return;
350     }
351 
352     napi_value napiTimeStamp = nullptr;
353     napi_value napiSource = nullptr;
354     napi_value napiPressure = nullptr;
355     napi_value napiTiltX = nullptr;
356     napi_value napiTiltY = nullptr;
357     napi_value napiSourceTool = nullptr;
358 
359     napi_create_double(env_,
360         static_cast<double>(clickInfo.GetTimeStamp().time_since_epoch().count()), &napiTimeStamp);
361     napi_create_double(env_, static_cast<int32_t>(clickInfo.GetSourceDevice()), &napiSource);
362     napi_create_double(env_, clickInfo.GetForce(), &napiPressure);
363     if (clickInfo.GetTiltX().has_value()) {
364         napi_create_double(env_, clickInfo.GetTiltX().value(), &napiTiltX);
365     }
366     if (clickInfo.GetTiltY().has_value()) {
367         napi_create_double(env_, clickInfo.GetTiltY().value(), &napiTiltY);
368     }
369     napi_create_double(env_, static_cast<int32_t>(clickInfo.GetSourceTool()), &napiSourceTool);
370 
371     napi_set_named_property(env_, objValueClickEvent, "timestamp", napiTimeStamp);
372     napi_set_named_property(env_, objValueClickEvent, "source", napiSource);
373     napi_set_named_property(env_, objValueClickEvent, "pressure", napiPressure);
374     napi_set_named_property(env_, objValueClickEvent, "tiltX", napiTiltX);
375     napi_set_named_property(env_, objValueClickEvent, "tiltY", napiTiltY);
376     napi_set_named_property(env_, objValueClickEvent, "sourceTool", napiSourceTool);
377 
378     napi_close_handle_scope(env_, scope);
379 }
380 
AddGestureEventInfoOne(napi_value objValueClickEvent,const GestureEvent & gestureEventInfo)381 void UIObserverListener::AddGestureEventInfoOne(napi_value objValueClickEvent, const GestureEvent& gestureEventInfo)
382 {
383     napi_handle_scope scope = nullptr;
384     auto status = napi_open_handle_scope(env_, &scope);
385     if (status != napi_ok) {
386         return;
387     }
388     double scale = Dimension(1.0, DimensionUnit::VP).ConvertToPx();
389     if (NearZero(scale)) {
390         scale = 1.0;
391     }
392     napi_value napiRepeat = GetNamedProperty(env_, objValueClickEvent, "repeat");
393     if (GetValueType(env_, napiRepeat) != napi_null) {
394         napi_get_boolean(env_, gestureEventInfo.GetRepeat(), &napiRepeat);
395         napi_set_named_property(env_, objValueClickEvent, "repeat", napiRepeat);
396     }
397     napi_value napiOffsetX = GetNamedProperty(env_, objValueClickEvent, "offsetX");
398     if (GetValueType(env_, napiOffsetX) != napi_null) {
399         napi_create_double(env_, gestureEventInfo.GetOffsetX() / scale, &napiOffsetX);
400         napi_set_named_property(env_, objValueClickEvent, "offsetX", napiOffsetX);
401     }
402     napi_value napiOffsetY = GetNamedProperty(env_, objValueClickEvent, "offsetY");
403     if (GetValueType(env_, napiOffsetY) != napi_null) {
404         napi_create_double(env_, gestureEventInfo.GetOffsetY() / scale, &napiOffsetY);
405         napi_set_named_property(env_, objValueClickEvent, "offsetY", napiOffsetY);
406     }
407     napi_value napiScale = GetNamedProperty(env_, objValueClickEvent, "scale");
408     if (GetValueType(env_, napiScale) != napi_null) {
409         napi_create_double(env_, gestureEventInfo.GetScale(), &napiScale);
410         napi_set_named_property(env_, objValueClickEvent, "scale", napiScale);
411     }
412     napi_value napiAngle = GetNamedProperty(env_, objValueClickEvent, "angle");
413     if (GetValueType(env_, napiAngle) != napi_null) {
414         napi_create_double(env_, gestureEventInfo.GetAngle() / scale, &napiAngle);
415         napi_set_named_property(env_, objValueClickEvent, "angle", napiAngle);
416     }
417     napi_value napiSpeed = GetNamedProperty(env_, objValueClickEvent, "speed");
418     if (GetValueType(env_, napiSpeed) != napi_null) {
419         napi_create_double(env_, gestureEventInfo.GetSpeed() / scale, &napiSpeed);
420         napi_set_named_property(env_, objValueClickEvent, "speed", napiSpeed);
421     }
422     napi_close_handle_scope(env_, scope);
423 }
424 
AddGestureEventInfoTwo(napi_value objValueClickEvent,const GestureEvent & gestureEventInfo)425 void UIObserverListener::AddGestureEventInfoTwo(napi_value objValueClickEvent, const GestureEvent& gestureEventInfo)
426 {
427     napi_handle_scope scope = nullptr;
428     auto status = napi_open_handle_scope(env_, &scope);
429     if (status != napi_ok) {
430         return;
431     }
432     double scale = Dimension(1.0, DimensionUnit::VP).ConvertToPx();
433     if (NearZero(scale)) {
434         scale = 1.0;
435     }
436     napi_value napiGlobalX = GetNamedProperty(env_, objValueClickEvent, "globalX");
437     if (GetValueType(env_, napiGlobalX) != napi_null) {
438         napi_create_double(env_, gestureEventInfo.GetGlobalLocation().GetX() / scale, &napiGlobalX);
439         napi_set_named_property(env_, objValueClickEvent, "globalX", napiGlobalX);
440     }
441     napi_value napiGlobalY = GetNamedProperty(env_, objValueClickEvent, "globalY");
442     if (GetValueType(env_, napiGlobalY) != napi_null) {
443         napi_create_double(env_, gestureEventInfo.GetGlobalLocation().GetY() / scale, &napiGlobalY);
444         napi_set_named_property(env_, objValueClickEvent, "globalY", napiGlobalY);
445     }
446     napi_value napiLocalX = GetNamedProperty(env_, objValueClickEvent, "localX");
447     if (GetValueType(env_, napiLocalX) != napi_null) {
448         napi_create_double(env_, gestureEventInfo.GetLocalLocation().GetX() / scale, &napiLocalX);
449         napi_set_named_property(env_, objValueClickEvent, "localX", napiLocalX);
450     }
451     napi_value napiLocalY = GetNamedProperty(env_, objValueClickEvent, "localY");
452     if (GetValueType(env_, napiLocalY) != napi_null) {
453         napi_create_double(env_, gestureEventInfo.GetLocalLocation().GetY() / scale, &napiLocalY);
454         napi_set_named_property(env_, objValueClickEvent, "localY", napiLocalY);
455     }
456     napi_value napiPinchCenterX = GetNamedProperty(env_, objValueClickEvent, "pinchCenterX");
457     if (GetValueType(env_, napiPinchCenterX) != napi_null) {
458         napi_create_double(env_, gestureEventInfo.GetPinchCenter().GetX() / scale, &napiPinchCenterX);
459         napi_set_named_property(env_, objValueClickEvent, "pinchCenterX", napiPinchCenterX);
460     }
461     napi_value napiPinchCenterY = GetNamedProperty(env_, objValueClickEvent, "pinchCenterY");
462     if (GetValueType(env_, napiPinchCenterY) != napi_null) {
463         napi_create_double(env_, gestureEventInfo.GetPinchCenter().GetY() / scale, &napiPinchCenterY);
464         napi_set_named_property(env_, objValueClickEvent, "pinchCenterY", napiPinchCenterY);
465     }
466     napi_close_handle_scope(env_, scope);
467 }
468 
AddGestureEventInfoThree(napi_value objValueClickEvent,const GestureEvent & gestureEventInfo)469 void UIObserverListener::AddGestureEventInfoThree(napi_value objValueClickEvent, const GestureEvent& gestureEventInfo)
470 {
471     napi_handle_scope scope = nullptr;
472     auto status = napi_open_handle_scope(env_, &scope);
473     if (status != napi_ok) {
474         return;
475     }
476     double scale = Dimension(1.0, DimensionUnit::VP).ConvertToPx();
477     if (NearZero(scale)) {
478         scale = 1.0;
479     }
480     napi_value napiVelocityX = GetNamedProperty(env_, objValueClickEvent, "velocityX");
481     if (GetValueType(env_, napiVelocityX) != napi_null) {
482         napi_create_double(env_, gestureEventInfo.GetVelocity().GetVelocityX() / scale, &napiVelocityX);
483         napi_set_named_property(env_, objValueClickEvent, "velocityX", napiVelocityX);
484     }
485     napi_value napiVelocityY = GetNamedProperty(env_, objValueClickEvent, "velocityY");
486     if (GetValueType(env_, napiVelocityY) != napi_null) {
487         napi_create_double(env_, gestureEventInfo.GetVelocity().GetVelocityY() / scale, &napiVelocityY);
488         napi_set_named_property(env_, objValueClickEvent, "velocityY", napiVelocityY);
489     }
490     napi_value napiVelocity = GetNamedProperty(env_, objValueClickEvent, "velocity");
491     if (GetValueType(env_, napiVelocity) != napi_null) {
492         napi_create_double(env_, gestureEventInfo.GetVelocity().GetVelocityValue() / scale, &napiVelocity);
493         napi_set_named_property(env_, objValueClickEvent, "velocity", napiVelocity);
494     }
495     AddFingerListInfo(objValueClickEvent, gestureEventInfo);
496     napi_close_handle_scope(env_, scope);
497 }
498 
AddFingerListInfo(napi_value objValueClickEvent,const GestureEvent & gestureEventInfo)499 void UIObserverListener::AddFingerListInfo(napi_value objValueClickEvent, const GestureEvent& gestureEventInfo)
500 {
501     napi_handle_scope scope = nullptr;
502     auto status = napi_open_handle_scope(env_, &scope);
503     if (status != napi_ok) {
504         return;
505     }
506 
507     const std::list<FingerInfo>& fingerList = gestureEventInfo.GetFingerList();
508     napi_value napiFingerList = nullptr;
509     napi_create_array(env_, &napiFingerList);
510     bool isArray = false;
511     if (napi_is_array(env_, napiFingerList, &isArray) != napi_ok || !isArray) {
512         return;
513     }
514     double scale = Dimension(1.0, DimensionUnit::VP).ConvertToPx();
515     if (NearZero(scale)) {
516         scale = 1.0;
517     }
518     int32_t index = 0;
519     if (fingerList.size() > 0) {
520         for (auto finger : fingerList) {
521             napi_value napiFinger = nullptr;
522             napi_create_object(env_, &napiFinger);
523 
524             napi_value napiId = nullptr;
525             napi_create_double(env_, finger.fingerId_, &napiId);
526             napi_set_named_property(env_, napiFinger, "id", napiId);
527             const OHOS::Ace::Offset& globalLocation = finger.globalLocation_;
528             const OHOS::Ace::Offset& localLocation = finger.localLocation_;
529             napi_value napiGlobalX = nullptr;
530             napi_create_double(env_, globalLocation.GetX() / scale, &napiGlobalX);
531             napi_set_named_property(env_, napiFinger, "globalX", napiGlobalX);
532             napi_value napiGlobalY = nullptr;
533             napi_create_double(env_, globalLocation.GetY() / scale, &napiGlobalY);
534             napi_set_named_property(env_, napiFinger, "globalY", napiGlobalY);
535             napi_value napiLocalX = nullptr;
536             napi_create_double(env_, localLocation.GetX() / scale, &napiLocalX);
537             napi_set_named_property(env_, napiFinger, "localX", napiLocalX);
538             napi_value napiLocalY = nullptr;
539             napi_create_double(env_, localLocation.GetY() / scale, &napiLocalY);
540             napi_set_named_property(env_, napiFinger, "localY", napiLocalY);
541 
542             napi_set_element(env_, napiFingerList, index++, napiFinger);
543         }
544     }
545     napi_set_named_property(env_, objValueClickEvent, "fingerList", napiFingerList);
546     napi_close_handle_scope(env_, scope);
547 }
548 
AddClickEventInfoOne(napi_value objValueClickEvent,const ClickInfo & clickInfo)549 void UIObserverListener::AddClickEventInfoOne(napi_value objValueClickEvent, const ClickInfo& clickInfo)
550 {
551     napi_handle_scope scope = nullptr;
552     auto status = napi_open_handle_scope(env_, &scope);
553     if (status != napi_ok) {
554         return;
555     }
556 
557     double scale = Dimension(1.0, DimensionUnit::VP).ConvertToPx();
558     if (NearZero(scale)) {
559         scale = 1.0;
560     }
561     Offset globalOffset = clickInfo.GetGlobalLocation();
562     Offset screenOffset = clickInfo.GetScreenLocation();
563     napi_value napiDisplayX = GetNamedProperty(env_, objValueClickEvent, "displayX");
564     if (GetValueType(env_, napiDisplayX) != napi_null) {
565         napi_create_double(env_, screenOffset.GetX() / scale, &napiDisplayX);
566         napi_set_named_property(env_, objValueClickEvent, "displayX", napiDisplayX);
567     }
568     napi_value napiDisplayY = GetNamedProperty(env_, objValueClickEvent, "displayY");
569     if (GetValueType(env_, napiDisplayY) != napi_null) {
570         napi_create_double(env_, screenOffset.GetY() / scale, &napiDisplayY);
571         napi_set_named_property(env_, objValueClickEvent, "displayY", napiDisplayY);
572     }
573     napi_value napiWindowX = GetNamedProperty(env_, objValueClickEvent, "windowX");
574     if (GetValueType(env_, napiWindowX) != napi_null) {
575         napi_create_double(env_, globalOffset.GetX() / scale, &napiWindowX);
576         napi_set_named_property(env_, objValueClickEvent, "windowX", napiWindowX);
577     }
578     napi_value napiWindowY = GetNamedProperty(env_, objValueClickEvent, "windowY");
579     if (GetValueType(env_, napiWindowY) != napi_null) {
580         napi_create_double(env_, globalOffset.GetY() / scale, &napiWindowY);
581         napi_set_named_property(env_, objValueClickEvent, "windowY", napiWindowY);
582     }
583     napi_close_handle_scope(env_, scope);
584 }
585 
AddClickEventInfoTwo(napi_value objValueClickEvent,const ClickInfo & clickInfo)586 void UIObserverListener::AddClickEventInfoTwo(napi_value objValueClickEvent, const ClickInfo& clickInfo)
587 {
588     napi_handle_scope scope = nullptr;
589     auto status = napi_open_handle_scope(env_, &scope);
590     if (status != napi_ok) {
591         return;
592     }
593 
594     double scale = Dimension(1.0, DimensionUnit::VP).ConvertToPx();
595     if (NearZero(scale)) {
596         scale = 1.0;
597     }
598     Offset globalOffset = clickInfo.GetGlobalLocation();
599     Offset localOffset = clickInfo.GetLocalLocation();
600     napi_value napiScreenX = GetNamedProperty(env_, objValueClickEvent, "screenX");
601     if (GetValueType(env_, napiScreenX) != napi_null) {
602         napi_create_double(env_, globalOffset.GetX() / scale, &napiScreenX);
603         napi_set_named_property(env_, objValueClickEvent, "screenX", napiScreenX);
604     }
605     napi_value napiScreenY = GetNamedProperty(env_, objValueClickEvent, "screenY");
606     if (GetValueType(env_, napiScreenY) != napi_null) {
607         napi_create_double(env_, globalOffset.GetY() / scale, &napiScreenY);
608         napi_set_named_property(env_, objValueClickEvent, "screenY", napiScreenY);
609     }
610     napi_value napiX = GetNamedProperty(env_, objValueClickEvent, "x");
611     if (GetValueType(env_, napiX) != napi_null) {
612         napi_create_double(env_, localOffset.GetX() / scale, &napiX);
613         napi_set_named_property(env_, objValueClickEvent, "x", napiX);
614     }
615     napi_value napiY = GetNamedProperty(env_, objValueClickEvent, "y");
616     if (GetValueType(env_, napiY) != napi_null) {
617         napi_create_double(env_, localOffset.GetY() / scale, &napiY);
618         napi_set_named_property(env_, objValueClickEvent, "y", napiY);
619     }
620     AddTargetObject(objValueClickEvent, clickInfo);
621     napi_close_handle_scope(env_, scope);
622 }
623 
AddTargetObject(napi_value objValueClickEvent,const ClickInfo & clickInfo)624 void UIObserverListener::AddTargetObject(napi_value objValueClickEvent, const ClickInfo& clickInfo)
625 {
626     napi_handle_scope scope = nullptr;
627     auto status = napi_open_handle_scope(env_, &scope);
628     if (status != napi_ok) {
629         return;
630     }
631 
632     napi_value napiTargetObject = nullptr;
633     napi_create_object(env_, &napiTargetObject);
634     const auto& localOffset = clickInfo.GetTarget().area.GetOffset();
635     const auto& origin = clickInfo.GetTarget().origin;
636 
637     napi_value napiOffset = nullptr;
638     napi_create_object(env_, &napiOffset);
639     napi_value napiX = nullptr;
640     napi_create_double(env_, localOffset.GetX().ConvertToVp(), &napiX);
641     napi_set_named_property(env_, napiOffset, "x", napiX);
642     napi_value napiY = nullptr;
643     napi_create_double(env_, localOffset.GetY().ConvertToVp(), &napiY);
644     napi_set_named_property(env_, napiOffset, "y", napiY);
645     napi_set_named_property(env_, napiTargetObject, "position", napiOffset);
646 
647     napi_value napiGlobalOffset = nullptr;
648     napi_create_object(env_, &napiGlobalOffset);
649     napi_value napiGlobalX = nullptr;
650     napi_create_double(env_, localOffset.GetX().ConvertToVp() + origin.GetX().ConvertToVp(),
651         &napiGlobalX);
652     napi_set_named_property(env_, napiGlobalOffset, "x", napiGlobalX);
653     napi_value napiGlobalY = nullptr;
654     napi_create_double(env_, localOffset.GetY().ConvertToVp() + origin.GetY().ConvertToVp(),
655         &napiGlobalY);
656     napi_set_named_property(env_, napiGlobalOffset, "y", napiGlobalY);
657     napi_set_named_property(env_, napiTargetObject, "globalPosition", napiGlobalOffset);
658 
659     napi_value napiArea = nullptr;
660     napi_create_object(env_, &napiArea);
661     napi_value napiWidth = nullptr;
662     napi_create_double(env_, clickInfo.GetTarget().area.GetWidth().ConvertToVp(), &napiWidth);
663     napi_set_named_property(env_, napiArea, "width", napiWidth);
664     napi_value napiHeight = nullptr;
665     napi_create_double(env_, clickInfo.GetTarget().area.GetHeight().ConvertToVp(), &napiHeight);
666     napi_set_named_property(env_, napiArea, "height", napiHeight);
667     napi_set_named_property(env_, napiTargetObject, "area", napiArea);
668 
669     napi_set_named_property(env_, objValueClickEvent, "target", napiTargetObject);
670     napi_close_handle_scope(env_, scope);
671 }
672 
CreateNavDestinationInfoObj(const NG::NavDestinationInfo & info)673 napi_value UIObserverListener::CreateNavDestinationInfoObj(const NG::NavDestinationInfo& info)
674 {
675     napi_value objValue = nullptr;
676     napi_create_object(env_, &objValue);
677     napi_value napiNavId = nullptr;
678     napi_value napiName = nullptr;
679     napi_value napiState = nullptr;
680     napi_value napiIdx = nullptr;
681     napi_value napiNavDesId = nullptr;
682     napi_create_string_utf8(env_, info.navigationId.c_str(), info.navigationId.length(), &napiNavId);
683     napi_create_string_utf8(env_, info.name.c_str(), info.name.length(), &napiName);
684     napi_create_int32(env_, static_cast<int32_t>(info.state), &napiState);
685     napi_create_int32(env_, info.index, &napiIdx);
686     napi_create_string_utf8(env_, info.navDestinationId.c_str(), info.navDestinationId.length(), &napiNavDesId);
687     napi_set_named_property(env_, objValue, "navigationId", napiNavId);
688     napi_set_named_property(env_, objValue, "name", napiName);
689     napi_set_named_property(env_, objValue, "state", napiState);
690     napi_set_named_property(env_, objValue, "index", napiIdx);
691     napi_set_named_property(env_, objValue, "param", info.param);
692     napi_set_named_property(env_, objValue, "navDestinationId", napiNavDesId);
693     return objValue;
694 }
695 
GetNapiCallback()696 napi_value UIObserverListener::GetNapiCallback()
697 {
698     napi_value callback = nullptr;
699     napi_get_reference_value(env_, callback_, &callback);
700     return callback;
701 }
702 
NapiEqual(napi_value cb)703 bool UIObserverListener::NapiEqual(napi_value cb)
704 {
705     bool isEquals = false;
706     napi_strict_equals(env_, cb, GetNapiCallback(), &isEquals);
707     return isEquals;
708 }
709 } // namespace OHOS::Ace::Napi
710