Fixes to startDelay

 Bug: 15991758

 Don't update the UI thread with final value until after
 startDelay

Change-Id: Ie8bffb5a3ace353ec1d82943a4efcbd01c42c28f
diff --git a/libs/hwui/Animator.cpp b/libs/hwui/Animator.cpp
index 4a8c122..f3ef48b 100644
--- a/libs/hwui/Animator.cpp
+++ b/libs/hwui/Animator.cpp
@@ -32,7 +32,8 @@
  ************************************************************/
 
 BaseRenderNodeAnimator::BaseRenderNodeAnimator(float finalValue)
-        : mFinalValue(finalValue)
+        : mTarget(NULL)
+        , mFinalValue(finalValue)
         , mDeltaValue(0)
         , mFromValue(0)
         , mInterpolator(0)
@@ -81,9 +82,14 @@
     mStartDelay = startDelay;
 }
 
-void BaseRenderNodeAnimator::pushStaging(RenderNode* target, TreeInfo& info) {
+void BaseRenderNodeAnimator::attach(RenderNode* target) {
+    mTarget = target;
+    onAttached();
+}
+
+void BaseRenderNodeAnimator::pushStaging(TreeInfo& info) {
     if (!mHasStartValue) {
-        doSetStartValue(getValue(target));
+        doSetStartValue(getValue(mTarget));
     }
     if (mStagingPlayState > mPlayState) {
         mPlayState = mStagingPlayState;
@@ -109,20 +115,25 @@
     }
     // No interpolator was set, use the default
     if (!mInterpolator) {
-        setInterpolator(Interpolator::createDefaultInterpolator());
+        mInterpolator = Interpolator::createDefaultInterpolator();
     }
     if (mDuration < 0 || mDuration > 50000) {
         ALOGW("Your duration is strange and confusing: %" PRId64, mDuration);
     }
 }
 
-bool BaseRenderNodeAnimator::animate(RenderNode* target, TreeInfo& info) {
+bool BaseRenderNodeAnimator::animate(TreeInfo& info) {
     if (mPlayState < RUNNING) {
         return false;
     }
 
+    // If BaseRenderNodeAnimator is handling the delay (not typical), then
+    // because the staging properties reflect the final value, we always need
+    // to call setValue even if the animation isn't yet running or is still
+    // being delayed as we need to override the staging value
     if (mStartTime > info.frameTimeMs) {
         info.out.hasAnimations |= true;
+        setValue(mTarget, mFromValue);
         return false;
     }
 
@@ -136,7 +147,7 @@
     }
 
     fraction = mInterpolator->interpolate(fraction);
-    setValue(target, mFromValue + (mDeltaValue * fraction));
+    setValue(mTarget, mFromValue + (mDeltaValue * fraction));
 
     if (mPlayState == FINISHED) {
         callOnFinishedListener(info);
@@ -188,12 +199,17 @@
         , mPropertyAccess(&(PROPERTY_ACCESSOR_LUT[property])) {
 }
 
-void RenderPropertyAnimator::onAttached(RenderNode* target) {
+void RenderPropertyAnimator::onAttached() {
     if (!mHasStartValue
-            && target->isPropertyFieldDirty(mPropertyAccess->dirtyMask)) {
-        setStartValue((target->stagingProperties().*mPropertyAccess->getter)());
+            && mTarget->isPropertyFieldDirty(mPropertyAccess->dirtyMask)) {
+        setStartValue((mTarget->stagingProperties().*mPropertyAccess->getter)());
     }
-    (target->mutateStagingProperties().*mPropertyAccess->setter)(finalValue());
+}
+
+void RenderPropertyAnimator::onStagingPlayStateChanged() {
+    if (mStagingPlayState == RUNNING) {
+        (mTarget->mutateStagingProperties().*mPropertyAccess->setter)(finalValue());
+    }
 }
 
 uint32_t RenderPropertyAnimator::dirtyMask() {
diff --git a/libs/hwui/Animator.h b/libs/hwui/Animator.h
index a981b5a..0dda23f 100644
--- a/libs/hwui/Animator.h
+++ b/libs/hwui/Animator.h
@@ -50,12 +50,14 @@
     ANDROID_API void setListener(AnimationListener* listener) {
         mListener = listener;
     }
-    ANDROID_API void start() { mStagingPlayState = RUNNING; }
-    ANDROID_API void cancel() { mStagingPlayState = FINISHED; }
+    ANDROID_API void start() { mStagingPlayState = RUNNING; onStagingPlayStateChanged(); }
+    ANDROID_API void cancel() { mStagingPlayState = FINISHED; onStagingPlayStateChanged(); }
 
-    virtual void onAttached(RenderNode* target) {}
-    virtual void pushStaging(RenderNode* target, TreeInfo& info);
-    bool animate(RenderNode* target, TreeInfo& info);
+    void attach(RenderNode* target);
+    virtual void onAttached() {}
+    void detach() { mTarget = 0; }
+    void pushStaging(TreeInfo& info);
+    bool animate(TreeInfo& info);
 
     bool isFinished() { return mPlayState == FINISHED; }
     float finalValue() { return mFinalValue; }
@@ -68,15 +70,20 @@
 
     virtual float getValue(RenderNode* target) const = 0;
     virtual void setValue(RenderNode* target, float value) = 0;
+    RenderNode* target() { return mTarget; }
 
     void callOnFinishedListener(TreeInfo& info);
 
+    virtual void onStagingPlayStateChanged() {}
+
     enum PlayState {
         NOT_STARTED,
         RUNNING,
         FINISHED,
     };
 
+    RenderNode* mTarget;
+
     float mFinalValue;
     float mDeltaValue;
     float mFromValue;
@@ -92,9 +99,9 @@
     sp<AnimationListener> mListener;
 
 private:
-    void doSetStartValue(float value);
     inline void checkMutable();
-    void transitionToRunning(TreeInfo& info);
+    virtual void transitionToRunning(TreeInfo& info);
+    void doSetStartValue(float value);
 };
 
 class RenderPropertyAnimator : public BaseRenderNodeAnimator {
@@ -116,13 +123,13 @@
 
     ANDROID_API RenderPropertyAnimator(RenderProperty property, float finalValue);
 
-    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);
+    virtual void onAttached();
+    virtual void onStagingPlayStateChanged();
 
 private:
     typedef bool (RenderProperties::*SetFloatProperty)(float value);
diff --git a/libs/hwui/AnimatorManager.cpp b/libs/hwui/AnimatorManager.cpp
index 6a10cf8..27b0893 100644
--- a/libs/hwui/AnimatorManager.cpp
+++ b/libs/hwui/AnimatorManager.cpp
@@ -25,6 +25,7 @@
 using namespace std;
 
 static void unref(BaseRenderNodeAnimator* animator) {
+    animator->detach();
     animator->decStrong(0);
 }
 
@@ -39,7 +40,7 @@
 
 void AnimatorManager::addAnimator(const sp<BaseRenderNodeAnimator>& animator) {
     animator->incStrong(0);
-    animator->onAttached(&mParent);
+    animator->attach(&mParent);
     mNewAnimators.push_back(animator.get());
 }
 
@@ -58,7 +59,7 @@
         move_all(mNewAnimators, mAnimators);
     }
     for (vector<BaseRenderNodeAnimator*>::iterator it = mAnimators.begin(); it != mAnimators.end(); it++) {
-        (*it)->pushStaging(&mParent, info);
+        (*it)->pushStaging(info);
     }
 }
 
@@ -68,7 +69,7 @@
             : mTarget(target), mInfo(info) {}
 
     bool operator() (BaseRenderNodeAnimator* animator) {
-        bool remove = animator->animate(&mTarget, mInfo);
+        bool remove = animator->animate(mInfo);
         if (remove) {
             animator->decStrong(0);
         }