Loading packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java +47 −16 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); }); Loading @@ -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 */ Loading Loading @@ -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; } Loading packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +30 −11 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); }); } /** Loading Loading @@ -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); Loading Loading @@ -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(); } Loading packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java +26 −6 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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; } } Loading Loading
packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java +47 −16 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); }); Loading @@ -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 */ Loading Loading @@ -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; } Loading
packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +30 −11 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); }); } /** Loading Loading @@ -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); Loading Loading @@ -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(); } Loading
packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java +26 −6 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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; } } Loading