diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java index e7764ea1a21e6..95b80df7fcbd2 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java @@ -636,10 +636,16 @@ public class BubbleController { } } - /** For the overflow to be focusable & receive key events the flags must be update. **/ - void updateWindowFlagsForOverflow(boolean showingOverflow) { + /** + * In some situations bubble's should be able to receive key events for back: + * - when the bubble overflow is showing + * - when the user education for the stack is showing. + * + * @param interceptBack whether back should be intercepted or not. + */ + void updateWindowFlagsForBackpress(boolean interceptBack) { if (mStackView != null && mAddedToWindowManager) { - mWmLayoutParams.flags = showingOverflow + mWmLayoutParams.flags = interceptBack ? 0 : WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java index 252b588ec63f9..4ac7dcf3d23a1 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java @@ -228,7 +228,7 @@ public class BubbleExpandedView extends LinearLayout { @Override public void onBackPressedOnTaskRoot(int taskId) { if (mTaskId == taskId && mStackView.isExpanded()) { - mController.collapseStack(); + mStackView.onBackPressed(); } } }; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java index ede42285d9cdb..5e9d97f23c577 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java @@ -142,7 +142,7 @@ public class BubbleOverflowContainerView extends LinearLayout { super.onAttachedToWindow(); if (mController != null) { // For the overflow to get key events (e.g. back press) we need to adjust the flags - mController.updateWindowFlagsForOverflow(true); + mController.updateWindowFlagsForBackpress(true); } setOnKeyListener(mKeyListener); } @@ -151,7 +151,7 @@ public class BubbleOverflowContainerView extends LinearLayout { protected void onDetachedFromWindow() { super.onDetachedFromWindow(); if (mController != null) { - mController.updateWindowFlagsForOverflow(false); + mController.updateWindowFlagsForBackpress(false); } setOnKeyListener(null); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java index 9e108ea911c6b..3d2505ef76999 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java @@ -927,8 +927,10 @@ public class BubbleStackView extends FrameLayout setOnClickListener(view -> { if (mShowingManage) { showManageMenu(false /* show */); + } else if (mManageEduView != null && mManageEduView.getVisibility() == VISIBLE) { + mManageEduView.hide(); } else if (mStackEduView != null && mStackEduView.getVisibility() == VISIBLE) { - mStackEduView.hide(false); + mStackEduView.hide(false /* isExpanding */); } else if (mBubbleData.isExpanded()) { mBubbleData.setExpanded(false); } @@ -1158,7 +1160,7 @@ public class BubbleStackView extends FrameLayout return false; } if (mStackEduView == null) { - mStackEduView = new StackEducationView(mContext, mPositioner); + mStackEduView = new StackEducationView(mContext, mPositioner, mBubbleController); addView(mStackEduView); } mBubbleContainer.bringToFront(); @@ -1169,7 +1171,7 @@ public class BubbleStackView extends FrameLayout private void updateUserEdu() { if (mStackEduView != null && mStackEduView.getVisibility() == VISIBLE) { removeView(mStackEduView); - mStackEduView = new StackEducationView(mContext, mPositioner); + mStackEduView = new StackEducationView(mContext, mPositioner, mBubbleController); addView(mStackEduView); mBubbleContainer.bringToFront(); // Stack appears on top of the stack education mStackEduView.show(mPositioner.getDefaultStartPosition()); @@ -1732,6 +1734,21 @@ public class BubbleStackView extends FrameLayout notifyExpansionChanged(mExpandedBubble, mIsExpanded); } + /** + * Called when back press occurs while bubbles are expanded. + */ + public void onBackPressed() { + if (mIsExpanded) { + if (mShowingManage) { + showManageMenu(false); + } else if (mManageEduView != null && mManageEduView.getVisibility() == VISIBLE) { + mManageEduView.hide(); + } else { + setExpanded(false); + } + } + } + void setBubbleVisibility(Bubble b, boolean visible) { if (b.getIconView() != null) { b.getIconView().setVisibility(visible ? VISIBLE : GONE); @@ -1957,6 +1974,9 @@ public class BubbleStackView extends FrameLayout private void animateCollapse() { cancelDelayedExpandCollapseSwitchAnimations(); + if (mManageEduView != null && mManageEduView.getVisibility() == VISIBLE) { + mManageEduView.hide(); + } // Hide the menu if it's visible. showManageMenu(false); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/StackEducationView.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/StackEducationView.kt index cb660004062dc..f6a90b7a76cda 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/StackEducationView.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/StackEducationView.kt @@ -18,8 +18,10 @@ package com.android.wm.shell.bubbles import android.content.Context import android.graphics.Color import android.graphics.PointF +import android.view.KeyEvent import android.view.LayoutInflater import android.view.View +import android.view.View.OnKeyListener import android.view.ViewGroup import android.widget.LinearLayout import android.widget.TextView @@ -31,7 +33,11 @@ import com.android.wm.shell.animation.Interpolators * User education view to highlight the collapsed stack of bubbles. * Shown only the first time a user taps the stack. */ -class StackEducationView constructor(context: Context, positioner: BubblePositioner) +class StackEducationView constructor( + context: Context, + positioner: BubblePositioner, + controller: BubbleController +) : LinearLayout(context) { private val TAG = if (BubbleDebugConfig.TAG_WITH_CLASS_NAME) "BubbleStackEducationView" @@ -41,6 +47,7 @@ class StackEducationView constructor(context: Context, positioner: BubblePositio private val ANIMATE_DURATION_SHORT: Long = 40 private val positioner: BubblePositioner = positioner + private val controller: BubbleController = controller private val view by lazy { findViewById(R.id.stack_education_layout) } private val titleTextView by lazy { findViewById(R.id.stack_education_title) } @@ -71,6 +78,28 @@ class StackEducationView constructor(context: Context, positioner: BubblePositio setTextColor() } + override fun onAttachedToWindow() { + super.onAttachedToWindow() + setFocusableInTouchMode(true) + setOnKeyListener(object : OnKeyListener { + override fun onKey(v: View?, keyCode: Int, event: KeyEvent): Boolean { + // if the event is a key down event on the enter button + if (event.action == KeyEvent.ACTION_UP && + keyCode == KeyEvent.KEYCODE_BACK && !isHiding) { + hide(false) + return true + } + return false + } + }) + } + + override fun onDetachedFromWindow() { + super.onDetachedFromWindow() + setOnKeyListener(null) + controller.updateWindowFlagsForBackpress(false /* interceptBack */) + } + private fun setTextColor() { val ta = mContext.obtainStyledAttributes(intArrayOf(android.R.attr.colorAccent, android.R.attr.textColorPrimaryInverse)) @@ -98,6 +127,7 @@ class StackEducationView constructor(context: Context, positioner: BubblePositio fun show(stackPosition: PointF): Boolean { if (visibility == VISIBLE) return false + controller.updateWindowFlagsForBackpress(true /* interceptBack */) layoutParams.width = if (positioner.isLargeScreen) context.resources.getDimensionPixelSize( R.dimen.bubbles_user_education_width_large_screen) @@ -106,6 +136,7 @@ class StackEducationView constructor(context: Context, positioner: BubblePositio setAlpha(0f) setVisibility(View.VISIBLE) post { + requestFocus() with(view) { if (resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_LTR) { setPadding(positioner.bubbleSize + paddingRight, paddingTop, paddingRight, @@ -134,6 +165,7 @@ class StackEducationView constructor(context: Context, positioner: BubblePositio fun hide(isExpanding: Boolean) { if (visibility != VISIBLE || isHiding) return + controller.updateWindowFlagsForBackpress(false /* interceptBack */) animate() .alpha(0f) .setDuration(if (isExpanding) ANIMATE_DURATION_SHORT else ANIMATE_DURATION)