Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4cb81efa authored by Mady Mellor's avatar Mady Mellor Committed by Android (Google) Code Review
Browse files

Merge "Translate bubbles with IME"

parents a8edeaa4 5d8f140c
Loading
Loading
Loading
Loading
+47 −16
Original line number Diff line number Diff line
@@ -94,6 +94,9 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList
    private boolean mActivityViewReady = false;
    private PendingIntent mBubbleIntent;

    private boolean mKeyboardVisible;
    private boolean mNeedsNewHeight;

    private int mMinHeight;
    private int mHeaderHeight;
    private int mBubbleHeight;
@@ -227,21 +230,15 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList
                true /* singleTaskInstance */);
        addView(mActivityView);

        mActivityView.setOnApplyWindowInsetsListener((View view, WindowInsets insets) -> {
            ActivityView activityView = (ActivityView) view;
            // Here we assume that the position of the ActivityView on the screen
            // remains regardless of IME status. When we move ActivityView, the
            // forwardedInsets should be computed not against the current location
            // and size, but against the post-moved location and size.
            Point displaySize = new Point();
            view.getContext().getDisplay().getSize(displaySize);
            int[] windowLocation = view.getLocationOnScreen();
            final int windowBottom = windowLocation[1] + view.getHeight();
        setOnApplyWindowInsetsListener((View view, WindowInsets insets) -> {
            // Keep track of IME displaying because we should not make any adjustments that might
            // cause a config change while the IME is displayed otherwise it'll loose focus.
            final int keyboardHeight = insets.getSystemWindowInsetBottom()
                    - insets.getStableInsetBottom();
            final int insetsBottom = Math.max(0,
                    windowBottom + keyboardHeight - displaySize.y);
            activityView.setForwardedInsets(Insets.of(0, 0, 0, insetsBottom));
            mKeyboardVisible = keyboardHeight != 0;
            if (!mKeyboardVisible && mNeedsNewHeight) {
                updateHeight();
            }
            return view.onApplyWindowInsets(insets);
        });

@@ -258,6 +255,34 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        mKeyboardVisible = false;
        mNeedsNewHeight = false;
        if (mActivityView != null) {
            mActivityView.setForwardedInsets(Insets.of(0, 0, 0, 0));
        }
    }

    /**
     * Called by {@link BubbleStackView} when the insets for the expanded state should be updated.
     * This should be done post-move and post-animation.
     */
    void updateInsets(WindowInsets insets) {
        if (usingActivityView()) {
            Point displaySize = new Point();
            mActivityView.getContext().getDisplay().getSize(displaySize);
            int[] windowLocation = mActivityView.getLocationOnScreen();
            final int windowBottom = windowLocation[1] + mActivityView.getHeight();
            final int keyboardHeight = insets.getSystemWindowInsetBottom()
                    - insets.getStableInsetBottom();
            final int insetsBottom = Math.max(0,
                    windowBottom + keyboardHeight - displaySize.y);
            mActivityView.setForwardedInsets(Insets.of(0, 0, 0, insetsBottom));
        }
    }

    /**
     * Creates a background with corners rounded based on how the view is configured to display
     */
@@ -448,9 +473,15 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList
            int height = Math.min(desiredHeight, max);
            height = Math.max(height, mMinHeight);
            LayoutParams lp = (LayoutParams) mActivityView.getLayoutParams();
            mNeedsNewHeight =  lp.height != height;
            if (!mKeyboardVisible) {
                // If the keyboard is visible... don't adjust the height because that will cause
                // a configuration change and the keyboard will be lost.
                lp.height = height;
                mBubbleHeight = height;
                mActivityView.setLayoutParams(lp);
                mNeedsNewHeight = false;
            }
        } else {
            mBubbleHeight = mNotifRow != null ? mNotifRow.getIntrinsicHeight() : mMinHeight;
        }
