Program: 54135
Project: 54135
Buggy source:
/** 
 * Called by TransitionManager to play the transition. This calls createAnimators() to set things up and create all of the animations and then runAnimations() to actually start the animations.
 */
void playTransition(ViewGroup sceneRoot){
  mStartValuesList=new ArrayList<TransitionValues>();
  mEndValuesList=new ArrayList<TransitionValues>();
  matchStartAndEnd(mStartValues,mEndValues);
  ArrayMap<Animator,AnimationInfo> runningAnimators=getRunningAnimators();
  int numOldAnims=runningAnimators.size();
  Object windowId=ViewUtils.getWindowId(sceneRoot);
  for (int i=numOldAnims - 1; i >= 0; i--) {
    Animator anim=runningAnimators.keyAt(i);
    if (anim != null) {
      AnimationInfo oldInfo=runningAnimators.get(anim);
      if (oldInfo != null && oldInfo.view != null && oldInfo.windowId == windowId) {
        TransitionValues oldValues=oldInfo.values;
        View oldView=oldInfo.view;
        TransitionValues startValues=getTransitionValues(oldView,true);
        TransitionValues endValues=getMatchedTransitionValues(oldView,true);
        if (startValues == null && endValues == null) {
          endValues=mEndValues.viewValues.get(oldView);
        }
        boolean cancel=(startValues != null || endValues != null) && oldInfo.transition.areValuesChanged(oldValues,endValues);
        if (cancel) {
          if (anim.isRunning() || AnimatorUtils.isAnimatorStarted(anim)) {
            if (DBG) {
              Log.d(LOG_TAG,"String_Node_Str" + anim);
            }
            anim.cancel();
          }
 else {
            if (DBG) {
              Log.d(LOG_TAG,"String_Node_Str" + anim);
            }
            runningAnimators.remove(anim);
          }
        }
      }
    }
  }
  createAnimators(sceneRoot,mStartValues,mEndValues,mStartValuesList,mEndValuesList);
  runAnimators();
}

Fixed version (ground truth):
/** 
 * Called by TransitionManager to play the transition. This calls createAnimators() to set things up and create all of the animations and then runAnimations() to actually start the animations.
 */
void playTransition(ViewGroup sceneRoot){
  mStartValuesList=new ArrayList<TransitionValues>();
  mEndValuesList=new ArrayList<TransitionValues>();
  matchStartAndEnd(mStartValues,mEndValues);
  ArrayMap<Animator,AnimationInfo> runningAnimators=getRunningAnimators();
synchronized (sRunningAnimators) {
    int numOldAnims=runningAnimators.size();
    Object windowId=ViewUtils.getWindowId(sceneRoot);
    for (int i=numOldAnims - 1; i >= 0; i--) {
      Animator anim=runningAnimators.keyAt(i);
      if (anim != null) {
        AnimationInfo oldInfo=runningAnimators.get(anim);
        if (oldInfo != null && oldInfo.view != null && oldInfo.windowId == windowId) {
          TransitionValues oldValues=oldInfo.values;
          View oldView=oldInfo.view;
          TransitionValues startValues=getTransitionValues(oldView,true);
          TransitionValues endValues=getMatchedTransitionValues(oldView,true);
          if (startValues == null && endValues == null) {
            endValues=mEndValues.viewValues.get(oldView);
          }
          boolean cancel=(startValues != null || endValues != null) && oldInfo.transition.areValuesChanged(oldValues,endValues);
          if (cancel) {
            if (anim.isRunning() || AnimatorUtils.isAnimatorStarted(anim)) {
              if (DBG) {
                Log.d(LOG_TAG,"String_Node_Str" + anim);
              }
              anim.cancel();
            }
 else {
              if (DBG) {
                Log.d(LOG_TAG,"String_Node_Str" + anim);
              }
              runningAnimators.remove(anim);
            }
          }
        }
      }
    }
  }
  createAnimators(sceneRoot,mStartValues,mEndValues,mStartValuesList,mEndValuesList);
  runAnimators();
}