1 /*
2 * Copyright (c) 2025 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 <ani.h>
17 #include <array>
18 #include <iostream>
19 #include <algorithm>
20 #include <chrono>
21 #include <future>
22 #include <thread>
23 #include <map>
24 #include <string>
25
26 #include "frameworks/bridge/declarative_frontend/engine/jsi/jsi_declarative_engine.h"
27 #include "frameworks/base/utils/utils.h"
28 #include "frameworks/base/log/log_wrapper.h"
29 #include "frameworks/bridge/common/utils/engine_helper.h"
30 #include "frameworks/core/common/container.h"
31 #include "frameworks/core/animation/curve.h"
32 #include "frameworks/core/animation/spring_curve.h"
33 #include "test/mock/interfaces/mock_ace_forward_compatibility.cpp"
34 namespace {
35 struct CurvesObj {
36 std::function<ani_double(ani_env*, ani_object, ani_double)> interpolate;
37 std::string curveString;
38 int32_t pageId;
39 };
40
41 typedef enum Curve {
42 Linear = 0,
43 Ease = 1,
44 EaseIn = 2,
45 EaseOut = 3,
46 EaseInOut = 4,
47 FastOutSlowIn = 5,
48 LinearOutSlowIn = 6,
49 FastOutLinearIn = 7,
50 ExtremeDeceleration = 8,
51 Sharp = 9,
52 Rhythm = 10,
53 Smooth = 11,
54 Friction = 12,
55 } Curve;
56
57 }
58
GetStagingPage(int32_t instanceId)59 OHOS::Ace::RefPtr<OHOS::Ace::Framework::JsAcePage> GetStagingPage(int32_t instanceId)
60 {
61 auto engine = OHOS::Ace::EngineHelper::GetEngine(instanceId);
62 auto jsiEngine = OHOS::Ace::AceType::DynamicCast<OHOS::Ace::Framework::JsiDeclarativeEngine>(engine);
63 if (!jsiEngine) {
64 return nullptr;
65 }
66 auto engineInstance = jsiEngine->GetEngineInstance();
67 if (engineInstance == nullptr) {
68 return nullptr;
69 }
70 return engineInstance->GetStagingPage();
71 }
72
GetCubicBezierCurveString(ani_double x1,ani_double y1,ani_double x2,ani_double y2)73 std::string GetCubicBezierCurveString(ani_double x1, ani_double y1, ani_double x2, ani_double y2)
74 {
75 float x1Value = 0.0f;
76 float y1Value = 0.0f;
77 float x2Value = 0.0f;
78 float y2Value = 0.0f;
79 if (!std::isnan(x1)) {
80 x1Value = static_cast<float>(x1);
81 }
82 if (!std::isnan(y1)) {
83 y1Value = static_cast<float>(y1);
84 }
85 if (!std::isnan(x2)) {
86 x2Value = static_cast<float>(x2);
87 }
88 if (!std::isnan(y2)) {
89 y2Value = static_cast<float>(y2);
90 }
91 x1Value = std::clamp(x1Value, 0.0f, 1.0f);
92 x2Value = std::clamp(x2Value, 0.0f, 1.0f);
93
94 auto curve = OHOS::Ace::AceType::MakeRefPtr<OHOS::Ace::CubicCurve>(x1Value, y1Value, x2Value, y2Value);
95 return curve->ToString();
96 }
97
GetSpringMotionCurveString(ani_env * env,ani_object response,ani_object dampingFraction,ani_object overlapDuration)98 std::string GetSpringMotionCurveString(ani_env *env,
99 ani_object response, ani_object dampingFraction, ani_object overlapDuration)
100 {
101 float responseValue = OHOS::Ace::ResponsiveSpringMotion::DEFAULT_SPRING_MOTION_RESPONSE;
102 float dampingFractionValue = OHOS::Ace::ResponsiveSpringMotion::DEFAULT_SPRING_MOTION_DAMPING_RATIO;
103 float overlapDurationValue = OHOS::Ace::ResponsiveSpringMotion::DEFAULT_SPRING_MOTION_BLEND_DURATION;
104
105 ani_boolean isUndefinedResponse = true;
106 env->Reference_IsUndefined(response, &isUndefinedResponse);
107 if (!isUndefinedResponse) {
108 ani_double resultResponse;
109 if (ANI_OK == env->Object_CallMethodByName_Double(response, "doubleValue", nullptr, &resultResponse)) {
110 double value = static_cast<double>(resultResponse);
111 responseValue = static_cast<float>(value);
112 }
113 }
114 ani_boolean isUndefinedDampingFraction = true;
115 env->Reference_IsUndefined(dampingFraction, &isUndefinedDampingFraction);
116 if (!isUndefinedDampingFraction) {
117 ani_double resultDampingFraction;
118 if (ANI_OK == env->Object_CallMethodByName_Double(dampingFraction, "doubleValue",
119 nullptr, &resultDampingFraction)) {
120 double value = static_cast<double>(resultDampingFraction);
121 dampingFractionValue = static_cast<float>(value);
122 }
123 }
124 ani_boolean isUndefinedOverlapDuration = true;
125 env->Reference_IsUndefined(overlapDuration, &isUndefinedOverlapDuration);
126 if (!isUndefinedOverlapDuration) {
127 ani_double resultOverlapDuration;
128 if (ANI_OK == env->Object_CallMethodByName_Double(overlapDuration, "doubleValue",
129 nullptr, &resultOverlapDuration)) {
130 double value = static_cast<double>(resultOverlapDuration);
131 overlapDurationValue = static_cast<float>(value);
132 }
133 }
134 if (OHOS::Ace::LessOrEqual(responseValue, 0)) {
135 responseValue = OHOS::Ace::ResponsiveSpringMotion::DEFAULT_SPRING_MOTION_RESPONSE;
136 }
137 if (OHOS::Ace::LessNotEqual(dampingFractionValue, 0)) {
138 dampingFractionValue = OHOS::Ace::ResponsiveSpringMotion::DEFAULT_SPRING_MOTION_DAMPING_RATIO;
139 }
140 if (OHOS::Ace::LessNotEqual(overlapDurationValue, 0)) {
141 overlapDurationValue = OHOS::Ace::ResponsiveSpringMotion::DEFAULT_SPRING_MOTION_BLEND_DURATION;
142 }
143 auto curve = OHOS::Ace::AceType::MakeRefPtr<OHOS::Ace::ResponsiveSpringMotion>(
144 responseValue, dampingFractionValue, overlapDurationValue);
145 return curve->ToString();
146 }
147
GetCurvesInitInternalMap(int curveType)148 std::string GetCurvesInitInternalMap(int curveType)
149 {
150 static std::map<int, std::string> curveMap = {
151 { static_cast<int>(Curve::Linear), "linear" },
152 { static_cast<int>(Curve::Ease), "ease" },
153 { static_cast<int>(Curve::EaseIn), "ease-in" },
154 { static_cast<int>(Curve::EaseOut), "ease-out" },
155 { static_cast<int>(Curve::EaseInOut), "ease-in-out" },
156 { static_cast<int>(Curve::FastOutSlowIn), "fast-out-slow-in" },
157 { static_cast<int>(Curve::LinearOutSlowIn), "linear-out-slow-in" },
158 { static_cast<int>(Curve::FastOutLinearIn), "fast-out-linear-in" },
159 { static_cast<int>(Curve::ExtremeDeceleration), "extreme-deceleration" },
160 { static_cast<int>(Curve::Sharp), "sharp" },
161 { static_cast<int>(Curve::Rhythm), "rhythm" },
162 { static_cast<int>(Curve::Smooth), "smooth" },
163 { static_cast<int>(Curve::Friction), "friction" },
164 };
165
166 auto curveString = OHOS::Ace::Framework::CreateCurve(curveMap[curveType]);
167 return curveString->ToString();
168 }
169
unwrapp(ani_env * env,ani_object object)170 static CurvesObj* unwrapp(ani_env *env, ani_object object)
171 {
172 ani_long curvesObj;
173 if (ANI_OK != env->Object_GetFieldByName_Long(object, "nativeContext", &curvesObj)) {
174 return nullptr;
175 }
176 return reinterpret_cast<CurvesObj*>(curvesObj);
177 }
178
Interpolate(ani_env * env,ani_object object,ani_double fraction)179 static ani_double Interpolate([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object object, ani_double fraction)
180 {
181 auto curveObject = unwrapp(env, object);
182 if (!curveObject) {
183 return 0.0;
184 }
185 auto curveString = curveObject->curveString;
186 float time = static_cast<float>(fraction);
187 time = std::clamp(time, 0.0f, 1.0f);
188 auto animationCurve = OHOS::Ace::Framework::CreateCurve(curveString, false);
189 if (!animationCurve) {
190 return 0.0;
191 }
192 ani_double curveValue = static_cast<ani_double>(animationCurve->Move(time));
193 return curveValue;
194 }
195
CubicBezier(ani_env * env,ani_double x1,ani_double y1,ani_double x2,ani_double y2)196 static ani_string CubicBezier([[maybe_unused]] ani_env *env,
197 ani_double x1, ani_double y1, ani_double x2, ani_double y2)
198 {
199 auto curvesStr = GetCubicBezierCurveString(x1, y1, x2, y2);
200 ani_string ret;
201 env->String_NewUTF8(curvesStr.c_str(), curvesStr.size(), &ret);
202 return ret;
203 }
204
CubicBezierCurve(ani_env * env,ani_double x1,ani_double y1,ani_double x2,ani_double y2)205 static ani_object CubicBezierCurve([[maybe_unused]] ani_env *env,
206 ani_double x1, ani_double y1, ani_double x2, ani_double y2)
207 {
208 static const char *className = "L@ohos/curves/curves/Curves;";
209 ani_class cls;
210 if (ANI_OK != env->FindClass(className, &cls)) {
211 return nullptr;
212 }
213
214 ani_method ctor;
215 if (ANI_OK != env->Class_FindMethod(cls, "<ctor>", nullptr, &ctor)) {
216 return nullptr;
217 }
218
219 CurvesObj* cubicBezierCurve = new CurvesObj();
220 cubicBezierCurve->interpolate = Interpolate;
221 std::string curveString = GetCubicBezierCurveString(x1, y1, x2, y2);
222
223 cubicBezierCurve->curveString = curveString;
224 std::string curveStr = curveString;
225 ani_string curveAniStr;
226 env->String_NewUTF8(curveStr.c_str(), curveStr.size(), &curveAniStr);
227
228 ani_object curve_object;
229
230 if (ANI_OK != env->Object_New(cls, ctor, &curve_object, reinterpret_cast<ani_object>(cubicBezierCurve))) {
231 return nullptr;
232 }
233
234 if (OHOS::Ace::Container::IsCurrentUseNewPipeline()) {
235 return curve_object;
236 }
237 auto page = GetStagingPage(OHOS::Ace::Container::CurrentId());
238 int32_t pageId = -1;
239 if (page) {
240 pageId = page->GetPageId();
241 }
242 cubicBezierCurve->pageId = pageId;
243
244 ani_object curveNew_object;
245 if (ANI_OK != env->Object_New(cls, ctor, &curveNew_object, reinterpret_cast<ani_object>(cubicBezierCurve))) {
246 return nullptr;
247 }
248
249 return curveNew_object;
250 }
251
SpringCurve(ani_env * env,ani_double velocity,ani_double mass,ani_double stiffness,ani_double damping)252 static ani_object SpringCurve([[maybe_unused]] ani_env* env,
253 ani_double velocity, ani_double mass, ani_double stiffness, ani_double damping)
254 {
255 static const char* className = "L@ohos/curves/curves/Curves;";
256 ani_class cls;
257 if (ANI_OK != env->FindClass(className, &cls)) {
258 return nullptr;
259 }
260
261 ani_method ctor;
262 if (ANI_OK != env->Class_FindMethod(cls, "<ctor>", nullptr, &ctor)) {
263 return nullptr;
264 }
265
266 CurvesObj* springCurve = new CurvesObj();
267 springCurve->interpolate = Interpolate;
268 if (OHOS::Ace::LessOrEqual(mass, 0)) {
269 mass = 1.0;
270 }
271 if (OHOS::Ace::LessOrEqual(stiffness, 0)) {
272 stiffness = 1.0;
273 }
274 if (OHOS::Ace::LessOrEqual(damping, 0)) {
275 damping = 1.0;
276 }
277 auto curve = OHOS::Ace::AceType::MakeRefPtr<OHOS::Ace::SpringCurve>(velocity, mass, stiffness, damping);
278 std::string curveString = curve->ToString();
279
280 springCurve->curveString = curveString;
281 ani_string curveAniStr {};
282 env->String_NewUTF8(curveString.c_str(), curveString.size(), &curveAniStr);
283
284 ani_object obj;
285
286 if (ANI_OK != env->Object_New(cls, ctor, &obj, reinterpret_cast<ani_object>(springCurve))) {
287 return nullptr;
288 }
289
290 if (OHOS::Ace::Container::IsCurrentUseNewPipeline()) {
291 return obj;
292 }
293 auto page = GetStagingPage(OHOS::Ace::Container::CurrentId());
294 int32_t pageId = -1;
295 if (page) {
296 pageId = page->GetPageId();
297 }
298 springCurve->pageId = pageId;
299
300 ani_object objNew;
301 if (ANI_OK != env->Object_New(cls, ctor, &objNew, reinterpret_cast<ani_object>(springCurve))) {
302 return nullptr;
303 }
304
305 return objNew;
306 }
307
GetSpringResponsiveMotionCurveString(ani_env * env,ani_object response,ani_object dampingFraction,ani_object overlapDuration)308 std::string GetSpringResponsiveMotionCurveString(ani_env *env,
309 ani_object response, ani_object dampingFraction, ani_object overlapDuration)
310 {
311 float responseValue = OHOS::Ace::ResponsiveSpringMotion::DEFAULT_RESPONSIVE_SPRING_MOTION_RESPONSE;
312 float dampingFractionValue = OHOS::Ace::ResponsiveSpringMotion::DEFAULT_RESPONSIVE_SPRING_MOTION_DAMPING_RATIO;
313 float overlapDurationValue = OHOS::Ace::ResponsiveSpringMotion::DEFAULT_RESPONSIVE_SPRING_MOTION_BLEND_DURATION;
314
315 ani_boolean isUndefinedResponse = true;
316 env->Reference_IsUndefined(response, &isUndefinedResponse);
317 if (!isUndefinedResponse) {
318 ani_double resultResponse;
319 if (ANI_OK == env->Object_CallMethodByName_Double(response, "doubleValue", nullptr, &resultResponse)) {
320 double value = static_cast<double>(resultResponse);
321 responseValue = static_cast<float>(value);
322 }
323 }
324 ani_boolean isUndefinedDampingFraction = true;
325 env->Reference_IsUndefined(dampingFraction, &isUndefinedDampingFraction);
326 if (!isUndefinedDampingFraction) {
327 ani_double resultDampingFraction;
328 if (ANI_OK == env->Object_CallMethodByName_Double(dampingFraction, "doubleValue",
329 nullptr, &resultDampingFraction)) {
330 double value = static_cast<double>(resultDampingFraction);
331 dampingFractionValue = static_cast<float>(value);
332 }
333 }
334 ani_boolean isUndefinedOverlapDuration = true;
335 env->Reference_IsUndefined(overlapDuration, &isUndefinedOverlapDuration);
336 if (!isUndefinedOverlapDuration) {
337 ani_double resultOverlapDuration;
338 if (ANI_OK == env->Object_CallMethodByName_Double(overlapDuration, "doubleValue",
339 nullptr, &resultOverlapDuration)) {
340 double value = static_cast<double>(resultOverlapDuration);
341 overlapDurationValue = static_cast<float>(value);
342 }
343 }
344 if (OHOS::Ace::LessOrEqual(responseValue, 0)) {
345 responseValue = OHOS::Ace::ResponsiveSpringMotion::DEFAULT_RESPONSIVE_SPRING_MOTION_RESPONSE;
346 }
347 if (OHOS::Ace::LessNotEqual(dampingFractionValue, 0)) {
348 dampingFractionValue = OHOS::Ace::ResponsiveSpringMotion::DEFAULT_RESPONSIVE_SPRING_MOTION_DAMPING_RATIO;
349 }
350 if (OHOS::Ace::LessNotEqual(overlapDurationValue, 0)) {
351 overlapDurationValue = OHOS::Ace::ResponsiveSpringMotion::DEFAULT_RESPONSIVE_SPRING_MOTION_BLEND_DURATION;
352 }
353 auto curve = OHOS::Ace::AceType::MakeRefPtr<OHOS::Ace::ResponsiveSpringMotion>(
354 responseValue, dampingFractionValue, overlapDurationValue);
355 return curve->ToString();
356 }
357
SpringResponsiveMotion(ani_env * env,ani_object response,ani_object dampingFraction,ani_object overlapDuration)358 static ani_object SpringResponsiveMotion([[maybe_unused]] ani_env *env,
359 ani_object response, ani_object dampingFraction, ani_object overlapDuration)
360 {
361 CurvesObj* springResponsiveMotion = new CurvesObj();
362 springResponsiveMotion->interpolate = Interpolate;
363 static const char *className = "L@ohos/curves/curves/Curves;";
364 ani_class cls;
365 if (ANI_OK != env->FindClass(className, &cls)) {
366 return nullptr;
367 }
368 ani_method ctor;
369 if (ANI_OK != env->Class_FindMethod(cls, "<ctor>", nullptr, &ctor)) {
370 return nullptr;
371 }
372 std::string curveString = GetSpringResponsiveMotionCurveString(env, response, dampingFraction, overlapDuration);
373 springResponsiveMotion->curveString = curveString;
374 std::string curveStr = curveString;
375 ani_string curveAniStr;
376 env->String_NewUTF8(curveStr.c_str(), curveStr.size(), &curveAniStr);
377
378 ani_object curve_object;
379 if (ANI_OK != env->Object_New(cls, ctor, &curve_object, reinterpret_cast<ani_object>(springResponsiveMotion))) {
380 return nullptr;
381 }
382
383 if (OHOS::Ace::Container::IsCurrentUseNewPipeline()) {
384 return curve_object;
385 }
386 auto page = GetStagingPage(OHOS::Ace::Container::CurrentId());
387 int32_t pageId = -1;
388 if (page) {
389 pageId = page->GetPageId();
390 }
391 springResponsiveMotion->pageId = pageId;
392
393 ani_object curveNew_object;
394 if (ANI_OK != env->Object_New(cls, ctor, &curveNew_object, reinterpret_cast<ani_object>(springResponsiveMotion))) {
395 return nullptr;
396 }
397 return curveNew_object;
398 }
399
SpringMotion(ani_env * env,ani_object response,ani_object dampingFraction,ani_object overlapDuration)400 static ani_object SpringMotion([[maybe_unused]] ani_env *env,
401 ani_object response, ani_object dampingFraction, ani_object overlapDuration)
402 {
403 CurvesObj* springMotion = new CurvesObj();
404 springMotion->interpolate = Interpolate;
405 static const char *className = "L@ohos/curves/curves/Curves;";
406 ani_class cls;
407 if (ANI_OK != env->FindClass(className, &cls)) {
408 return nullptr;
409 }
410 ani_method ctor;
411 if (ANI_OK != env->Class_FindMethod(cls, "<ctor>", nullptr, &ctor)) {
412 return nullptr;
413 }
414 std::string curveString = GetSpringMotionCurveString(env, response, dampingFraction, overlapDuration);
415 springMotion->curveString = curveString;
416 std::string curveStr = curveString;
417 ani_string curveAniStr;
418 env->String_NewUTF8(curveStr.c_str(), curveStr.size(), &curveAniStr);
419
420 ani_object curve_object;
421 if (ANI_OK != env->Object_New(cls, ctor, &curve_object, reinterpret_cast<ani_object>(springMotion))) {
422 return nullptr;
423 }
424
425 if (OHOS::Ace::Container::IsCurrentUseNewPipeline()) {
426 return curve_object;
427 }
428 auto page = GetStagingPage(OHOS::Ace::Container::CurrentId());
429 int32_t pageId = -1;
430 if (page) {
431 pageId = page->GetPageId();
432 }
433 springMotion->pageId = pageId;
434
435 ani_object curveNew_object;
436 if (ANI_OK != env->Object_New(cls, ctor, &curveNew_object, reinterpret_cast<ani_object>(springMotion))) {
437 return nullptr;
438 }
439 return curveNew_object;
440 }
441
InitCurve(ani_env * env,ani_enum_item enumItem)442 static ani_object InitCurve([[maybe_unused]] ani_env* env, ani_enum_item enumItem)
443 {
444 ani_boolean isUndefined;
445 env->Reference_IsUndefined(enumItem, &isUndefined);
446 ani_int curveType;
447 if (isUndefined) {
448 curveType = Curve::Linear;
449 } else {
450 if (ANI_OK != env->EnumItem_GetValue_Int(enumItem, &curveType)) {
451 std::cerr << "Enum_GetEnumItemByIndex curveType FAILD" << std::endl;
452 }
453 }
454 std::string curveString = GetCurvesInitInternalMap(curveType);
455
456 static const char* className = "L@ohos/curves/curves/Curves;";
457 ani_class cls;
458 if (ANI_OK != env->FindClass(className, &cls)) {
459 std::cerr << "Not found '" << className << "'" << std::endl;
460 return nullptr;
461 }
462
463 ani_method ctor;
464 if (ANI_OK != env->Class_FindMethod(cls, "<ctor>", nullptr, &ctor)) {
465 std::cerr << "get ctor Failed'" << className << "'" << std::endl;
466 return nullptr;
467 }
468 CurvesObj* curvesInitInternal = new CurvesObj();
469 curvesInitInternal->interpolate = Interpolate;
470 curvesInitInternal->curveString = curveString;
471 ani_string curveAniStr {};
472 env->String_NewUTF8(curveString.c_str(), curveString.size(), &curveAniStr);
473
474 ani_object obj;
475
476 if (ANI_OK != env->Object_New(cls, ctor, &obj, reinterpret_cast<ani_object>(curvesInitInternal))) {
477 return nullptr;
478 }
479
480 if (OHOS::Ace::Container::IsCurrentUseNewPipeline()) {
481 return obj;
482 }
483 auto page = GetStagingPage(OHOS::Ace::Container::CurrentId());
484 int32_t pageId = -1;
485 if (page) {
486 pageId = page->GetPageId();
487 }
488 curvesInitInternal->pageId = pageId;
489
490 ani_object newObj;
491 if (ANI_OK != env->Object_New(cls, ctor, &newObj, reinterpret_cast<ani_object>(curvesInitInternal))) {
492 return nullptr;
493 }
494 return newObj;
495 }
496
InterpolatingSpring(ani_env * env,ani_double velocity,ani_double mass,ani_double stiffness,ani_double damping)497 static ani_object InterpolatingSpring([[maybe_unused]] ani_env* env,
498 ani_double velocity, ani_double mass, ani_double stiffness, ani_double damping)
499 {
500 static const char* className = "L@ohos/curves/curves/Curves;";
501 ani_class cls;
502 if (ANI_OK != env->FindClass(className, &cls)) {
503 std::cerr << "Not found '" << className << "'" << std::endl;
504 return nullptr;
505 }
506
507 ani_method ctor;
508 if (ANI_OK != env->Class_FindMethod(cls, "<ctor>", nullptr, &ctor)) {
509 std::cerr << "get ctor Failed'" << className << "'" << std::endl;
510 return nullptr;
511 }
512
513 CurvesObj* interpolatingCurve = new CurvesObj();
514 interpolatingCurve->interpolate = Interpolate;
515 if (OHOS::Ace::LessOrEqual(mass, 0)) {
516 mass = 1.0;
517 }
518 if (OHOS::Ace::LessOrEqual(stiffness, 0)) {
519 stiffness = 1.0;
520 }
521 if (OHOS::Ace::LessOrEqual(damping, 0)) {
522 damping = 1.0;
523 }
524 auto curve = OHOS::Ace::AceType::MakeRefPtr<OHOS::Ace::InterpolatingSpring>(velocity, mass, stiffness, damping);
525 std::string curveString = curve->ToString();
526
527 interpolatingCurve->curveString = curveString;
528 ani_string curveAniStr {};
529 env->String_NewUTF8(curveString.c_str(), curveString.size(), &curveAniStr);
530
531 ani_object obj;
532
533 if (ANI_OK != env->Object_New(cls, ctor, &obj, reinterpret_cast<ani_object>(interpolatingCurve))) {
534 std::cerr << "New curve object Fail" << std::endl;
535 return nullptr;
536 }
537
538 if (OHOS::Ace::Container::IsCurrentUseNewPipeline()) {
539 return obj;
540 }
541 auto page = GetStagingPage(OHOS::Ace::Container::CurrentId());
542 int32_t pageId = -1;
543 if (page) {
544 pageId = page->GetPageId();
545 }
546 interpolatingCurve->pageId = pageId;
547
548 ani_object objNew;
549 if (ANI_OK != env->Object_New(cls, ctor, &objNew, reinterpret_cast<ani_object>(interpolatingCurve))) {
550 std::cerr << "New curve object Fail" << std::endl;
551 return nullptr;
552 }
553
554 return objNew;
555 }
556
ANI_Constructor(ani_vm * vm,uint32_t * result)557 ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result)
558 {
559 ani_env *env;
560 if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env)) {
561 return ANI_ERROR;
562 }
563 ani_namespace ns;
564 if (ANI_OK != env->FindNamespace("L@ohos/curves/curves;", &ns)) {
565 return ANI_ERROR;
566 }
567 std::array methods = {
568 ani_native_function {"cubicBezier", nullptr, reinterpret_cast<void *>(CubicBezier)},
569 ani_native_function {"cubicBezierCurve", nullptr, reinterpret_cast<void *>(CubicBezierCurve)},
570 ani_native_function {"springMotion", nullptr, reinterpret_cast<void *>(SpringMotion)},
571 ani_native_function {"initCurve", nullptr, reinterpret_cast<void*>(InitCurve)},
572 ani_native_function {"interpolatingSpring", nullptr, reinterpret_cast<void*>(InterpolatingSpring)},
573 ani_native_function {"springCurve", nullptr, reinterpret_cast<void*>(SpringCurve)},
574 ani_native_function {"responsiveSpringMotion", nullptr, reinterpret_cast<void*>(SpringResponsiveMotion)}
575 };
576 if (ANI_OK != env->Namespace_BindNativeFunctions(ns, methods.data(), methods.size())) {
577 return ANI_ERROR;
578 }
579
580 static const char *classNameCurves = "L@ohos/curves/curves/Curves;";
581 ani_class clsCurves;
582 if (ANI_OK != env->FindClass(classNameCurves, &clsCurves)) {
583 return ANI_ERROR;
584 }
585 std::array methodsCurves = {
586 ani_native_function {"interpolate", nullptr, reinterpret_cast<void *>(Interpolate)},
587 };
588
589 if (ANI_OK != env->Class_BindNativeMethods(clsCurves, methodsCurves.data(), methodsCurves.size())) {
590 return ANI_ERROR;
591 };
592
593 *result = ANI_VERSION_1;
594 return ANI_OK;
595 }