+30 −11
Original line number Diff line number Diff line
@@ -128,6 +128,7 @@ public class BubbleStackView extends FrameLayout {

    private Bubble mExpandedBubble;
    private boolean mIsExpanded;
    private boolean mImeVisible;

    private BubbleTouchHandler mTouchHandler;
    private BubbleController.BubbleExpandListener mExpandListener;
@@ -236,6 +237,28 @@ public class BubbleStackView extends FrameLayout {
        setClipChildren(false);
        setFocusable(true);
        mBubbleContainer.bringToFront();

        setOnApplyWindowInsetsListener((View view, WindowInsets insets) -> {
            final int keyboardHeight = insets.getSystemWindowInsetBottom()
                    - insets.getStableInsetBottom();
            if (!mIsExpanded) {
                return view.onApplyWindowInsets(insets);
            }
            mImeVisible = keyboardHeight != 0;

            float newY = getYPositionForExpandedView();
            if (newY < 0) {
                // TODO: This means our expanded content is too big to fit on screen. Right now
                // we'll let it translate off but we should be clipping it & pushing the header
                // down so that it always remains visible.
            }
            mExpandedViewYAnim.animateToFinalPosition(newY);
            mExpandedAnimationController.updateYPosition(
                    // Update the insets after we're done translating otherwise position
                    // calculation for them won't be correct.
                    () -> mExpandedBubble.expandedView.updateInsets(insets));
            return view.onApplyWindowInsets(insets);
        });
    }

    /**
@@ -646,15 +669,6 @@ public class BubbleStackView extends FrameLayout {
        }
    }

    /**
     * The width of the collapsed stack of bubbles.
     */
    public int getStackWidth() {
        return mBubblePadding * (mBubbleContainer.getChildCount() - 1)
                + mBubbleSize + mBubbleContainer.getPaddingEnd()
                + mBubbleContainer.getPaddingStart();
    }

    private void notifyExpansionChanged(NotificationEntry entry, boolean expanded) {
        if (mExpandListener != null) {
            mExpandListener.onBubbleExpandChanged(expanded, entry != null ? entry.key : null);
@@ -843,8 +857,13 @@ public class BubbleStackView extends FrameLayout {
            // calculation is correct)
            mExpandedBubble.expandedView.updateView();
            final float y = getYPositionForExpandedView();
            if (!mExpandedViewYAnim.isRunning()) {
                // We're not animating so set the value
                mExpandedViewContainer.setTranslationY(y);
            // Then update the view so that ActivityView knows we translated
            } else {
                // We are animating so update the value
                mExpandedViewYAnim.animateToFinalPosition(y);
            }
            mExpandedBubble.expandedView.updateView();
        }

+26 −6
Original line number Diff line number Diff line
@@ -197,6 +197,19 @@ public class ExpandedAnimationController
        mBubbleDraggedOutEnough = false;
    }

    /**
     * Animates the bubbles to {@link #getExpandedY()} position. Used in response to IME showing.
     */
    public void updateYPosition(Runnable after) {
        if (mLayout == null) return;

        for (int i = 0; i < mLayout.getChildCount(); i++) {
            boolean isLast = i == mLayout.getChildCount() - 1;
            mLayout.animateValueForChildAtIndex(DynamicAnimation.TRANSLATION_Y, i,
                    getExpandedY(), isLast ? after : null);
        }
    }

    /**
     * Animates the bubbles, starting at the given index, to the left or right by the given number
     * of bubble widths. Passing zero for numBubbleWidths will animate the bubbles to their normal
@@ -213,18 +226,25 @@ public class ExpandedAnimationController

    /** The Y value of the row of expanded bubbles. */
    public float getExpandedY() {
        boolean showOnTop = mLayout != null
                && BubbleController.showBubblesAtTop(mLayout.getContext());
        final WindowInsets insets = mLayout != null ? mLayout.getRootWindowInsets() : null;
        if (showOnTop && insets != null) {
        if (mLayout == null || mLayout.getRootWindowInsets() == null) {
            return 0;
        }
        final boolean showOnTop = BubbleController.showBubblesAtTop(mLayout.getContext());
        final WindowInsets insets = mLayout.getRootWindowInsets();
        if (showOnTop) {
            return mBubblePaddingPx + Math.max(
                    mStatusBarHeight,
                    insets.getDisplayCutout() != null
                            ? insets.getDisplayCutout().getSafeInsetTop()
                            : 0);
        } else {
            int bottomInset = insets != null ? insets.getSystemWindowInsetBottom() : 0;
            return mDisplaySize.y - mBubbleSizePx - (mPipDismissHeight - bottomInset);
            int keyboardHeight = insets.getSystemWindowInsetBottom()
                    - insets.getStableInsetBottom();
            float bottomInset = keyboardHeight > 0
                    ? keyboardHeight
                    : (mPipDismissHeight - insets.getStableInsetBottom());
            // Stable insets are excluded from display size, so we must subtract it
            return mDisplaySize.y - mBubbleSizePx - mBubblePaddingPx - bottomInset;
        }
    }