private void updateClipping(
      StackScrollState resultState,
      StackScrollAlgorithmState algorithmState,
      AmbientState ambientState) {
    Log.d(TAG, "updateClipping: ");
    boolean dismissAllInProgress = ambientState.isDismissAllInProgress();
    float previousNotificationEnd = 0;
    float previousNotificationStart = 0;
    boolean previousNotificationIsSwiped = false;
    int childCount = algorithmState.visibleChildren.size();
    for (int i = 0; i < childCount; i++) {
      ExpandableView child = algorithmState.visibleChildren.get(i);
      StackViewState state = resultState.getViewStateForView(child);
      float newYTranslation = state.yTranslation + state.height * (1f - state.scale) / 2f;
      float newHeight = state.height * state.scale;
      // apply clipping and shadow
      float newNotificationEnd = newYTranslation + newHeight;

      float clipHeight;
      if (previousNotificationIsSwiped) {
        // When the previous notification is swiped, we don't clip the content to the
        // bottom of it.
        clipHeight = newHeight;
      } else {
        clipHeight = newNotificationEnd - previousNotificationEnd;
        clipHeight = Math.max(0.0f, clipHeight);
        if (clipHeight != 0.0f) {

          // In the unlocked shade we have to clip a little bit higher because of the rounded
          // corners of the notifications, but only if we are not fully overlapped by
          // the top card.
          float clippingCorrection = state.dimmed ? 0 : mRoundedRectCornerRadius * state.scale;
          clipHeight += clippingCorrection;
        }
      }

      updateChildClippingAndBackground(
          state, newHeight, clipHeight, newHeight - (previousNotificationStart - newYTranslation));

      if (dismissAllInProgress) {
        state.clipTopAmount = Math.max(child.getMinClipTopAmount(), state.clipTopAmount);
      }

      if (!child.isTransparent()) {
        // Only update the previous values if we are not transparent,
        // otherwise we would clip to a transparent view.
        if ((dismissAllInProgress && canChildBeDismissed(child))) {
          previousNotificationIsSwiped = true;
        } else {
          previousNotificationIsSwiped = ambientState.getDraggedViews().contains(child);
          previousNotificationEnd = newNotificationEnd;
          previousNotificationStart = newYTranslation + state.clipTopAmount * state.scale;
        }
      }
    }
  }