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 "bridge/cj_frontend/interfaces/cj_ffi/cj_gesture_ffi.h"
17 
18 #include "bridge/cj_frontend/cppview/gesture.h"
19 #include "cj_lambda.h"
20 #include "bridge/cj_frontend/interfaces/cj_ffi/utils.h"
21 #include "frameworks/core/components_ng/base/view_stack_processor.h"
22 #include "frameworks/core/components_ng/gestures/gesture_group.h"
23 #include "frameworks/core/components_ng/gestures/long_press_gesture.h"
24 #include "frameworks/core/components_ng/gestures/pan_gesture.h"
25 #include "frameworks/core/components_ng/gestures/pinch_gesture.h"
26 #include "frameworks/core/components_ng/gestures/recognizers/exclusive_recognizer.h"
27 #include "frameworks/core/components_ng/gestures/recognizers/parallel_recognizer.h"
28 #include "frameworks/core/components_ng/gestures/rotation_gesture.h"
29 #include "frameworks/core/components_ng/gestures/swipe_gesture.h"
30 #include "frameworks/core/components_ng/gestures/tap_gesture.h"
31 
32 using namespace OHOS::FFI;
33 using namespace OHOS::Ace;
34 using namespace OHOS::Ace::Framework;
35 
36 namespace {
37 constexpr int32_t DEFAULT_TAP_FINGER = 1;
38 constexpr int32_t MAX_TAP_FINGER = 10;
39 constexpr int32_t DEFAULT_TAP_COUNT = 1;
40 constexpr int32_t DEFAULT_LONG_PRESS_FINGER = 1;
41 constexpr int32_t MAX_LONG_PRESS_FINGER = 10;
42 constexpr int32_t DEFAULT_PINCH_FINGER = 2;
43 constexpr int32_t MAX_PINCH_FINGER = 5;
44 constexpr double DEFAULT_PINCH_DISTANCE = 3.0;
45 constexpr int32_t DEFAULT_ROTATION_FINGER = 2;
46 constexpr int32_t MAX_ROTATION_FINGER = 5;
47 constexpr double DEFAULT_ROTATION_ANGLE = 1.0;
48 constexpr int32_t MAX_PAN_FINGER = 10;
49 constexpr int32_t MAX_SLIDE_FINGER = 10;
50 
51 const std::vector<GesturePriority> GESTURE_PRIORITY = { GesturePriority::Low, GesturePriority::High,
52     GesturePriority::Parallel };
53 
54 const std::vector<GestureMask> GESTURE_MASK = { GestureMask::Normal, GestureMask::IgnoreInternal };
55 
56 const std::vector<GestureMode> GROUP_GESTURE_MODE = { GestureMode::Sequence, GestureMode::Parallel,
57     GestureMode::Exclusive };
58 
59 enum class GestureEventType { ACTION, START, UPDATE, END, CANCEL };
60 
FormatGestureEvenFunction(void (* callback)(CJGestureEvent info))61 std::function<void(const GestureEvent& event)> FormatGestureEvenFunction(void (*callback)(CJGestureEvent info))
62 {
63     std::function<void(const GestureEvent& event)> result = [ffiOnAction = CJLambda::Create(callback)](
64                                                                 const GestureEvent& event) -> void {
65         CJGestureEvent ffiGestureEvent {};
66         CJEventTarget ffiEventTarget {};
67         CJArea ffiArea {};
68         CJPosition ffiPosition {};
69         CJPosition ffiGlobalPosition {};
70 
71         const auto& eventTarget = event.GetTarget();
72         ffiArea.width = eventTarget.area.GetWidth().ConvertToVp();
73         ffiArea.height = eventTarget.area.GetHeight().ConvertToVp();
74         const auto& localOffset = eventTarget.area.GetOffset();
75         const auto& origin = eventTarget.origin;
76         ffiPosition.x = localOffset.GetX().ConvertToVp();
77         ffiPosition.y = localOffset.GetY().ConvertToVp();
78         ffiGlobalPosition.x = origin.GetX().ConvertToVp() + localOffset.GetX().ConvertToVp();
79         ffiGlobalPosition.y = origin.GetX().ConvertToVp() + localOffset.GetY().ConvertToVp();
80 
81         ffiArea.globalPosition = &ffiGlobalPosition;
82         ffiArea.position = &ffiPosition;
83 
84         ffiEventTarget.area = &ffiArea;
85 
86         auto& fingerList = event.GetFingerList();
87         ffiGestureEvent.fingerListSize = static_cast<int32_t>(fingerList.size());
88         ffiGestureEvent.fingerList = new CJFingerInfo[fingerList.size()];
89         TransformNativeCJFingerInfo(ffiGestureEvent.fingerList, fingerList);
90 
91         ffiGestureEvent.target = &ffiEventTarget;
92         ffiGestureEvent.timestamp = event.GetTimeStamp().time_since_epoch().count();
93         ffiGestureEvent.repeat = event.GetRepeat();
94         ffiGestureEvent.source = static_cast<int32_t>(event.GetSourceDevice());
95         ffiGestureEvent.offsetX = event.GetOffsetX();
96         ffiGestureEvent.offsetY = event.GetOffsetY();
97         ffiGestureEvent.scale = event.GetScale();
98         ffiGestureEvent.pinchCenterX = event.GetPinchCenter().GetX();
99         ffiGestureEvent.pinchCenterY = event.GetPinchCenter().GetY();
100         ffiGestureEvent.angle = event.GetAngle();
101         ffiGestureEvent.speed = event.GetSpeed();
102 
103         ffiOnAction(ffiGestureEvent);
104     };
105     return result;
106 }
107 
FormatGestureEvenFunction(void (* callback)())108 std::function<void(const GestureEvent& event)> FormatGestureEvenFunction(void (*callback)())
109 {
110     std::function<void(const GestureEvent& event)> result = [ffiOnAction = CJLambda::Create(callback)](
111                                                                 const GestureEvent& event) -> void { ffiOnAction(); };
112     return result;
113 }
114 
HandlerOnGestureEvent(const GestureEventType & action,const std::function<void (const GestureEvent & event)> & callback)115 void HandlerOnGestureEvent(
116     const GestureEventType& action, const std::function<void(const GestureEvent& event)>& callback)
117 {
118     RefPtr<GestureProcessor> gestureProcessor = NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
119     auto gesture = gestureProcessor->TopGestureNG();
120     if (!gesture) {
121         LOGE("top gesture is illegal");
122         return;
123     }
124 
125     if (action == GestureEventType::CANCEL) {
126         auto onActionCancelFunc = [callback = std::move(callback)]() {
127             auto info = GestureEvent();
128             callback(info);
129         };
130         gesture->SetOnActionCancelId(onActionCancelFunc);
131         return;
132     }
133 
134     auto onActionFunc = [callback = std::move(callback)](GestureEvent& info) {
135         callback(info);
136     };
137 
138     switch (action) {
139         case GestureEventType::ACTION:
140             gesture->SetOnActionId(onActionFunc);
141             break;
142         case GestureEventType::START:
143             gesture->SetOnActionStartId(onActionFunc);
144             break;
145         case GestureEventType::UPDATE:
146             gesture->SetOnActionUpdateId(onActionFunc);
147             break;
148         case GestureEventType::END:
149             gesture->SetOnActionEndId(onActionFunc);
150             break;
151         default:
152             LOGW("Gesture: Unknown gesture action %{public}d", action);
153             break;
154     }
155 }
156 
157 } // namespace
158 
159 extern "C" {
FfiOHOSAceFrameworkGestureCreate(int32_t priority,int32_t mask)160 void FfiOHOSAceFrameworkGestureCreate(int32_t priority, int32_t mask)
161 {
162     if (!Utils::CheckParamsValid(priority, GESTURE_PRIORITY.size())) {
163         LOGE("invalid value for gesturePriority");
164         return;
165     }
166     if (!Utils::CheckParamsValid(mask, GESTURE_MASK.size())) {
167         LOGE("invalid value for gestureMask");
168         return;
169     }
170 
171     RefPtr<GestureProcessor> gestureProcessor =
172             NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
173     gestureProcessor->SetPriority(GESTURE_PRIORITY[priority]);
174     gestureProcessor->SetGestureMask(GESTURE_MASK[mask]);
175 }
176 
FfiOHOSAceFrameworkGestureOnAction(void (* callback)(CJGestureEvent info))177 void FfiOHOSAceFrameworkGestureOnAction(void (*callback)(CJGestureEvent info))
178 {
179     HandlerOnGestureEvent(GestureEventType::ACTION, FormatGestureEvenFunction(callback));
180 }
181 
FfiOHOSAceFrameworkGestureOnActionStart(void (* callback)(CJGestureEvent info))182 void FfiOHOSAceFrameworkGestureOnActionStart(void (*callback)(CJGestureEvent info))
183 {
184     HandlerOnGestureEvent(GestureEventType::START, FormatGestureEvenFunction(callback));
185 }
186 
FfiOHOSAceFrameworkGestureOnActionUpdate(void (* callback)(CJGestureEvent info))187 void FfiOHOSAceFrameworkGestureOnActionUpdate(void (*callback)(CJGestureEvent info))
188 {
189     HandlerOnGestureEvent(GestureEventType::UPDATE, FormatGestureEvenFunction(callback));
190 }
191 
FfiOHOSAceFrameworkGestureOnActionEnd(void (* callback)(CJGestureEvent info))192 void FfiOHOSAceFrameworkGestureOnActionEnd(void (*callback)(CJGestureEvent info))
193 {
194     HandlerOnGestureEvent(GestureEventType::END, FormatGestureEvenFunction(callback));
195 }
196 
FfiOHOSAceFrameworkGestureOnActionCancel(void (* callback)())197 void FfiOHOSAceFrameworkGestureOnActionCancel(void (*callback)())
198 {
199     HandlerOnGestureEvent(GestureEventType::CANCEL, FormatGestureEvenFunction(callback));
200 }
201 
FfiOHOSAceFrameworkGestureFinish()202 void FfiOHOSAceFrameworkGestureFinish()
203 {
204     RefPtr<GestureProcessor> gestureProcessor =
205         NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
206     NG::ViewStackProcessor::GetInstance()->ResetGestureProcessor();
207 
208     auto gesture = gestureProcessor->FinishGestureNG();
209     if (!gesture) {
210         LOGE("gesture is not exist when component finish");
211         return;
212     }
213     gesture->SetGestureMask(gestureProcessor->GetGestureMask());
214     gesture->SetPriority(gestureProcessor->GetPriority());
215     auto gestureEventHub = NG::ViewStackProcessor::GetInstance()->GetMainFrameNodeGestureEventHub();
216     if (gestureEventHub) {
217         gestureEventHub->AddGesture(gesture);
218     }
219 }
220 
FfiOHOSAceFrameworkGesturePop()221 void FfiOHOSAceFrameworkGesturePop()
222 {
223     RefPtr<GestureProcessor> gestureProcessor =
224         NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
225     gestureProcessor->PopGestureNG();
226 }
227 
228 // tapGesture
FfiOHOSAceFrameworkTapGestureCreate(int32_t count,int32_t fingers)229 void FfiOHOSAceFrameworkTapGestureCreate(int32_t count, int32_t fingers)
230 {
231     RefPtr<GestureProcessor> gestureProcessor =
232         NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
233 
234     int32_t countNum = Utils::CheckMin(DEFAULT_TAP_COUNT, DEFAULT_TAP_COUNT, count);
235     int32_t fingersNum = Utils::CheckRange(DEFAULT_TAP_FINGER, MAX_TAP_FINGER, DEFAULT_TAP_FINGER, fingers);
236 
237     auto gesture = AceType::MakeRefPtr<NG::TapGesture>(countNum, fingersNum);
238     gestureProcessor->PushGestureNG(gesture);
239 }
240 
241 // LongPressGesture
FfiOHOSAceFrameworkLongPressGestureCreate(int32_t fingers,bool repeat,int32_t duration)242 void FfiOHOSAceFrameworkLongPressGestureCreate(int32_t fingers, bool repeat, int32_t duration)
243 {
244     RefPtr<GestureProcessor> gestureProcessor =
245         NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
246 
247     int32_t fingersNum =
248         Utils::CheckRange(DEFAULT_LONG_PRESS_FINGER, MAX_LONG_PRESS_FINGER, DEFAULT_LONG_PRESS_FINGER, fingers);
249     int32_t durationNum = Utils::CheckMin(0, DEFAULT_LONG_PRESS_DURATION, duration);
250 
251     auto gesture = AceType::MakeRefPtr<NG::LongPressGesture>(fingersNum, repeat, durationNum);
252     gestureProcessor->PushGestureNG(gesture);
253 }
254 
255 // PinchPressGesture
FfiOHOSAceFrameworkPinchGestureCreate(int32_t fingers,double distance)256 void FfiOHOSAceFrameworkPinchGestureCreate(int32_t fingers, double distance)
257 {
258     RefPtr<GestureProcessor> gestureProcessor =
259         NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
260 
261     int32_t fingersNum =
262         Utils::CheckRange(DEFAULT_PINCH_FINGER, MAX_PINCH_FINGER, DEFAULT_PINCH_FINGER, fingers);
263     double distanceNum = Utils::CheckMin(0.0, DEFAULT_PINCH_DISTANCE, distance);
264 
265     auto gesture = AceType::MakeRefPtr<NG::PinchGesture>(fingersNum, distanceNum);
266     gestureProcessor->PushGestureNG(gesture);
267 }
268 
269 // SwipeGesture
FfiOHOSAceFrameworkSwipeGestureCreate(int32_t fingers,uint32_t direction,double speed)270 void FfiOHOSAceFrameworkSwipeGestureCreate(int32_t fingers, uint32_t direction, double speed)
271 {
272     OHOS::Ace::SwipeDirection swipeDirection;
273     swipeDirection.type = direction;
274 
275     RefPtr<GestureProcessor> gestureProcessor =
276         NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
277 
278     int32_t fingersNum =
279         Utils::CheckRange(DEFAULT_SLIDE_FINGER, MAX_SLIDE_FINGER, DEFAULT_SLIDE_FINGER, fingers);
280     double speedNum = Utils::CheckMin(0.0, DEFAULT_SLIDE_SPEED, speed);
281 
282     auto gesture = AceType::MakeRefPtr<NG::SwipeGesture>(fingersNum, swipeDirection, speedNum);
283     gestureProcessor->PushGestureNG(gesture);
284 }
285 
286 // RotationGesture
FfiOHOSAceFrameworkRotationGestureCreate(int32_t fingers,double angle)287 void FfiOHOSAceFrameworkRotationGestureCreate(int32_t fingers, double angle)
288 {
289     RefPtr<GestureProcessor> gestureProcessor =
290         NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
291 
292     int32_t fingersNum =
293         Utils::CheckRange(DEFAULT_ROTATION_FINGER, MAX_ROTATION_FINGER, DEFAULT_ROTATION_FINGER, fingers);
294     double angleNum = Utils::CheckMin(0.0, DEFAULT_ROTATION_ANGLE, angle);
295 
296     auto gesture = AceType::MakeRefPtr<NG::RotationGesture>(fingersNum, angleNum);
297     gestureProcessor->PushGestureNG(gesture);
298 }
299 
300 // PanGesture
FfiOHOSAceFrameworkPanGestureCreate(int32_t fingers,uint32_t direction,double distance)301 void FfiOHOSAceFrameworkPanGestureCreate(int32_t fingers, uint32_t direction, double distance)
302 {
303     OHOS::Ace::PanDirection panDirection;
304     panDirection.type = direction;
305 
306     RefPtr<GestureProcessor> gestureProcessor =
307         NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
308 
309     int32_t fingersNum =
310         Utils::CheckRange(DEFAULT_PAN_FINGER, MAX_PAN_FINGER, DEFAULT_PAN_FINGER, fingers);
311     double distanceNum = Utils::CheckMin(0.0, DEFAULT_PAN_DISTANCE.Value(), distance);
312 
313     auto gesture = AceType::MakeRefPtr<NG::PanGesture>(fingersNum, panDirection, distanceNum);
314     gestureProcessor->PushGestureNG(gesture);
315 }
316 
FfiOHOSAceFrameworkPanGestureCreateWithOptions(int64_t OptionID)317 void FfiOHOSAceFrameworkPanGestureCreateWithOptions(int64_t OptionID)
318 {
319     auto panGestureOption = FFIData::GetData<NativePanGestureOption>(OptionID);
320     if (panGestureOption == nullptr) {
321         LOGE("FfiGesture: invalid PanGestureOptions ID");
322     } else {
323         RefPtr<GestureProcessor> gestureProcessor =
324             NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
325 
326         auto gesture = AceType::MakeRefPtr<NG::PanGesture>(panGestureOption->GetPanGestureOption());
327         gestureProcessor->PushGestureNG(gesture);
328     }
329 }
330 
331 // GestureGroup
FfiOHOSAceFrameworkGestureGroupCreate(int32_t mode)332 void FfiOHOSAceFrameworkGestureGroupCreate(int32_t mode)
333 {
334     if (!Utils::CheckParamsValid(mode, GROUP_GESTURE_MODE.size())) {
335         LOGE("invalid value for gesture group mode");
336         return;
337     }
338 
339     RefPtr<GestureProcessor> gestureProcessor =
340         NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
341     auto gesture = AceType::MakeRefPtr<NG::GestureGroup>(GROUP_GESTURE_MODE[mode]);
342     gestureProcessor->PushGestureNG(gesture);
343 }
344 
FfiOHOSAceFrameworkPanGestureOptionsCtor(int32_t fingers,uint32_t direction,double distance)345 int64_t FfiOHOSAceFrameworkPanGestureOptionsCtor(int32_t fingers, uint32_t direction, double distance)
346 {
347     OHOS::Ace::PanDirection panDirection;
348     panDirection.type = direction;
349 
350     int32_t fingersNum = Utils::CheckRange(DEFAULT_PAN_FINGER, MAX_PAN_FINGER, DEFAULT_PAN_FINGER, fingers);
351     double distanceNum = Utils::CheckMin(0.0, DEFAULT_PAN_DISTANCE.Value(), distance);
352 
353     auto ret_ = FFIData::Create<NativePanGestureOption>(fingersNum, panDirection, distanceNum);
354     if (ret_ == nullptr) {
355         return FFI_ERROR_CODE;
356     }
357     return ret_->GetID();
358 }
359 
FfiOHOSAceFrameworkPanGestureOptionsSetFingers(int64_t selfID,int32_t fingers)360 void FfiOHOSAceFrameworkPanGestureOptionsSetFingers(int64_t selfID, int32_t fingers)
361 {
362     auto self = FFIData::GetData<NativePanGestureOption>(selfID);
363     if (self != nullptr) {
364         self->SetFingers(fingers);
365     } else {
366         LOGE("FfiGesture: invalid PanGestureOptions ID");
367     }
368 }
369 
FfiOHOSAceFrameworkPanGestureOptionsSetDirection(int64_t selfID,uint32_t direction)370 void FfiOHOSAceFrameworkPanGestureOptionsSetDirection(int64_t selfID, uint32_t direction)
371 {
372     OHOS::Ace::PanDirection panDirection;
373     panDirection.type = direction;
374 
375     auto self = FFIData::GetData<NativePanGestureOption>(selfID);
376     if (self != nullptr) {
377         self->SetDirection(panDirection);
378     } else {
379         LOGE("FfiGesture: invalid PanGestureOptions ID");
380     }
381 }
382 
FfiOHOSAceFrameworkPanGestureOptionsSetDistance(int64_t selfID,double distance)383 void FfiOHOSAceFrameworkPanGestureOptionsSetDistance(int64_t selfID, double distance)
384 {
385     auto self = FFIData::GetData<NativePanGestureOption>(selfID);
386     if (self != nullptr) {
387         self->SetDistance(distance);
388     } else {
389         LOGE("FfiGesture: invalid PanGestureOptions ID");
390     }
391 }
392 }
393