Support Keyframe definition for AVD on RT

BUG: 27441613
Change-Id: Iece386f65f3704d1b7caa2b3690a8d3048ccf6e2
diff --git a/libs/hwui/PropertyValuesHolder.h b/libs/hwui/PropertyValuesHolder.h
index b905fae..432f8ba 100644
--- a/libs/hwui/PropertyValuesHolder.h
+++ b/libs/hwui/PropertyValuesHolder.h
@@ -31,91 +31,130 @@
 class ANDROID_API PropertyValuesHolder {
 public:
     virtual void setFraction(float fraction) = 0;
-    void setPropertyDataSource(float* dataSource, int length) {
-        mDataSource.insert(mDataSource.begin(), dataSource, dataSource + length);
-    }
-   float getValueFromData(float fraction);
-   virtual ~PropertyValuesHolder() {}
-protected:
-   std::vector<float> mDataSource;
+    virtual ~PropertyValuesHolder() {}
 };
 
-class ANDROID_API GroupPropertyValuesHolder : public PropertyValuesHolder {
+template <typename T>
+class Evaluator {
+public:
+    virtual void evaluate(T* out, const T& from, const T& to, float fraction) const {};
+    virtual ~Evaluator() {}
+};
+
+class FloatEvaluator : public Evaluator<float> {
+public:
+    virtual void evaluate(float* out, const float& from, const float& to, float fraction)
+            const override {
+        *out = from * (1 - fraction) + to * fraction;
+    }
+};
+
+class ANDROID_API ColorEvaluator : public Evaluator<SkColor> {
+public:
+    virtual void evaluate(SkColor* outColor, const SkColor& from, const SkColor& to,
+            float fraction) const override;
+};
+
+class ANDROID_API PathEvaluator : public Evaluator<PathData> {
+    virtual void evaluate(PathData* out, const PathData& from, const PathData& to, float fraction)
+            const override;
+};
+
+template <typename T>
+class ANDROID_API PropertyValuesHolderImpl : public PropertyValuesHolder {
+public:
+    PropertyValuesHolderImpl(const T& startValue, const T& endValue)
+            : mStartValue(startValue)
+            , mEndValue(endValue) {}
+    void setPropertyDataSource(T* dataSource, int length) {
+        mDataSource.insert(mDataSource.begin(), dataSource, dataSource + length);
+    }
+    // Calculate the animated value from the data source.
+    const T getValueFromData(float fraction) const;
+    // Convenient method to favor getting animated value from data source. If no data source is set
+    // fall back to linear interpolation.
+    const T calculateAnimatedValue(float fraction) const;
+protected:
+   std::unique_ptr<Evaluator<T>> mEvaluator = nullptr;
+   // This contains uniformly sampled data throughout the animation duration. The first element
+   // should be the start value and the last should be the end value of the animation. When the
+   // data source is set, we'll favor data source over the linear interpolation of start/end value
+   // for calculation of animated value.
+   std::vector<T> mDataSource;
+   T mStartValue;
+   T mEndValue;
+};
+
+class ANDROID_API GroupPropertyValuesHolder : public PropertyValuesHolderImpl<float> {
 public:
     GroupPropertyValuesHolder(VectorDrawable::Group* ptr, int propertyId, float startValue,
             float endValue)
-            : mGroup(ptr)
-            , mPropertyId(propertyId)
-            , mStartValue(startValue)
-            , mEndValue(endValue){
+            : PropertyValuesHolderImpl(startValue, endValue)
+            , mGroup(ptr)
+            , mPropertyId(propertyId) {
+        mEvaluator.reset(new FloatEvaluator());
     }
     void setFraction(float fraction) override;
 private:
     VectorDrawable::Group* mGroup;
     int mPropertyId;
-    float mStartValue;
-    float mEndValue;
 };
 
-class ANDROID_API FullPathColorPropertyValuesHolder : public PropertyValuesHolder {
+class ANDROID_API FullPathColorPropertyValuesHolder : public PropertyValuesHolderImpl<SkColor> {
 public:
-    FullPathColorPropertyValuesHolder(VectorDrawable::FullPath* ptr, int propertyId, int32_t startValue,
-            int32_t endValue)
-            : mFullPath(ptr)
-            , mPropertyId(propertyId)
-            , mStartValue(startValue)
-            , mEndValue(endValue) {};
+    FullPathColorPropertyValuesHolder(VectorDrawable::FullPath* ptr, int propertyId,
+            SkColor startValue, SkColor endValue)
+            : PropertyValuesHolderImpl(startValue, endValue)
+            , mFullPath(ptr)
+            , mPropertyId(propertyId) {
+        mEvaluator.reset(new ColorEvaluator());
+    }
     void setFraction(float fraction) override;
     static SkColor interpolateColors(SkColor fromColor, SkColor toColor, float fraction);
 private:
     VectorDrawable::FullPath* mFullPath;
     int mPropertyId;
-    int32_t mStartValue;
-    int32_t mEndValue;
 };
 
-class ANDROID_API FullPathPropertyValuesHolder : public PropertyValuesHolder {
+class ANDROID_API FullPathPropertyValuesHolder : public PropertyValuesHolderImpl<float> {
 public:
     FullPathPropertyValuesHolder(VectorDrawable::FullPath* ptr, int propertyId, float startValue,
             float endValue)
-            : mFullPath(ptr)
-            , mPropertyId(propertyId)
-            , mStartValue(startValue)
-            , mEndValue(endValue) {};
+            : PropertyValuesHolderImpl(startValue, endValue)
+            , mFullPath(ptr)
+            , mPropertyId(propertyId) {
+        mEvaluator.reset(new FloatEvaluator());
+    };
     void setFraction(float fraction) override;
 private:
     VectorDrawable::FullPath* mFullPath;
     int mPropertyId;
-    float mStartValue;
-    float mEndValue;
 };
 
-class ANDROID_API PathDataPropertyValuesHolder : public PropertyValuesHolder {
+class ANDROID_API PathDataPropertyValuesHolder : public PropertyValuesHolderImpl<PathData> {
 public:
     PathDataPropertyValuesHolder(VectorDrawable::Path* ptr, PathData* startValue,
             PathData* endValue)
-            : mPath(ptr)
-            , mStartValue(*startValue)
-            , mEndValue(*endValue) {};
+            : PropertyValuesHolderImpl(*startValue, *endValue)
+            , mPath(ptr) {
+        mEvaluator.reset(new PathEvaluator());
+    };
     void setFraction(float fraction) override;
 private:
     VectorDrawable::Path* mPath;
     PathData mPathData;
-    PathData mStartValue;
-    PathData mEndValue;
 };
 
-class ANDROID_API RootAlphaPropertyValuesHolder : public PropertyValuesHolder {
+class ANDROID_API RootAlphaPropertyValuesHolder : public PropertyValuesHolderImpl<float> {
 public:
     RootAlphaPropertyValuesHolder(VectorDrawable::Tree* tree, float startValue, float endValue)
-            : mTree(tree)
-            , mStartValue(startValue)
-            , mEndValue(endValue) {}
+            : PropertyValuesHolderImpl(startValue, endValue)
+            , mTree(tree) {
+        mEvaluator.reset(new FloatEvaluator());
+    }
     void setFraction(float fraction) override;
 private:
     VectorDrawable::Tree* mTree;
-    float mStartValue;
-    float mEndValue;
 };
 }
 }