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_interactable_view_ffi.h"
17
18 #include <cinttypes>
19
20 #include "cj_lambda.h"
21
22 #include "bridge/cj_frontend/interfaces/cj_ffi/utils.h"
23 #include "bridge/declarative_frontend/view_stack_processor.h"
24 #include "core/components_ng/base/view_abstract_model_ng.h"
25 #include "core/components_ng/base/view_stack_model.h"
26 #include "core/components_ng/pattern/image/image_model_ng.h"
27 #include "core/event/ace_event_handler.h"
28 #include "core/gestures/click_recognizer.h"
29 #ifndef _NON_OHOS_
30 #include "foundation/multimedia/image_framework/frameworks/kits/cj/include/pixel_map_impl.h"
31
32 #include "adapter/ohos/osal/pixel_map_ohos.h"
33 #endif
34
35 using namespace OHOS::Ace;
36 using namespace OHOS::Ace::Framework;
37
38 namespace OHOS::Ace {
FFiSetDragInfo(const RefPtr<DragEvent> & info,const std::string & extraParams,CJPosition & cjPosition,CJDragInfo & ffiDragInfo)39 void FFiSetDragInfo(
40 const RefPtr<DragEvent>& info, const std::string& extraParams, CJPosition& cjPosition, CJDragInfo& ffiDragInfo)
41 {
42 cjPosition.x = info->GetX();
43 cjPosition.y = info->GetY();
44 ffiDragInfo.extraParams = extraParams.c_str();
45 }
46
ParseDragNode(void (* builder)())47 RefPtr<AceType> ParseDragNode(void (*builder)())
48 {
49 if (builder == nullptr) {
50 return nullptr;
51 }
52 std::function<void(void)> builderFunc = CJLambda::Create(builder);
53 // use another VSP instance while executing the builder function
54 ViewStackModel::GetInstance()->NewScope();
55 {
56 builderFunc();
57 }
58 return ViewStackModel::GetInstance()->Finish();
59 }
60
ParseDragPixelMap(int64_t pixelMapId)61 RefPtr<PixelMap> ParseDragPixelMap(int64_t pixelMapId)
62 {
63 #ifndef _NON_OHOS_
64 if (pixelMapId == 0) {
65 return nullptr;
66 }
67 auto pixelMapImpl = OHOS::FFI::FFIData::GetData<OHOS::Media::PixelMapImpl>(pixelMapId);
68 if (pixelMapImpl == nullptr) {
69 LOGE("DragStart error, Cannot get PixelMapProxy by id: %{public}" PRId64, pixelMapId);
70 return nullptr;
71 }
72 auto pixMap = pixelMapImpl->GetRealPixelMap();
73 if (pixMap == nullptr) {
74 LOGE("DragStart error, Cannot get pixMap in PixelMapProxy");
75 return nullptr;
76 }
77 auto pixMapOhos = PixelMap::CreatePixelMap(&pixMap);
78 if (pixMapOhos == nullptr) {
79 LOGE("DragStart error, Cannot create PixelMapOhos by pixMap");
80 return nullptr;
81 }
82 return pixMapOhos;
83 #else
84 return nullptr;
85 #endif
86 }
87
88 } // namespace OHOS::Ace
89
90 extern "C" {
ToString() const91 std::string CJClickInfo::ToString() const
92 {
93 std::string result = "x: " + std::to_string(x);
94 result = result + ", y: " + std::to_string(y);
95 result = result + ", windowX: " + std::to_string(windowX);
96 result = result + ", windowY: " + std::to_string(windowY);
97 result = result + ", displayX: " + std::to_string(displayX);
98 result = result + ", displayY: " + std::to_string(displayY);
99 result = result + ", timestamp: " + std::to_string(timestamp);
100 result = result + ", target.area.width: " + std::to_string(target->area->width);
101 result = result + ", target.area.height: " + std::to_string(target->area->width);
102 result = result + ", target.area.position.x: " + std::to_string(target->area->position->x);
103 result = result + ", target.area.position.y: " + std::to_string(target->area->position->y);
104 result = result + ", target.area.globalPosition.x: " + std::to_string(target->area->globalPosition->y);
105 result = result + ", target.area.globalPosition.y: " + std::to_string(target->area->globalPosition->y);
106 return result;
107 }
108
ToString() const109 std::string CJTouchEvent::ToString() const
110 {
111 std::string result = "type: " + std::to_string(eventType);
112 result = result + ", touchesSize: " + std::to_string(touchesSize);
113 result = result + ", changedTouchesSize: " + std::to_string(changedTouchesSize);
114 return result;
115 }
116
FfiOHOSAceFrameworkInteractableViewOnClick(void (* callback)(CJClickInfo clickInfo))117 void FfiOHOSAceFrameworkInteractableViewOnClick(void (*callback)(CJClickInfo clickInfo))
118 {
119 auto lambda = [ffiOnClick = CJLambda::Create(callback)](const GestureEvent& event) -> void {
120 CJClickInfo cjClickInfo {};
121 CJEventTarget cjEventTarget {};
122 CJArea cjArea {};
123 CJPosition cjPosition {};
124 CJPosition cjGlobalPosition {};
125 AssambleCJClickInfo(event, cjClickInfo, cjEventTarget, cjArea, cjPosition, cjGlobalPosition);
126 ffiOnClick(cjClickInfo);
127 };
128 ViewAbstractModel::GetInstance()->SetOnClick(std::move(lambda), nullptr);
129 }
130
FfiOHOSAceFrameworkInteractableViewOnTouch(bool (* callback)(CJTouchEvent touchInfo))131 void FfiOHOSAceFrameworkInteractableViewOnTouch(bool (*callback)(CJTouchEvent touchInfo))
132 {
133 auto onTouch = [ffiCallback = CJLambda::Create(callback)](TouchEventInfo& touchEventInfo) {
134 CJTouchEvent ffiTouchInfo;
135
136 auto& touches = touchEventInfo.GetTouches();
137 ffiTouchInfo.touches = new CJTouchInfo[touches.size()];
138 TransformNativeTouchLocationInfo(ffiTouchInfo.touches, touches);
139 ffiTouchInfo.touchesSize = static_cast<int32_t>(touches.size());
140
141 auto& changedTouches = touchEventInfo.GetChangedTouches();
142 auto changeTouchArr = new CJTouchInfo[changedTouches.size()];
143 TransformNativeTouchLocationInfo(changeTouchArr, touchEventInfo.GetChangedTouches());
144 ffiTouchInfo.changedTouches = changeTouchArr;
145 ffiTouchInfo.changedTouchesSize = static_cast<int32_t>(changedTouches.size());
146
147 ffiTouchInfo.eventType = 0;
148 if (changedTouches.size() > 0) {
149 ffiTouchInfo.eventType = static_cast<uint8_t>(changedTouches.front().GetTouchType());
150 }
151 ffiTouchInfo.timestamp = touchEventInfo.GetTimeStamp().time_since_epoch().count();
152 ffiTouchInfo.sourceType = static_cast<int32_t>(touchEventInfo.GetSourceDevice());
153 CJArea cjArea {};
154 CJEventTarget cjEventTarget {};
155 CJPosition cjPosition {};
156 CJPosition cjGlobalPosition {};
157 AssambleCJEventTarget(touchEventInfo.GetTarget(), cjArea, cjPosition, cjGlobalPosition);
158 cjArea.position = &cjPosition;
159 cjArea.globalPosition = &cjGlobalPosition;
160 cjEventTarget.area = &cjArea;
161
162 ffiTouchInfo.target = &cjEventTarget;
163
164 auto flag = ffiCallback(ffiTouchInfo);
165 touchEventInfo.SetStopPropagation(flag);
166 delete[] ffiTouchInfo.touches;
167 delete[] ffiTouchInfo.changedTouches;
168 };
169 ViewAbstractModel::GetInstance()->SetOnTouch(std::move(onTouch));
170 }
FfiOHOSAceFrameworkInteractableViewOnAppear(void (* callback)())171 void FfiOHOSAceFrameworkInteractableViewOnAppear(void (*callback)())
172 {
173 auto onAppear = CJLambda::Create(callback);
174 ViewAbstractModel::GetInstance()->SetOnAppear([onAppear]() { onAppear(); });
175 }
176
FfiOHOSAceFrameworkInteractableViewOnDisAppear(void (* callback)())177 void FfiOHOSAceFrameworkInteractableViewOnDisAppear(void (*callback)())
178 {
179 auto onDisappear = CJLambda::Create(callback);
180 ViewAbstractModel::GetInstance()->SetOnDisAppear([onDisappear]() { onDisappear(); });
181 }
182
FfiOHOSAceFrameworkInteractableViewOnHover(void (* callback)(bool))183 void FfiOHOSAceFrameworkInteractableViewOnHover(void (*callback)(bool))
184 {
185 auto onHover = CJLambda::Create(callback);
186 ViewAbstractModel::GetInstance()->SetOnHover([onHover](bool param, HoverInfo& info) { onHover(param); });
187 }
188
FfiOHOSAceFrameworkInteractableViewOnAreaChanged(void (* callback)(CJArea,CJArea))189 void FfiOHOSAceFrameworkInteractableViewOnAreaChanged(void (*callback)(CJArea, CJArea))
190 {
191 auto onAreaChanged = CJLambda::Create(callback);
192 ViewAbstractModel::GetInstance()->SetOnAreaChanged(
193 [onAreaChanged](const Rect& lastRect, const Offset& lastOrigin, const Rect& rect, const Offset& origin) {
194 CJArea lastCjArea {};
195 lastCjArea.width = lastRect.Width();
196 lastCjArea.height = lastRect.Height();
197 CJPosition lastCjPosition {};
198 CJPosition lastCjGlobalPosition {};
199 lastCjPosition.x = lastRect.GetOffset().GetX();
200 lastCjPosition.y = lastRect.GetOffset().GetY();
201 lastCjGlobalPosition.x = lastRect.GetOffset().GetX() + lastOrigin.GetX();
202 lastCjGlobalPosition.y = lastRect.GetOffset().GetY() + lastOrigin.GetY();
203 lastCjArea.position = &lastCjPosition;
204 lastCjArea.globalPosition = &lastCjGlobalPosition;
205
206 CJArea cjArea {};
207 cjArea.width = rect.Width();
208 cjArea.height = rect.Height();
209 CJPosition cjPosition {};
210 CJPosition cjGlobalPosition {};
211 cjPosition.x = rect.GetOffset().GetX();
212 cjPosition.y = rect.GetOffset().GetY();
213 cjGlobalPosition.x = rect.GetOffset().GetX() + origin.GetX();
214 cjGlobalPosition.y = rect.GetOffset().GetY() + origin.GetY();
215 cjArea.position = &cjPosition;
216 cjArea.globalPosition = &cjGlobalPosition;
217
218 onAreaChanged(lastCjArea, cjArea);
219 });
220 }
221
FfiOHOSAceFrameworkInteractableViewOnVisibleAreaChange(VectorFloat64Handle raitosValsHandle,void (* callback)(bool isVisible,double currentRatio))222 void FfiOHOSAceFrameworkInteractableViewOnVisibleAreaChange(
223 VectorFloat64Handle raitosValsHandle, void (*callback)(bool isVisible, double currentRatio))
224 {
225 auto onVisibleChange = CJLambda::Create(callback);
226 const auto& ratios = *reinterpret_cast<std::vector<double>*>(raitosValsHandle);
227
228 ViewAbstractModel::GetInstance()->SetOnVisibleChange(
229 [onVisibleChange](bool isVisible, double currentRatio) { onVisibleChange(isVisible, currentRatio); }, ratios);
230 }
231
FfiOHOSAceFrameworkInteractableViewOnMouse(void (* callback)(CJMouseEvent))232 void FfiOHOSAceFrameworkInteractableViewOnMouse(void (*callback)(CJMouseEvent))
233 {
234 auto onMouse = [func = CJLambda::Create(callback)](MouseInfo& mouseInfo) {
235 CJMouseEvent cjMouseEvent {};
236 cjMouseEvent.timestamp = static_cast<int64_t>(mouseInfo.GetTimeStamp().time_since_epoch().count());
237 Offset globalOffset = mouseInfo.GetGlobalLocation();
238 Offset localOffset = mouseInfo.GetLocalLocation();
239 cjMouseEvent.screenX = PipelineBase::Px2VpWithCurrentDensity(globalOffset.GetX());
240 cjMouseEvent.screenY = PipelineBase::Px2VpWithCurrentDensity(globalOffset.GetY());
241 cjMouseEvent.x = PipelineBase::Px2VpWithCurrentDensity(localOffset.GetX());
242 cjMouseEvent.y = PipelineBase::Px2VpWithCurrentDensity(localOffset.GetY());
243 cjMouseEvent.button = static_cast<int32_t>(mouseInfo.GetButton());
244 cjMouseEvent.action = static_cast<int32_t>(mouseInfo.GetAction());
245 func(cjMouseEvent);
246 };
247
248 ViewAbstractModel::GetInstance()->SetOnMouse(std::move(onMouse));
249 }
250
251 // can not trigged this event on eTS app
FfiOHOSAceFrameworkInteractableViewOnKey(bool (* callback)(CJKeyEvent info))252 void FfiOHOSAceFrameworkInteractableViewOnKey(bool (*callback)(CJKeyEvent info))
253 {
254 auto onKeyEvent = [ffiCallback = CJLambda::Create(callback)](KeyEventInfo& keyInfo) -> bool {
255 CJKeyEvent ffiKeyInfo {};
256 ffiKeyInfo.keyText = keyInfo.GetKeyText();
257 ffiKeyInfo.type = static_cast<int32_t>(keyInfo.GetKeyType());
258 ffiKeyInfo.keyCode = static_cast<int32_t>(keyInfo.GetKeyCode());
259 ffiKeyInfo.keySource = static_cast<int32_t>(keyInfo.GetKeySource());
260 ffiKeyInfo.metaKey = keyInfo.GetMetaKey();
261 ffiKeyInfo.deviceId = keyInfo.GetDeviceId();
262 ffiKeyInfo.timestamp = keyInfo.GetTimeStamp().time_since_epoch().count();
263 auto ret = ffiCallback(ffiKeyInfo);
264 keyInfo.SetStopPropagation(ret);
265 return ret;
266 };
267 ViewAbstractModel::GetInstance()->SetOnKeyEvent(onKeyEvent);
268 }
269
FfiOHOSAceFrameworkInteractableViewOnDelete(void (* callback)())270 void FfiOHOSAceFrameworkInteractableViewOnDelete(void (*callback)())
271 {
272 ViewAbstractModel::GetInstance()->SetOnDelete(CJLambda::Create(callback));
273 }
274
FfiOHOSAceFrameworkInteractableViewOnFocus(void (* callback)())275 void FfiOHOSAceFrameworkInteractableViewOnFocus(void (*callback)())
276 {
277 ViewAbstractModel::GetInstance()->SetOnFocus(CJLambda::Create(callback));
278 }
279
FfiOHOSAceFrameworkInteractableViewOnBlur(void (* callback)())280 void FfiOHOSAceFrameworkInteractableViewOnBlur(void (*callback)())
281 {
282 ViewAbstractModel::GetInstance()->SetOnBlur(CJLambda::Create(callback));
283 }
284
FfiOHOSAceFrameworkInteractableViewOnDragStart(CJDragItemInfo (* callback)(CJDragInfo info),uint32_t componentName)285 void FfiOHOSAceFrameworkInteractableViewOnDragStart(CJDragItemInfo (*callback)(CJDragInfo info), uint32_t componentName)
286 {
287 if (!Container::IsCurrentUseNewPipeline()) {
288 LOGE("not supported");
289 return;
290 }
291 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
292 auto ffiCallback = CJLambda::Create(callback);
293 auto onDragStart = [ffiCallback, fnode = frameNode](
294 const RefPtr<DragEvent>& info, const std::string& extraParams) -> NG::DragDropBaseInfo {
295 LOGD("extraParams: %{public}s", extraParams.c_str());
296 PipelineContext::SetCallBackNode(fnode);
297 NG::DragDropBaseInfo itemInfo;
298 CJDragInfo ffiDragInfo {};
299 CJPosition cjPosition {};
300 FFiSetDragInfo(info, extraParams, cjPosition, ffiDragInfo);
301 ffiDragInfo.position = &cjPosition;
302 auto ret = ffiCallback(ffiDragInfo);
303 LOGD("piexlMapId: %{public}" PRId64 ", extraInfo: %{public}s", ret.pixelMapId, ret.extraInfo);
304 auto node = ParseDragNode(ret.builder);
305 #if defined(PIXEL_MAP_SUPPORTED)
306 itemInfo.pixelMap = ParseDragPixelMap(ret.pixelMapId);
307 #endif
308 itemInfo.extraInfo = ret.extraInfo;
309 itemInfo.node = node;
310 return itemInfo;
311 };
312
313 ViewAbstractModel::GetInstance()->SetOnDragStart(std::move(onDragStart));
314 }
315
FfiOHOSAceFrameworkInteractableViewOnDragEnter(void (* callback)(CJDragInfo info),uint32_t componentName)316 void FfiOHOSAceFrameworkInteractableViewOnDragEnter(void (*callback)(CJDragInfo info), uint32_t componentName)
317 {
318 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
319 auto ffiCallback = CJLambda::Create(callback);
320 auto onDragEnter = [ffiCallback, fnode = frameNode](const RefPtr<DragEvent>& info, const std::string& extraParams) {
321 LOGD("extraParams: %{public}s", extraParams.c_str());
322 PipelineContext::SetCallBackNode(fnode);
323 NG::DragDropBaseInfo itemInfo;
324 CJDragInfo ffiDragInfo {};
325 CJPosition cjPosition {};
326 FFiSetDragInfo(info, extraParams, cjPosition, ffiDragInfo);
327 ffiDragInfo.position = &cjPosition;
328 ffiCallback(ffiDragInfo);
329 };
330
331 ViewAbstractModel::GetInstance()->SetOnDragEnter(std::move(onDragEnter));
332 }
333
FfiOHOSAceFrameworkInteractableViewOnDragMove(void (* callback)(CJDragInfo info),uint32_t componentName)334 void FfiOHOSAceFrameworkInteractableViewOnDragMove(void (*callback)(CJDragInfo info), uint32_t componentName)
335 {
336 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
337 auto ffiCallback = CJLambda::Create(callback);
338 auto onDragMove = [ffiCallback, fnode = frameNode](const RefPtr<DragEvent>& info, const std::string& extraParams) {
339 LOGD("extraParams: %{public}s", extraParams.c_str());
340 PipelineContext::SetCallBackNode(fnode);
341 NG::DragDropBaseInfo itemInfo;
342 CJDragInfo ffiDragInfo {};
343 CJPosition cjPosition {};
344 FFiSetDragInfo(info, extraParams, cjPosition, ffiDragInfo);
345 ffiDragInfo.position = &cjPosition;
346 ffiCallback(ffiDragInfo);
347 };
348
349 ViewAbstractModel::GetInstance()->SetOnDragMove(std::move(onDragMove));
350 }
351
FfiOHOSAceFrameworkInteractableViewOnDragLeave(void (* callback)(CJDragInfo info),uint32_t componentName)352 void FfiOHOSAceFrameworkInteractableViewOnDragLeave(void (*callback)(CJDragInfo info), uint32_t componentName)
353 {
354 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
355 auto ffiCallback = CJLambda::Create(callback);
356 auto onDragLeave = [ffiCallback, fnode = frameNode](const RefPtr<DragEvent>& info, const std::string& extraParams) {
357 LOGD("extraParams: %{public}s", extraParams.c_str());
358 PipelineContext::SetCallBackNode(fnode);
359 NG::DragDropBaseInfo itemInfo;
360 CJDragInfo ffiDragInfo {};
361 CJPosition cjPosition {};
362 FFiSetDragInfo(info, extraParams, cjPosition, ffiDragInfo);
363 ffiDragInfo.position = &cjPosition;
364 ffiCallback(ffiDragInfo);
365 };
366
367 ViewAbstractModel::GetInstance()->SetOnDragLeave(std::move(onDragLeave));
368 }
369
FfiOHOSAceFrameworkInteractableViewOnDrop(void (* callback)(CJDragInfo info),uint32_t componentName)370 void FfiOHOSAceFrameworkInteractableViewOnDrop(void (*callback)(CJDragInfo info), uint32_t componentName)
371 {
372 WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
373 auto ffiCallback = CJLambda::Create(callback);
374 auto onDrop = [ffiCallback, fnode = frameNode](const RefPtr<DragEvent>& info, const std::string& extraParams) {
375 LOGD("extraParams: %{public}s", extraParams.c_str());
376 PipelineContext::SetCallBackNode(fnode);
377 NG::DragDropBaseInfo itemInfo;
378 CJDragInfo ffiDragInfo {};
379 CJPosition cjPosition {};
380 FFiSetDragInfo(info, extraParams, cjPosition, ffiDragInfo);
381 ffiDragInfo.position = &cjPosition;
382 ffiCallback(ffiDragInfo);
383 };
384
385 ViewAbstractModel::GetInstance()->SetOnDrop(std::move(onDrop));
386 }
387 }
388