Re-enable ViewPropAnimRT

Change-Id: I2f30547c4e2212747c479760dff4f3f901d1eaf3
diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java
index af1de78..fa14bfd 100644
--- a/core/java/android/view/ViewPropertyAnimator.java
+++ b/core/java/android/view/ViewPropertyAnimator.java
@@ -253,10 +253,9 @@
     ViewPropertyAnimator(View view) {
         mView = view;
         view.ensureTransformationInfo();
-        // TODO: Disabled because of b/15287046
-        //if (view.getContext().getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.L) {
-        //    mRTBackend = new ViewPropertyAnimatorRT(view);
-        //}
+        if (view.getContext().getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.L) {
+            mRTBackend = new ViewPropertyAnimatorRT(view);
+        }
     }
 
     /**
@@ -434,6 +433,9 @@
         }
         mPendingAnimations.clear();
         mView.removeCallbacks(mAnimationStarter);
+        if (mRTBackend != null) {
+            mRTBackend.cancelAll();
+        }
     }
 
     /**
diff --git a/core/java/android/view/ViewPropertyAnimatorRT.java b/core/java/android/view/ViewPropertyAnimatorRT.java
index 709efdb..254f254 100644
--- a/core/java/android/view/ViewPropertyAnimatorRT.java
+++ b/core/java/android/view/ViewPropertyAnimatorRT.java
@@ -50,6 +50,15 @@
         return true;
     }
 
+    public void cancelAll() {
+        for (int i = 0; i < mAnimators.length; i++) {
+            if (mAnimators[i] != null) {
+                mAnimators[i].cancel();
+                mAnimators[i] = null;
+            }
+        }
+    }
+
     private void doStartAnimation(ViewPropertyAnimator parent) {
         int size = parent.mPendingAnimations.size();
 
@@ -99,10 +108,27 @@
         if (parent.hasActions()) {
             return false;
         }
+        if (hasAlphaAnimation(parent)) {
+            // TODO: Alpha does too much weird stuff currently to safely RT-accelerate
+            // see View:getFinalAlpha() and friends, which need to be fixed to
+            // work with RT animators
+            return false;
+        }
         // Here goes nothing...
         return true;
     }
 
+    private boolean hasAlphaAnimation(ViewPropertyAnimator parent) {
+        int size = parent.mPendingAnimations.size();
+        for (int i = 0; i < size; i++) {
+            NameValuesHolder holder = parent.mPendingAnimations.get(i);
+            if (holder.mNameConstant == ViewPropertyAnimator.ALPHA) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private void cancelAnimators(ArrayList<NameValuesHolder> mPendingAnimations) {
         int size = mPendingAnimations.size();
         for (int i = 0; i < size; i++) {
diff --git a/libs/hwui/Animator.cpp b/libs/hwui/Animator.cpp
index eff3011..dc6d852 100644
--- a/libs/hwui/Animator.cpp
+++ b/libs/hwui/Animator.cpp
@@ -160,6 +160,10 @@
     (target->mutateStagingProperties().*mPropertyAccess->setter)(finalValue());
 }
 
+uint32_t RenderPropertyAnimator::dirtyMask() {
+    return mPropertyAccess->dirtyMask;
+}
+
 float RenderPropertyAnimator::getValue(RenderNode* target) const {
     return (target->properties().*mPropertyAccess->getter)();
 }
diff --git a/libs/hwui/Animator.h b/libs/hwui/Animator.h
index 203cdff..6cb72c4c 100644
--- a/libs/hwui/Animator.h
+++ b/libs/hwui/Animator.h
@@ -61,6 +61,8 @@
     bool isFinished() { return mPlayState == FINISHED; }
     float finalValue() { return mFinalValue; }
 
+    ANDROID_API virtual uint32_t dirtyMask() { return 0; }
+
 protected:
     BaseRenderNodeAnimator(float finalValue);
     virtual ~BaseRenderNodeAnimator();
@@ -112,6 +114,8 @@
 
     ANDROID_API virtual void onAttached(RenderNode* target);
 
+    ANDROID_API virtual uint32_t dirtyMask();
+
 protected:
     virtual float getValue(RenderNode* target) const;
     virtual void setValue(RenderNode* target, float value);
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index b2fe849..2d6d409 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -189,6 +189,8 @@
     // UI thread only!
     ANDROID_API void removeAnimator(const sp<BaseRenderNodeAnimator>& animator) {
         mStagingAnimators.erase(animator);
+        // Force a sync of the staging property value
+        mDirtyPropertyFields |= animator->dirtyMask();
         mNeedsAnimatorsSync = true;
     }