Merge "Make the bubbles window NOT_FOCUSABLE when the IME is up, but FOCUSABLE otherwise." into rvc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
cb61f9da9d
@@ -211,6 +211,13 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
|
||||
// TODO (b/145659174): allow for multiple callbacks to support the "shadow" new notif pipeline
|
||||
private final List<NotifCallback> mCallbacks = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Whether the IME is visible, as reported by the BubbleStackView. If it is, we'll make the
|
||||
* Bubbles window NOT_FOCUSABLE so that touches on the Bubbles UI doesn't steal focus from the
|
||||
* ActivityView and hide the IME.
|
||||
*/
|
||||
private boolean mImeVisible = false;
|
||||
|
||||
/**
|
||||
* Listener to find out about stack expansion / collapse events.
|
||||
*/
|
||||
@@ -598,7 +605,8 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
|
||||
if (mStackView == null) {
|
||||
mStackView = new BubbleStackView(
|
||||
mContext, mBubbleData, mSurfaceSynchronizer, mFloatingContentCoordinator,
|
||||
mSysUiState, mNotificationShadeWindowController, this::onAllBubblesAnimatedOut);
|
||||
mSysUiState, mNotificationShadeWindowController, this::onAllBubblesAnimatedOut,
|
||||
this::onImeVisibilityChanged);
|
||||
mStackView.addView(mBubbleScrim);
|
||||
if (mExpandListener != null) {
|
||||
mStackView.setExpandListener(mExpandListener);
|
||||
@@ -649,6 +657,11 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
|
||||
}
|
||||
}
|
||||
|
||||
private void onImeVisibilityChanged(boolean imeVisible) {
|
||||
mImeVisible = imeVisible;
|
||||
updateWmFlags();
|
||||
}
|
||||
|
||||
/** Removes the BubbleStackView from the WindowManager if it's there. */
|
||||
private void removeFromWindowManagerMaybe() {
|
||||
if (!mAddedToWindowManager) {
|
||||
@@ -676,13 +689,14 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
|
||||
* the new params if the stack has been added.
|
||||
*/
|
||||
private void updateWmFlags() {
|
||||
if (isStackExpanded()) {
|
||||
// If we're expanded, we want to be focusable so that the ActivityView can receive focus
|
||||
// and show the IME.
|
||||
if (isStackExpanded() && !mImeVisible) {
|
||||
// If we're expanded, and the IME isn't visible, we want to be focusable. This ensures
|
||||
// that any taps within Bubbles (including on the ActivityView) results in Bubbles
|
||||
// receiving focus and clearing it from any other windows that might have it.
|
||||
mWmLayoutParams.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
|
||||
} else {
|
||||
// If we're collapsed, we don't want to be able to receive focus. Doing so would
|
||||
// preclude applications from using the IME since we are always above them.
|
||||
// If we're collapsed, we don't want to be focusable since tapping on the stack would
|
||||
// steal focus from apps. We also don't want to be focusable if the IME is visible,
|
||||
mWmLayoutParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES;
|
||||
import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.ActivityOptions;
|
||||
import android.app.ActivityTaskManager;
|
||||
import android.app.ActivityView;
|
||||
@@ -239,6 +240,7 @@ public class BubbleExpandedView extends LinearLayout {
|
||||
mPointerMargin = res.getDimensionPixelSize(R.dimen.bubble_pointer_margin);
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
@@ -290,6 +292,30 @@ public class BubbleExpandedView extends LinearLayout {
|
||||
}
|
||||
return view.onApplyWindowInsets(insets);
|
||||
});
|
||||
|
||||
final int expandedViewPadding =
|
||||
res.getDimensionPixelSize(R.dimen.bubble_expanded_view_padding);
|
||||
|
||||
setPadding(
|
||||
expandedViewPadding, expandedViewPadding, expandedViewPadding, expandedViewPadding);
|
||||
setOnTouchListener((view, motionEvent) -> {
|
||||
if (!usingActivityView()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final Rect avBounds = new Rect();
|
||||
mActivityView.getBoundsOnScreen(avBounds);
|
||||
|
||||
// Consume and ignore events on the expanded view padding that are within the
|
||||
// ActivityView's vertical bounds. These events are part of a back gesture, and so they
|
||||
// should not collapse the stack (which all other touches on areas around the AV would
|
||||
// do).
|
||||
if (motionEvent.getRawY() >= avBounds.top && motionEvent.getRawY() <= avBounds.bottom) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
private String getBubbleKey() {
|
||||
@@ -323,9 +349,19 @@ public class BubbleExpandedView extends LinearLayout {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides the IME if it's showing. This is currently done by dispatching a back press to the AV.
|
||||
*/
|
||||
void hideImeIfVisible() {
|
||||
if (mKeyboardVisible) {
|
||||
performBackPressIfNeeded();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
hideImeIfVisible();
|
||||
mKeyboardVisible = false;
|
||||
mNeedsNewHeight = false;
|
||||
if (mActivityView != null) {
|
||||
|
||||
@@ -341,6 +341,12 @@ public class BubbleStackView extends FrameLayout
|
||||
|
||||
private final NotificationShadeWindowController mNotificationShadeWindowController;
|
||||
|
||||
/**
|
||||
* Callback to run when the IME visibility changes - BubbleController uses this to update the
|
||||
* Bubbles window focusability flags with the WindowManager.
|
||||
*/
|
||||
public final Consumer<Boolean> mOnImeVisibilityChanged;
|
||||
|
||||
/**
|
||||
* The currently magnetized object, which is being dragged and will be attracted to the magnetic
|
||||
* dismiss target.
|
||||
@@ -667,7 +673,8 @@ public class BubbleStackView extends FrameLayout
|
||||
FloatingContentCoordinator floatingContentCoordinator,
|
||||
SysUiState sysUiState,
|
||||
NotificationShadeWindowController notificationShadeWindowController,
|
||||
Runnable allBubblesAnimatedOutAction) {
|
||||
Runnable allBubblesAnimatedOutAction,
|
||||
Consumer<Boolean> onImeVisibilityChanged) {
|
||||
super(context);
|
||||
|
||||
mBubbleData = data;
|
||||
@@ -724,8 +731,6 @@ public class BubbleStackView extends FrameLayout
|
||||
|
||||
mExpandedViewContainer = new FrameLayout(context);
|
||||
mExpandedViewContainer.setElevation(elevation);
|
||||
mExpandedViewContainer.setPadding(mExpandedViewPadding, mExpandedViewPadding,
|
||||
mExpandedViewPadding, mExpandedViewPadding);
|
||||
mExpandedViewContainer.setClipChildren(false);
|
||||
addView(mExpandedViewContainer);
|
||||
|
||||
@@ -793,7 +798,11 @@ public class BubbleStackView extends FrameLayout
|
||||
|
||||
setUpOverflow();
|
||||
|
||||
mOnImeVisibilityChanged = onImeVisibilityChanged;
|
||||
|
||||
setOnApplyWindowInsetsListener((View view, WindowInsets insets) -> {
|
||||
onImeVisibilityChanged.accept(insets.getInsets(WindowInsets.Type.ime()).bottom > 0);
|
||||
|
||||
if (!mIsExpanded || mIsExpansionAnimating) {
|
||||
return view.onApplyWindowInsets(insets);
|
||||
}
|
||||
@@ -2126,6 +2135,13 @@ public class BubbleStackView extends FrameLayout
|
||||
if (DEBUG_BUBBLE_STACK_VIEW) {
|
||||
Log.d(TAG, "updateExpandedBubble()");
|
||||
}
|
||||
|
||||
if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) {
|
||||
// Hide the currently expanded bubble's IME if it's visible before switching to a new
|
||||
// bubble.
|
||||
mExpandedBubble.getExpandedView().hideImeIfVisible();
|
||||
}
|
||||
|
||||
mExpandedViewContainer.removeAllViews();
|
||||
if (mIsExpanded && mExpandedBubble != null
|
||||
&& mExpandedBubble.getExpandedView() != null) {
|
||||
|
||||
Reference in New Issue
Block a user