• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }