docs: boolean animationFrame(long currentTime) {
          boolean done = false;
  
          if (mPlayingState == STOPPED) {
              mPlayingState = RUNNING;
              if (mSeekTime < 0) {
                  mStartTime = currentTime;
              } else {
                  mStartTime = currentTime - mSeekTime;
                  // Now that we're playing, reset the seek time
                  mSeekTime = -1;
              }
          }
          switch (mPlayingState) {
          case RUNNING:
          case SEEKED:
              float fraction = mDuration > 0 ? (float)(currentTime - mStartTime) / mDuration : 1f;
              if (fraction >= 1f) {
                  if (mCurrentIteration < mRepeatCount || mRepeatCount == INFINITE) {
                      // Time to repeat
                      if (mListeners != null) {
                          int numListeners = mListeners.size();
                          for (int i = 0; i < numListeners; ++i) {
                              mListeners.get(i).onAnimationRepeat(this);
                          }
                      }
                      if (mRepeatMode == REVERSE) {
                          mPlayingBackwards = mPlayingBackwards ? false : true;
                      }
                      mCurrentIteration += (int)fraction;
                      fraction = fraction % 1f;
                      mStartTime += mDuration;
                  } else {
                      done = true;
                      fraction = Math.min(fraction, 1.0f);
                  }
              }
              if (mPlayingBackwards) {
                  fraction = 1f - fraction;
              }
              animateValue(fraction);
              break;
          }
  
          return done;
      }