@Override
  protected void dispatchDraw(Canvas canvas) {
    super.dispatchDraw(canvas);

    if (mDragging) {
      if (mAnimationState == ANIMATION_STATE_STARTING) {
        mAnimationStartTime = SystemClock.uptimeMillis();
        mAnimationState = ANIMATION_STATE_RUNNING;
      }

      if (mAnimationState == ANIMATION_STATE_RUNNING) {
        float normalized =
            (float) (SystemClock.uptimeMillis() - mAnimationStartTime) / mAnimationDuration;
        if (normalized >= 1.0f) {
          mAnimationState = ANIMATION_STATE_DONE;
        }
        normalized = Math.min(normalized, 1.0f);
        final float value = mAnimationFrom + (mAnimationTo - mAnimationFrom) * normalized;

        switch (mAnimationType) {
          case ANIMATION_TYPE_SCALE:
            if (mDrawModeBitmap && mDragBitmap != null) {
              final Bitmap dragBitmap = mDragBitmap;
              canvas.save();
              canvas.translate(
                  getScrollX() + mLastMotionX - mTouchOffsetX - mBitmapOffsetX,
                  getScrollY() + mLastMotionY - mTouchOffsetY - mBitmapOffsetY);
              canvas.translate(
                  (dragBitmap.getWidth() * (1.0f - value)) / 2,
                  (dragBitmap.getHeight() * (1.0f - value)) / 2);
              canvas.scale(value, value);
              canvas.drawBitmap(dragBitmap, 0.0f, 0.0f, mDragPaint);
              canvas.restore();
            } else {
              canvas.save();
              canvas.translate(
                  getScrollX() + mLastMotionX - mTouchOffsetX - mBitmapOffsetX,
                  getScrollY() + mLastMotionY - mTouchOffsetY - mBitmapOffsetY);
              canvas.translate(
                  (mDrawWidth * (1.0f - value)) / 2, (mDrawHeight * (1.0f - value)) / 2);
              canvas.drawRoundRect(
                  new RectF(0, 0, mDrawWidth, mDrawHeight), 8.0f, 8.0f, mRectPaint);
              canvas.restore();
            }
            break;
        }
      } else {
        // Draw actual icon being dragged
        if (mDrawModeBitmap && mDragBitmap != null) {
          canvas.drawBitmap(
              mDragBitmap,
              getScrollX() + mLastMotionX - mTouchOffsetX - mBitmapOffsetX,
              getScrollY() + mLastMotionY - mTouchOffsetY - mBitmapOffsetY,
              mDragPaint);
        } else {
          canvas.save();
          canvas.translate(
              getScrollX() + mLastMotionX - mTouchOffsetX - mBitmapOffsetX,
              getScrollY() + mLastMotionY - mTouchOffsetY - mBitmapOffsetY);
          canvas.drawRoundRect(new RectF(0, 0, mDrawWidth, mDrawHeight), 8.0f, 8.0f, mRectPaint);
          canvas.restore();
        }
      }
    }
    if (pids.length > 0 && AlmostNexusSettingsHelper.getDebugShowMemUsage(getContext())) {
      mRectPaint.setTextSize(debugTextSize);
      mRectPaint.setAntiAlias(true);
      mRectPaint.setColor(0xff000000);
      if (pids.length > 0) canvas.drawRect(0, 0, getWidth(), 70, mRectPaint);
      mRectPaint.setColor(0xffffffff);
      memoryInfoArray = activityManager.getProcessMemoryInfo(pids);
      for (Debug.MemoryInfo pidMemoryInfo : memoryInfoArray) {
        canvas.drawText(
            "getTotalPrivateDirty: " + pidMemoryInfo.getTotalPrivateDirty(),
            0,
            debugTextSize,
            mRectPaint);
        canvas.drawText(
            "getTotalPss: " + pidMemoryInfo.getTotalPss(), 0, debugTextSize * 2, mRectPaint);
        canvas.drawText(
            "getTotalSharedDirty: " + pidMemoryInfo.getTotalSharedDirty(),
            0,
            debugTextSize * 3,
            mRectPaint);
      }
    }
  }