Loading packages/CarSystemUI/res/layout/super_notification_shade.xml +0 −8 Original line number Diff line number Diff line Loading @@ -43,14 +43,6 @@ android:visibility="invisible"/> </com.android.systemui.statusbar.BackDropView> <com.android.systemui.statusbar.ScrimView android:id="@+id/scrim_for_bubble" android:layout_width="match_parent" android:layout_height="match_parent" android:importantForAccessibility="no" sysui:ignoreRightInset="true" /> <com.android.systemui.statusbar.ScrimView android:id="@+id/scrim_behind" android:layout_width="match_parent" Loading packages/SystemUI/res/layout/super_notification_shade.xml +0 −8 Original line number Diff line number Diff line Loading @@ -43,14 +43,6 @@ android:visibility="invisible" /> </com.android.systemui.statusbar.BackDropView> <com.android.systemui.statusbar.ScrimView android:id="@+id/scrim_for_bubble" android:layout_width="match_parent" android:layout_height="match_parent" android:importantForAccessibility="no" sysui:ignoreRightInset="true" /> <com.android.systemui.statusbar.ScrimView android:id="@+id/scrim_behind" android:layout_width="match_parent" Loading packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +70 −50 Original line number Diff line number Diff line Loading @@ -29,7 +29,7 @@ import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; import static android.view.View.INVISIBLE; import static android.view.View.VISIBLE; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_CONTROLLER; import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES; Loading @@ -53,7 +53,9 @@ import android.content.Context; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.graphics.PixelFormat; import android.graphics.Rect; import android.os.Binder; import android.os.Handler; import android.os.RemoteException; import android.os.ServiceManager; Loading @@ -66,7 +68,7 @@ import android.util.Pair; import android.util.SparseSetArray; import android.view.Display; import android.view.ViewGroup; import android.widget.FrameLayout; import android.view.WindowManager; import androidx.annotation.IntDef; import androidx.annotation.MainThread; Loading @@ -76,7 +78,6 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.NotificationVisibility; import com.android.systemui.Dumpable; import com.android.systemui.R; import com.android.systemui.bubbles.dagger.BubbleModule; import com.android.systemui.dump.DumpManager; import com.android.systemui.model.SysUiState; Loading @@ -88,6 +89,7 @@ import com.android.systemui.shared.system.WindowManagerWrapper; import com.android.systemui.statusbar.FeatureFlags; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationRemoveInterceptor; import com.android.systemui.statusbar.ScrimView; import com.android.systemui.statusbar.notification.NotificationChannelHelper; import com.android.systemui.statusbar.notification.NotificationEntryListener; import com.android.systemui.statusbar.notification.NotificationEntryManager; Loading @@ -98,6 +100,7 @@ import com.android.systemui.statusbar.notification.collection.notifcollection.No import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider; import com.android.systemui.statusbar.phone.NotificationGroupManager; import com.android.systemui.statusbar.phone.NotificationShadeWindowController; import com.android.systemui.statusbar.phone.ScrimController; import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.ConfigurationController; Loading Loading @@ -145,7 +148,6 @@ public class BubbleController implements ConfigurationController.ConfigurationLi private final NotificationEntryManager mNotificationEntryManager; private final NotifPipeline mNotifPipeline; private final BubbleTaskStackListener mTaskStackListener; private BubbleStateChangeListener mStateChangeListener; private BubbleExpandListener mExpandListener; @Nullable private BubbleStackView.SurfaceSynchronizer mSurfaceSynchronizer; private final NotificationGroupManager mNotificationGroupManager; Loading @@ -153,6 +155,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi private final FloatingContentCoordinator mFloatingContentCoordinator; private BubbleData mBubbleData; private ScrimView mBubbleScrim; @Nullable private BubbleStackView mStackView; private BubbleIconFactory mBubbleIconFactory; Loading @@ -175,11 +178,16 @@ public class BubbleController implements ConfigurationController.ConfigurationLi private final NotificationInterruptStateProvider mNotificationInterruptStateProvider; private IStatusBarService mBarService; private WindowManager mWindowManager; private SysUiState mSysUiState; // Used to post to main UI thread private Handler mHandler = new Handler(); /** LayoutParams used to add the BubbleStackView to the window maanger. */ private WindowManager.LayoutParams mWmLayoutParams; // Used for determining view rect for touch interaction private Rect mTempRect = new Rect(); Loading @@ -194,16 +202,6 @@ 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<>(); /** * Listener to be notified when some states of the bubbles change. */ public interface BubbleStateChangeListener { /** * Called when the stack has bubbles or no longer has bubbles. */ void onHasBubblesChanged(boolean hasBubbles); } /** * Listener to find out about stack expansion / collapse events. */ Loading Loading @@ -393,9 +391,12 @@ public class BubbleController implements ConfigurationController.ConfigurationLi } mSurfaceSynchronizer = synchronizer; mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); mBarService = IStatusBarService.Stub.asInterface( ServiceManager.getService(Context.STATUS_BAR_SERVICE)); mBubbleScrim = new ScrimView(mContext); mSavedBubbleKeysPerUser = new SparseSetArray<>(); mCurrentUserId = mNotifUserManager.getCurrentUserId(); mNotifUserManager.addUserChangedListener( Loading Loading @@ -572,6 +573,15 @@ public class BubbleController implements ConfigurationController.ConfigurationLi }); } /** * Returns the scrim drawn behind the bubble stack. This is managed by {@link ScrimController} * since we want the scrim's appearance and behavior to be identical to that of the notification * shade scrim. */ public ScrimView getScrimForBubble() { return mBubbleScrim; } /** * Sets whether to perform inflation on the same thread as the caller. This method should only * be used in tests, not in production. Loading @@ -592,7 +602,6 @@ public class BubbleController implements ConfigurationController.ConfigurationLi return mBubbleData.getOverflowBubbles(); } /** * BubbleStackView is lazily created by this method the first time a Bubble is added. This * method initializes the stack view and adds it to the StatusBar just above the scrim. Loading @@ -602,11 +611,8 @@ public class BubbleController implements ConfigurationController.ConfigurationLi mStackView = new BubbleStackView( mContext, mBubbleData, mSurfaceSynchronizer, mFloatingContentCoordinator, mSysUiState, mNotificationShadeWindowController); ViewGroup nsv = mNotificationShadeWindowController.getNotificationShadeView(); int bubbleScrimIndex = nsv.indexOfChild(nsv.findViewById(R.id.scrim_for_bubble)); int stackIndex = bubbleScrimIndex + 1; // Show stack above bubble scrim. nsv.addView(mStackView, stackIndex, new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)); mStackView.addView(mBubbleScrim); addToWindowManager(); if (mExpandListener != null) { mStackView.setExpandListener(mExpandListener); } Loading @@ -616,6 +622,45 @@ public class BubbleController implements ConfigurationController.ConfigurationLi } } /** Adds the BubbleStackView to the WindowManager. */ private void addToWindowManager() { mWmLayoutParams = new WindowManager.LayoutParams( // Fill the screen so we can use translation animations to position the bubble // stack. We'll use touchable regions to ignore touches that are not on the bubbles // themselves. ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, // Start not focusable - we'll become focusable when expanded so the ActivityView // can use the IME. WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, PixelFormat.TRANSLUCENT); mWmLayoutParams.setFitInsetsTypes(0); mWmLayoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; mWmLayoutParams.token = new Binder(); mWmLayoutParams.setTitle("Bubbles!"); mWmLayoutParams.packageName = mContext.getPackageName(); mWmLayoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; mWindowManager.addView(mStackView, mWmLayoutParams); } 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. 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. mWmLayoutParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; } mWindowManager.updateViewLayout(mStackView, mWmLayoutParams); } /** * Records the notification key for any active bubbles. These are used to restore active * bubbles when the user returns to the foreground. Loading Loading @@ -686,13 +731,6 @@ public class BubbleController implements ConfigurationController.ConfigurationLi } } /** * Set a listener to be notified when some states of the bubbles change. */ public void setBubbleStateChangeListener(BubbleStateChangeListener listener) { mStateChangeListener = listener; } /** * Set a listener to be notified of bubble expand events. */ Loading @@ -701,7 +739,8 @@ public class BubbleController implements ConfigurationController.ConfigurationLi if (listener != null) { listener.onBubbleExpandChanged(isExpanding, key); } mNotificationShadeWindowController.setBubbleExpanded(isExpanding); updateWmFlags(); }); if (mStackView != null) { mStackView.setExpandListener(mExpandListener); Loading @@ -712,7 +751,8 @@ public class BubbleController implements ConfigurationController.ConfigurationLi * Whether or not there are bubbles present, regardless of them being visible on the * screen (e.g. if on AOD). */ public boolean hasBubbles() { @VisibleForTesting boolean hasBubbles() { if (mStackView == null) { return false; } Loading Loading @@ -1146,8 +1186,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi /** * Lets any listeners know if bubble state has changed. * Updates the visibility of the bubbles based on current state. * Does not un-bubble, just hides or un-hides. Notifies any * {@link BubbleStateChangeListener}s of visibility changes. * Does not un-bubble, just hides or un-hides. * Updates stack description for TalkBack focus. */ public void updateStack() { Loading @@ -1161,28 +1200,9 @@ public class BubbleController implements ConfigurationController.ConfigurationLi mStackView.setVisibility(INVISIBLE); } // Let listeners know if bubble state changed. boolean hadBubbles = mNotificationShadeWindowController.getBubblesShowing(); boolean hasBubblesShowing = hasBubbles() && mStackView.getVisibility() == VISIBLE; mNotificationShadeWindowController.setBubblesShowing(hasBubblesShowing); if (mStateChangeListener != null && hadBubbles != hasBubblesShowing) { mStateChangeListener.onHasBubblesChanged(hasBubblesShowing); } mStackView.updateContentDescription(); } /** * Rect indicating the touchable region for the bubble stack / expanded stack. */ public Rect getTouchableRegion() { if (mStackView == null || mStackView.getVisibility() != VISIBLE) { return null; } mStackView.getBoundsOnScreen(mTempRect); return mTempRect; } /** * The display id of the expanded view, if the stack is expanded and not occluded by the * status bar, otherwise returns {@link Display#INVALID_DISPLAY}. Loading packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +29 −11 Original line number Diff line number Diff line Loading @@ -108,7 +108,8 @@ import java.util.function.Consumer; /** * Renders bubbles in a stack and handles animating expanded and collapsed states. */ public class BubbleStackView extends FrameLayout { public class BubbleStackView extends FrameLayout implements ViewTreeObserver.OnComputeInternalInsetsListener { private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleStackView" : TAG_BUBBLES; /** Animation durations for bubble stack user education views. **/ Loading Loading @@ -647,7 +648,6 @@ public class BubbleStackView extends FrameLayout { private boolean mShowingManage = false; private PhysicsAnimator.SpringConfig mManageSpringConfig = new PhysicsAnimator.SpringConfig( SpringForce.STIFFNESS_MEDIUM, SpringForce.DAMPING_RATIO_LOW_BOUNCY); @SuppressLint("ClickableViewAccessibility") public BubbleStackView(Context context, BubbleData data, @Nullable SurfaceSynchronizer synchronizer, Loading Loading @@ -1052,14 +1052,24 @@ public class BubbleStackView extends FrameLayout { } @Override public void getBoundsOnScreen(Rect outRect, boolean clipToParent) { getBoundsOnScreen(outRect); public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo inoutInfo) { inoutInfo.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION); getTouchableRegion(mTempRect); inoutInfo.touchableRegion.set(mTempRect); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); getViewTreeObserver().addOnComputeInternalInsetsListener(this); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); getViewTreeObserver().removeOnPreDrawListener(mViewUpdater); getViewTreeObserver().removeOnComputeInternalInsetsListener(this); } @Override Loading Loading @@ -1960,8 +1970,16 @@ public class BubbleStackView extends FrameLayout { mAfterFlyoutHidden = null; } @Override public void getBoundsOnScreen(Rect outRect) { /** * Fills the Rect with the touchable region of the bubbles. This will be used by WindowManager * to decide which touch events go to Bubbles. * * Bubbles is below the status bar/notification shade but above application windows. If you're * trying to get touch events from the status bar or another higher-level window layer, you'll * need to re-order TYPE_BUBBLES in WindowManagerPolicy so that we have the opportunity to steal * them. */ public void getTouchableRegion(Rect outRect) { if (mUserEducationView != null && mUserEducationView.getVisibility() == VISIBLE) { // When user education shows then capture all touches outRect.set(0, 0, getWidth(), getHeight()); Loading @@ -1971,12 +1989,12 @@ public class BubbleStackView extends FrameLayout { if (!mIsExpanded) { if (getBubbleCount() > 0) { mBubbleContainer.getChildAt(0).getBoundsOnScreen(outRect); } // Increase the touch target size of the bubble outRect.top -= mBubbleTouchPadding; outRect.left -= mBubbleTouchPadding; outRect.right += mBubbleTouchPadding; outRect.bottom += mBubbleTouchPadding; } } else { mBubbleContainer.getBoundsOnScreen(outRect); } Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowController.java +2 −35 Original line number Diff line number Diff line Loading @@ -273,8 +273,7 @@ public class NotificationShadeWindowController implements Callback, Dumpable, private void applyFocusableFlag(State state) { boolean panelFocusable = state.mNotificationShadeFocusable && state.mPanelExpanded; if (state.mBouncerShowing && (state.mKeyguardOccluded || state.mKeyguardNeedsInput) || ENABLE_REMOTE_INPUT && state.mRemoteInputActive || state.mBubbleExpanded) { || ENABLE_REMOTE_INPUT && state.mRemoteInputActive) { mLpChanged.flags &= ~LayoutParams.FLAG_NOT_FOCUSABLE; mLpChanged.flags &= ~LayoutParams.FLAG_ALT_FOCUSABLE_IM; } else if (state.isKeyguardShowingAndNotOccluded() || panelFocusable) { Loading Loading @@ -320,7 +319,7 @@ public class NotificationShadeWindowController implements Callback, Dumpable, private boolean isExpanded(State state) { return !state.mForceCollapsed && (state.isKeyguardShowingAndNotOccluded() || state.mPanelVisible || state.mKeyguardFadingAway || state.mBouncerShowing || state.mHeadsUpShowing || state.mBubblesShowing || state.mHeadsUpShowing || state.mScrimsVisibility != ScrimController.TRANSPARENT) || state.mBackgroundBlurRadius > 0; } Loading Loading @@ -578,36 +577,6 @@ public class NotificationShadeWindowController implements Callback, Dumpable, apply(mCurrentState); } /** * Sets whether there are bubbles showing on the screen. */ public void setBubblesShowing(boolean bubblesShowing) { mCurrentState.mBubblesShowing = bubblesShowing; apply(mCurrentState); } /** * The bubbles showing state for the status bar. */ public boolean getBubblesShowing() { return mCurrentState.mBubblesShowing; } /** * Sets if there is a bubble being expanded on the screen. */ public void setBubbleExpanded(boolean bubbleExpanded) { mCurrentState.mBubbleExpanded = bubbleExpanded; apply(mCurrentState); } /** * Whether the bubble is shown in expanded state for the status bar. */ public boolean getBubbleExpanded() { return mCurrentState.mBubbleExpanded; } /** * Whether the status bar panel is expanded or not. */ Loading Loading @@ -679,8 +648,6 @@ public class NotificationShadeWindowController implements Callback, Dumpable, boolean mBackdropShowing; boolean mWallpaperSupportsAmbientMode; boolean mNotTouchable; boolean mBubblesShowing; boolean mBubbleExpanded; boolean mForceHasTopUi; /** Loading Loading
packages/CarSystemUI/res/layout/super_notification_shade.xml +0 −8 Original line number Diff line number Diff line Loading @@ -43,14 +43,6 @@ android:visibility="invisible"/> </com.android.systemui.statusbar.BackDropView> <com.android.systemui.statusbar.ScrimView android:id="@+id/scrim_for_bubble" android:layout_width="match_parent" android:layout_height="match_parent" android:importantForAccessibility="no" sysui:ignoreRightInset="true" /> <com.android.systemui.statusbar.ScrimView android:id="@+id/scrim_behind" android:layout_width="match_parent" Loading
packages/SystemUI/res/layout/super_notification_shade.xml +0 −8 Original line number Diff line number Diff line Loading @@ -43,14 +43,6 @@ android:visibility="invisible" /> </com.android.systemui.statusbar.BackDropView> <com.android.systemui.statusbar.ScrimView android:id="@+id/scrim_for_bubble" android:layout_width="match_parent" android:layout_height="match_parent" android:importantForAccessibility="no" sysui:ignoreRightInset="true" /> <com.android.systemui.statusbar.ScrimView android:id="@+id/scrim_behind" android:layout_width="match_parent" Loading
packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +70 −50 Original line number Diff line number Diff line Loading @@ -29,7 +29,7 @@ import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; import static android.view.View.INVISIBLE; import static android.view.View.VISIBLE; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; import static com.android.systemui.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_CONTROLLER; import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_BUBBLES; Loading @@ -53,7 +53,9 @@ import android.content.Context; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.graphics.PixelFormat; import android.graphics.Rect; import android.os.Binder; import android.os.Handler; import android.os.RemoteException; import android.os.ServiceManager; Loading @@ -66,7 +68,7 @@ import android.util.Pair; import android.util.SparseSetArray; import android.view.Display; import android.view.ViewGroup; import android.widget.FrameLayout; import android.view.WindowManager; import androidx.annotation.IntDef; import androidx.annotation.MainThread; Loading @@ -76,7 +78,6 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.NotificationVisibility; import com.android.systemui.Dumpable; import com.android.systemui.R; import com.android.systemui.bubbles.dagger.BubbleModule; import com.android.systemui.dump.DumpManager; import com.android.systemui.model.SysUiState; Loading @@ -88,6 +89,7 @@ import com.android.systemui.shared.system.WindowManagerWrapper; import com.android.systemui.statusbar.FeatureFlags; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationRemoveInterceptor; import com.android.systemui.statusbar.ScrimView; import com.android.systemui.statusbar.notification.NotificationChannelHelper; import com.android.systemui.statusbar.notification.NotificationEntryListener; import com.android.systemui.statusbar.notification.NotificationEntryManager; Loading @@ -98,6 +100,7 @@ import com.android.systemui.statusbar.notification.collection.notifcollection.No import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider; import com.android.systemui.statusbar.phone.NotificationGroupManager; import com.android.systemui.statusbar.phone.NotificationShadeWindowController; import com.android.systemui.statusbar.phone.ScrimController; import com.android.systemui.statusbar.phone.ShadeController; import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.ConfigurationController; Loading Loading @@ -145,7 +148,6 @@ public class BubbleController implements ConfigurationController.ConfigurationLi private final NotificationEntryManager mNotificationEntryManager; private final NotifPipeline mNotifPipeline; private final BubbleTaskStackListener mTaskStackListener; private BubbleStateChangeListener mStateChangeListener; private BubbleExpandListener mExpandListener; @Nullable private BubbleStackView.SurfaceSynchronizer mSurfaceSynchronizer; private final NotificationGroupManager mNotificationGroupManager; Loading @@ -153,6 +155,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi private final FloatingContentCoordinator mFloatingContentCoordinator; private BubbleData mBubbleData; private ScrimView mBubbleScrim; @Nullable private BubbleStackView mStackView; private BubbleIconFactory mBubbleIconFactory; Loading @@ -175,11 +178,16 @@ public class BubbleController implements ConfigurationController.ConfigurationLi private final NotificationInterruptStateProvider mNotificationInterruptStateProvider; private IStatusBarService mBarService; private WindowManager mWindowManager; private SysUiState mSysUiState; // Used to post to main UI thread private Handler mHandler = new Handler(); /** LayoutParams used to add the BubbleStackView to the window maanger. */ private WindowManager.LayoutParams mWmLayoutParams; // Used for determining view rect for touch interaction private Rect mTempRect = new Rect(); Loading @@ -194,16 +202,6 @@ 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<>(); /** * Listener to be notified when some states of the bubbles change. */ public interface BubbleStateChangeListener { /** * Called when the stack has bubbles or no longer has bubbles. */ void onHasBubblesChanged(boolean hasBubbles); } /** * Listener to find out about stack expansion / collapse events. */ Loading Loading @@ -393,9 +391,12 @@ public class BubbleController implements ConfigurationController.ConfigurationLi } mSurfaceSynchronizer = synchronizer; mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); mBarService = IStatusBarService.Stub.asInterface( ServiceManager.getService(Context.STATUS_BAR_SERVICE)); mBubbleScrim = new ScrimView(mContext); mSavedBubbleKeysPerUser = new SparseSetArray<>(); mCurrentUserId = mNotifUserManager.getCurrentUserId(); mNotifUserManager.addUserChangedListener( Loading Loading @@ -572,6 +573,15 @@ public class BubbleController implements ConfigurationController.ConfigurationLi }); } /** * Returns the scrim drawn behind the bubble stack. This is managed by {@link ScrimController} * since we want the scrim's appearance and behavior to be identical to that of the notification * shade scrim. */ public ScrimView getScrimForBubble() { return mBubbleScrim; } /** * Sets whether to perform inflation on the same thread as the caller. This method should only * be used in tests, not in production. Loading @@ -592,7 +602,6 @@ public class BubbleController implements ConfigurationController.ConfigurationLi return mBubbleData.getOverflowBubbles(); } /** * BubbleStackView is lazily created by this method the first time a Bubble is added. This * method initializes the stack view and adds it to the StatusBar just above the scrim. Loading @@ -602,11 +611,8 @@ public class BubbleController implements ConfigurationController.ConfigurationLi mStackView = new BubbleStackView( mContext, mBubbleData, mSurfaceSynchronizer, mFloatingContentCoordinator, mSysUiState, mNotificationShadeWindowController); ViewGroup nsv = mNotificationShadeWindowController.getNotificationShadeView(); int bubbleScrimIndex = nsv.indexOfChild(nsv.findViewById(R.id.scrim_for_bubble)); int stackIndex = bubbleScrimIndex + 1; // Show stack above bubble scrim. nsv.addView(mStackView, stackIndex, new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)); mStackView.addView(mBubbleScrim); addToWindowManager(); if (mExpandListener != null) { mStackView.setExpandListener(mExpandListener); } Loading @@ -616,6 +622,45 @@ public class BubbleController implements ConfigurationController.ConfigurationLi } } /** Adds the BubbleStackView to the WindowManager. */ private void addToWindowManager() { mWmLayoutParams = new WindowManager.LayoutParams( // Fill the screen so we can use translation animations to position the bubble // stack. We'll use touchable regions to ignore touches that are not on the bubbles // themselves. ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, // Start not focusable - we'll become focusable when expanded so the ActivityView // can use the IME. WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, PixelFormat.TRANSLUCENT); mWmLayoutParams.setFitInsetsTypes(0); mWmLayoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; mWmLayoutParams.token = new Binder(); mWmLayoutParams.setTitle("Bubbles!"); mWmLayoutParams.packageName = mContext.getPackageName(); mWmLayoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; mWindowManager.addView(mStackView, mWmLayoutParams); } 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. 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. mWmLayoutParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; } mWindowManager.updateViewLayout(mStackView, mWmLayoutParams); } /** * Records the notification key for any active bubbles. These are used to restore active * bubbles when the user returns to the foreground. Loading Loading @@ -686,13 +731,6 @@ public class BubbleController implements ConfigurationController.ConfigurationLi } } /** * Set a listener to be notified when some states of the bubbles change. */ public void setBubbleStateChangeListener(BubbleStateChangeListener listener) { mStateChangeListener = listener; } /** * Set a listener to be notified of bubble expand events. */ Loading @@ -701,7 +739,8 @@ public class BubbleController implements ConfigurationController.ConfigurationLi if (listener != null) { listener.onBubbleExpandChanged(isExpanding, key); } mNotificationShadeWindowController.setBubbleExpanded(isExpanding); updateWmFlags(); }); if (mStackView != null) { mStackView.setExpandListener(mExpandListener); Loading @@ -712,7 +751,8 @@ public class BubbleController implements ConfigurationController.ConfigurationLi * Whether or not there are bubbles present, regardless of them being visible on the * screen (e.g. if on AOD). */ public boolean hasBubbles() { @VisibleForTesting boolean hasBubbles() { if (mStackView == null) { return false; } Loading Loading @@ -1146,8 +1186,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi /** * Lets any listeners know if bubble state has changed. * Updates the visibility of the bubbles based on current state. * Does not un-bubble, just hides or un-hides. Notifies any * {@link BubbleStateChangeListener}s of visibility changes. * Does not un-bubble, just hides or un-hides. * Updates stack description for TalkBack focus. */ public void updateStack() { Loading @@ -1161,28 +1200,9 @@ public class BubbleController implements ConfigurationController.ConfigurationLi mStackView.setVisibility(INVISIBLE); } // Let listeners know if bubble state changed. boolean hadBubbles = mNotificationShadeWindowController.getBubblesShowing(); boolean hasBubblesShowing = hasBubbles() && mStackView.getVisibility() == VISIBLE; mNotificationShadeWindowController.setBubblesShowing(hasBubblesShowing); if (mStateChangeListener != null && hadBubbles != hasBubblesShowing) { mStateChangeListener.onHasBubblesChanged(hasBubblesShowing); } mStackView.updateContentDescription(); } /** * Rect indicating the touchable region for the bubble stack / expanded stack. */ public Rect getTouchableRegion() { if (mStackView == null || mStackView.getVisibility() != VISIBLE) { return null; } mStackView.getBoundsOnScreen(mTempRect); return mTempRect; } /** * The display id of the expanded view, if the stack is expanded and not occluded by the * status bar, otherwise returns {@link Display#INVALID_DISPLAY}. Loading
packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +29 −11 Original line number Diff line number Diff line Loading @@ -108,7 +108,8 @@ import java.util.function.Consumer; /** * Renders bubbles in a stack and handles animating expanded and collapsed states. */ public class BubbleStackView extends FrameLayout { public class BubbleStackView extends FrameLayout implements ViewTreeObserver.OnComputeInternalInsetsListener { private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleStackView" : TAG_BUBBLES; /** Animation durations for bubble stack user education views. **/ Loading Loading @@ -647,7 +648,6 @@ public class BubbleStackView extends FrameLayout { private boolean mShowingManage = false; private PhysicsAnimator.SpringConfig mManageSpringConfig = new PhysicsAnimator.SpringConfig( SpringForce.STIFFNESS_MEDIUM, SpringForce.DAMPING_RATIO_LOW_BOUNCY); @SuppressLint("ClickableViewAccessibility") public BubbleStackView(Context context, BubbleData data, @Nullable SurfaceSynchronizer synchronizer, Loading Loading @@ -1052,14 +1052,24 @@ public class BubbleStackView extends FrameLayout { } @Override public void getBoundsOnScreen(Rect outRect, boolean clipToParent) { getBoundsOnScreen(outRect); public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo inoutInfo) { inoutInfo.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION); getTouchableRegion(mTempRect); inoutInfo.touchableRegion.set(mTempRect); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); getViewTreeObserver().addOnComputeInternalInsetsListener(this); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); getViewTreeObserver().removeOnPreDrawListener(mViewUpdater); getViewTreeObserver().removeOnComputeInternalInsetsListener(this); } @Override Loading Loading @@ -1960,8 +1970,16 @@ public class BubbleStackView extends FrameLayout { mAfterFlyoutHidden = null; } @Override public void getBoundsOnScreen(Rect outRect) { /** * Fills the Rect with the touchable region of the bubbles. This will be used by WindowManager * to decide which touch events go to Bubbles. * * Bubbles is below the status bar/notification shade but above application windows. If you're * trying to get touch events from the status bar or another higher-level window layer, you'll * need to re-order TYPE_BUBBLES in WindowManagerPolicy so that we have the opportunity to steal * them. */ public void getTouchableRegion(Rect outRect) { if (mUserEducationView != null && mUserEducationView.getVisibility() == VISIBLE) { // When user education shows then capture all touches outRect.set(0, 0, getWidth(), getHeight()); Loading @@ -1971,12 +1989,12 @@ public class BubbleStackView extends FrameLayout { if (!mIsExpanded) { if (getBubbleCount() > 0) { mBubbleContainer.getChildAt(0).getBoundsOnScreen(outRect); } // Increase the touch target size of the bubble outRect.top -= mBubbleTouchPadding; outRect.left -= mBubbleTouchPadding; outRect.right += mBubbleTouchPadding; outRect.bottom += mBubbleTouchPadding; } } else { mBubbleContainer.getBoundsOnScreen(outRect); } Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowController.java +2 −35 Original line number Diff line number Diff line Loading @@ -273,8 +273,7 @@ public class NotificationShadeWindowController implements Callback, Dumpable, private void applyFocusableFlag(State state) { boolean panelFocusable = state.mNotificationShadeFocusable && state.mPanelExpanded; if (state.mBouncerShowing && (state.mKeyguardOccluded || state.mKeyguardNeedsInput) || ENABLE_REMOTE_INPUT && state.mRemoteInputActive || state.mBubbleExpanded) { || ENABLE_REMOTE_INPUT && state.mRemoteInputActive) { mLpChanged.flags &= ~LayoutParams.FLAG_NOT_FOCUSABLE; mLpChanged.flags &= ~LayoutParams.FLAG_ALT_FOCUSABLE_IM; } else if (state.isKeyguardShowingAndNotOccluded() || panelFocusable) { Loading Loading @@ -320,7 +319,7 @@ public class NotificationShadeWindowController implements Callback, Dumpable, private boolean isExpanded(State state) { return !state.mForceCollapsed && (state.isKeyguardShowingAndNotOccluded() || state.mPanelVisible || state.mKeyguardFadingAway || state.mBouncerShowing || state.mHeadsUpShowing || state.mBubblesShowing || state.mHeadsUpShowing || state.mScrimsVisibility != ScrimController.TRANSPARENT) || state.mBackgroundBlurRadius > 0; } Loading Loading @@ -578,36 +577,6 @@ public class NotificationShadeWindowController implements Callback, Dumpable, apply(mCurrentState); } /** * Sets whether there are bubbles showing on the screen. */ public void setBubblesShowing(boolean bubblesShowing) { mCurrentState.mBubblesShowing = bubblesShowing; apply(mCurrentState); } /** * The bubbles showing state for the status bar. */ public boolean getBubblesShowing() { return mCurrentState.mBubblesShowing; } /** * Sets if there is a bubble being expanded on the screen. */ public void setBubbleExpanded(boolean bubbleExpanded) { mCurrentState.mBubbleExpanded = bubbleExpanded; apply(mCurrentState); } /** * Whether the bubble is shown in expanded state for the status bar. */ public boolean getBubbleExpanded() { return mCurrentState.mBubbleExpanded; } /** * Whether the status bar panel is expanded or not. */ Loading Loading @@ -679,8 +648,6 @@ public class NotificationShadeWindowController implements Callback, Dumpable, boolean mBackdropShowing; boolean mWallpaperSupportsAmbientMode; boolean mNotTouchable; boolean mBubblesShowing; boolean mBubbleExpanded; boolean mForceHasTopUi; /** Loading