Program: 192871
Project: 192871
Buggy source:
private void startAppearAnimation(boolean isAppearing,float translationDirection,long delay,long duration,final Runnable onFinishedRunnable){
  cancelAppearAnimation();
  mAnimationTranslationY=translationDirection * getActualHeight();
  if (mAppearAnimationFraction == -1.0f) {
    if (isAppearing) {
      mAppearAnimationFraction=0.0f;
      mAppearAnimationTranslation=mAnimationTranslationY;
    }
 else {
      mAppearAnimationFraction=1.0f;
      mAppearAnimationTranslation=0;
    }
  }
  float targetValue;
  if (isAppearing) {
    mCurrentAppearInterpolator=mSlowOutFastInInterpolator;
    mCurrentAlphaInterpolator=mLinearOutSlowInInterpolator;
    targetValue=1.0f;
  }
 else {
    mCurrentAppearInterpolator=mFastOutSlowInInterpolator;
    mCurrentAlphaInterpolator=mSlowOutLinearInInterpolator;
    targetValue=0.0f;
  }
  mAppearAnimator=ValueAnimator.ofFloat(mAppearAnimationFraction,targetValue);
  mAppearAnimator.setInterpolator(mLinearInterpolator);
  mAppearAnimator.setDuration((long)(duration * Math.abs(mAppearAnimationFraction - targetValue)));
  mAppearAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener(){
    @Override public void onAnimationUpdate(    ValueAnimator animation){
      mAppearAnimationFraction=(float)animation.getAnimatedValue();
      updateAppearAnimationAlpha();
      updateAppearRect();
      invalidate();
    }
  }
);
  if (delay > 0) {
    updateAppearAnimationAlpha();
    updateAppearRect();
    mAppearAnimator.setStartDelay(delay);
  }
  mAppearAnimator.addListener(new AnimatorListenerAdapter(){
    private boolean mWasCancelled;
    @Override public void onAnimationEnd(    Animator animation){
      if (onFinishedRunnable != null) {
        onFinishedRunnable.run();
      }
      if (!mWasCancelled) {
        mAppearAnimationFraction=-1;
        setOutlineRect(null);
        enableAppearDrawing(false);
      }
    }
    @Override public void onAnimationStart(    Animator animation){
      mWasCancelled=false;
    }
    @Override public void onAnimationCancel(    Animator animation){
      mWasCancelled=true;
    }
  }
);
  mAppearAnimator.start();
}

Fixed version (ground truth):
private void startAppearAnimation(boolean isAppearing,float translationDirection,long delay,long duration,final Runnable onFinishedRunnable){
  cancelAppearAnimation();
  mAnimationTranslationY=translationDirection * getActualHeight();
  if (mAppearAnimationFraction == -1.0f) {
    if (isAppearing) {
      mAppearAnimationFraction=0.0f;
      mAppearAnimationTranslation=mAnimationTranslationY;
    }
 else {
      mAppearAnimationFraction=1.0f;
      mAppearAnimationTranslation=0;
    }
  }
  float targetValue;
  if (isAppearing) {
    mCurrentAppearInterpolator=mSlowOutFastInInterpolator;
    mCurrentAlphaInterpolator=mLinearOutSlowInInterpolator;
    targetValue=1.0f;
  }
 else {
    mCurrentAppearInterpolator=mFastOutSlowInInterpolator;
    mCurrentAlphaInterpolator=mSlowOutLinearInInterpolator;
    targetValue=0.0f;
  }
  mAppearAnimator=ValueAnimator.ofFloat(mAppearAnimationFraction,targetValue);
  mAppearAnimator.setInterpolator(mLinearInterpolator);
  mAppearAnimator.setDuration((long)(duration * Math.abs(mAppearAnimationFraction - targetValue)));
  mAppearAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener(){
    @Override public void onAnimationUpdate(    ValueAnimator animation){
      mAppearAnimationFraction=(float)animation.getAnimatedValue();
      updateAppearAnimationAlpha();
      updateAppearRect();
      invalidate();
    }
  }
);
  if (delay > 0) {
    updateAppearAnimationAlpha();
    updateAppearRect();
    mAppearAnimator.setStartDelay(delay);
  }
  mAppearAnimator.addListener(new AnimatorListenerAdapter(){
    private boolean mWasCancelled;
    @Override public void onAnimationEnd(    Animator animation){
      if (onFinishedRunnable != null) {
        onFinishedRunnable.run();
      }
      if (!mWasCancelled) {
        enableAppearDrawing(false);
      }
    }
    @Override public void onAnimationStart(    Animator animation){
      mWasCancelled=false;
    }
    @Override public void onAnimationCancel(    Animator animation){
      mWasCancelled=true;
    }
  }
);
  mAppearAnimator.start();
}