Merge "Make the bubbles window NOT_FOCUSABLE when the IME is up, but FOCUSABLE otherwise." into rvc-dev

This commit is contained in:
TreeHugger Robot
2020-06-02 17:49:04 +00:00
committed by Android (Google) Code Review
3 changed files with 75 additions and 9 deletions

View File

@@ -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;
}

View File

@@ -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) {

View File

@@ -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) {