public void onTouchUp() {
    int xThreshold = mCellLayout.getCellWidth() + mCellLayout.getWidthGap();
    int yThreshold = mCellLayout.getCellHeight() + mCellLayout.getHeightGap();

    mDeltaXAddOn = mRunningHInc * xThreshold;
    mDeltaYAddOn = mRunningVInc * yThreshold;
    mDeltaX = 0;
    mDeltaY = 0;

    post(
        new Runnable() {
          @Override
          public void run() {
            snapToWidget(true);
          }
        });
  }
  /** Based on the current deltas, we determine if and how to resize the widget. */
  private void resizeWidgetIfNeeded(boolean onDismiss) {
    int xThreshold = mCellLayout.getCellWidth() + mCellLayout.getWidthGap();
    int yThreshold = mCellLayout.getCellHeight() + mCellLayout.getHeightGap();

    int deltaX = mDeltaX + mDeltaXAddOn;
    int deltaY = mDeltaY + mDeltaYAddOn;

    float hSpanIncF = 1.0f * deltaX / xThreshold - mRunningHInc;
    float vSpanIncF = 1.0f * deltaY / yThreshold - mRunningVInc;

    int hSpanInc = 0;
    int vSpanInc = 0;
    int cellXInc = 0;
    int cellYInc = 0;

    int countX = mCellLayout.getCountX();
    int countY = mCellLayout.getCountY();

    if (Math.abs(hSpanIncF) > RESIZE_THRESHOLD) {
      hSpanInc = Math.round(hSpanIncF);
    }
    if (Math.abs(vSpanIncF) > RESIZE_THRESHOLD) {
      vSpanInc = Math.round(vSpanIncF);
    }

    if (!onDismiss && (hSpanInc == 0 && vSpanInc == 0)) return;

    CellLayout.LayoutParams lp = (CellLayout.LayoutParams) mWidgetView.getLayoutParams();

    int spanX = lp.cellHSpan;
    int spanY = lp.cellVSpan;
    int cellX = lp.useTmpCoords ? lp.tmpCellX : lp.cellX;
    int cellY = lp.useTmpCoords ? lp.tmpCellY : lp.cellY;

    int hSpanDelta = 0;
    int vSpanDelta = 0;

    // For each border, we bound the resizing based on the minimum width, and the maximum
    // expandability.
    if (mLeftBorderActive) {
      cellXInc = Math.max(-cellX, hSpanInc);
      cellXInc = Math.min(lp.cellHSpan - mMinHSpan, cellXInc);
      hSpanInc *= -1;
      hSpanInc = Math.min(cellX, hSpanInc);
      hSpanInc = Math.max(-(lp.cellHSpan - mMinHSpan), hSpanInc);
      hSpanDelta = -hSpanInc;

    } else if (mRightBorderActive) {
      hSpanInc = Math.min(countX - (cellX + spanX), hSpanInc);
      hSpanInc = Math.max(-(lp.cellHSpan - mMinHSpan), hSpanInc);
      hSpanDelta = hSpanInc;
    }

    if (mTopBorderActive) {
      cellYInc = Math.max(-cellY, vSpanInc);
      cellYInc = Math.min(lp.cellVSpan - mMinVSpan, cellYInc);
      vSpanInc *= -1;
      vSpanInc = Math.min(cellY, vSpanInc);
      vSpanInc = Math.max(-(lp.cellVSpan - mMinVSpan), vSpanInc);
      vSpanDelta = -vSpanInc;
    } else if (mBottomBorderActive) {
      vSpanInc = Math.min(countY - (cellY + spanY), vSpanInc);
      vSpanInc = Math.max(-(lp.cellVSpan - mMinVSpan), vSpanInc);
      vSpanDelta = vSpanInc;
    }

    mDirectionVector[0] = 0;
    mDirectionVector[1] = 0;
    // Update the widget's dimensions and position according to the deltas computed above
    if (mLeftBorderActive || mRightBorderActive) {
      spanX += hSpanInc;
      cellX += cellXInc;
      if (hSpanDelta != 0) {
        mDirectionVector[0] = mLeftBorderActive ? -1 : 1;
      }
    }

    if (mTopBorderActive || mBottomBorderActive) {
      spanY += vSpanInc;
      cellY += cellYInc;
      if (vSpanDelta != 0) {
        mDirectionVector[1] = mTopBorderActive ? -1 : 1;
      }
    }

    if (!onDismiss && vSpanDelta == 0 && hSpanDelta == 0) return;

    // We always want the final commit to match the feedback, so we make sure to use the
    // last used direction vector when committing the resize / reorder.
    if (onDismiss) {
      mDirectionVector[0] = mLastDirectionVector[0];
      mDirectionVector[1] = mLastDirectionVector[1];
    } else {
      mLastDirectionVector[0] = mDirectionVector[0];
      mLastDirectionVector[1] = mDirectionVector[1];
    }

    if (mCellLayout.createAreaForResize(
        cellX, cellY, spanX, spanY, mWidgetView, mDirectionVector, onDismiss)) {
      lp.tmpCellX = cellX;
      lp.tmpCellY = cellY;
      lp.cellHSpan = spanX;
      lp.cellVSpan = spanY;
      mRunningVInc += vSpanDelta;
      mRunningHInc += hSpanDelta;
      if (!onDismiss) {
        updateWidgetSizeRanges(mWidgetView, mLauncher, spanX, spanY);
      }
    }
    mWidgetView.requestLayout();
  }