@Override
  public void draw(Canvas canvas) {
    boolean done = true;
    float ratio;

    switch (mTransitionState) {
      case TRANSITION_STARTING:
        // initialize start alphas and start time
        System.arraycopy(mAlphas, 0, mStartAlphas, 0, mLayers.length);
        mStartTimeMs = getCurrentTimeMs();
        // if the duration is 0, update alphas to the target opacities immediately
        ratio = (mDurationMs == 0) ? 1.0f : 0.0f;
        // if all the layers have reached their target opacity, transition is done
        done = updateAlphas(ratio);
        maybeOnFadeStarted();
        mTransitionState = done ? TRANSITION_NONE : TRANSITION_RUNNING;
        break;

      case TRANSITION_RUNNING:
        Preconditions.checkState(mDurationMs > 0);
        // determine ratio based on the elapsed time
        ratio = (float) (getCurrentTimeMs() - mStartTimeMs) / mDurationMs;
        // if all the layers have reached their target opacity, transition is done
        done = updateAlphas(ratio);
        mTransitionState = done ? TRANSITION_NONE : TRANSITION_RUNNING;
        break;

      case TRANSITION_NONE:
        // there is no transition in progress and mAlphas should be left as is.
        done = true;
        break;
    }

    for (int i = 0; i < mLayers.length; i++) {
      drawDrawableWithAlpha(canvas, mLayers[i], (int) Math.ceil(mAlphas[i] * mAlpha / 255.0));
    }

    if (done) {
      maybeOnFadeFinished();
      maybeOnImageShownImmediately();
    } else {
      invalidateSelf();
    }
  }
Updates the current alphas based on the ratio of the elapsed time and duration.

@param ratio
@return whether the all layers have reached their target opacity
drawee/src/main/java/com/facebook/drawee/drawable/FadeDrawable.java