Move Bubbles into a hw-accelerated TYPE_APPLICATION_OVERLAY WindowManager layer.
This addresses several issues caused by Bubbles living in the status bar window and makes it easier to address several more open bugs. Test: atest SystemUITests Test: manually, a lot Fixes: 130579263 Fixes: 142075351 Fixes: 151086286 Fixes: 149473357 Bug: 150906076 Change-Id: I61594931cce55cba78e6cb1fcec440e4fec32bb0
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -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(
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -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);
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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() {
|
||||
@@ -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}.
|
||||
|
||||
@@ -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. **/
|
||||
@@ -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,
|
||||
@@ -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
|
||||
@@ -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());
|
||||
@@ -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;
|
||||
}
|
||||
// Increase the touch target size of the bubble
|
||||
outRect.top -= mBubbleTouchPadding;
|
||||
outRect.left -= mBubbleTouchPadding;
|
||||
outRect.right += mBubbleTouchPadding;
|
||||
outRect.bottom += mBubbleTouchPadding;
|
||||
} else {
|
||||
mBubbleContainer.getBoundsOnScreen(outRect);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -679,8 +648,6 @@ public class NotificationShadeWindowController implements Callback, Dumpable,
|
||||
boolean mBackdropShowing;
|
||||
boolean mWallpaperSupportsAmbientMode;
|
||||
boolean mNotTouchable;
|
||||
boolean mBubblesShowing;
|
||||
boolean mBubbleExpanded;
|
||||
boolean mForceHasTopUi;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1144,7 +1144,7 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
|
||||
ScrimView scrimBehind = mNotificationShadeWindowView.findViewById(R.id.scrim_behind);
|
||||
ScrimView scrimInFront = mNotificationShadeWindowView.findViewById(R.id.scrim_in_front);
|
||||
ScrimView scrimForBubble = mNotificationShadeWindowView.findViewById(R.id.scrim_for_bubble);
|
||||
ScrimView scrimForBubble = mBubbleController.getScrimForBubble();
|
||||
|
||||
mScrimController.setScrimVisibleListener(scrimsVisible -> {
|
||||
mNotificationShadeWindowController.setScrimsVisibility(scrimsVisible);
|
||||
|
||||
@@ -32,7 +32,6 @@ import android.view.WindowInsets;
|
||||
import com.android.systemui.Dumpable;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.ScreenDecorations;
|
||||
import com.android.systemui.bubbles.BubbleController;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
|
||||
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
|
||||
@@ -45,8 +44,8 @@ import javax.inject.Singleton;
|
||||
|
||||
/**
|
||||
* Manages what parts of the status bar are touchable. Clients are primarily UI that display in the
|
||||
* status bar even though the UI doesn't look like part of the status bar. Currently this
|
||||
* includes HeadsUpNotifications and Bubbles.
|
||||
* status bar even though the UI doesn't look like part of the status bar. Currently this consists
|
||||
* of HeadsUpNotifications.
|
||||
*/
|
||||
@Singleton
|
||||
public final class StatusBarTouchableRegionManager implements Dumpable {
|
||||
@@ -55,7 +54,6 @@ public final class StatusBarTouchableRegionManager implements Dumpable {
|
||||
private final Context mContext;
|
||||
private final HeadsUpManagerPhone mHeadsUpManager;
|
||||
private final NotificationShadeWindowController mNotificationShadeWindowController;
|
||||
private final BubbleController mBubbleController;
|
||||
|
||||
private boolean mIsStatusBarExpanded = false;
|
||||
private boolean mShouldAdjustInsets = false;
|
||||
@@ -73,8 +71,7 @@ public final class StatusBarTouchableRegionManager implements Dumpable {
|
||||
Context context,
|
||||
NotificationShadeWindowController notificationShadeWindowController,
|
||||
ConfigurationController configurationController,
|
||||
HeadsUpManagerPhone headsUpManager,
|
||||
BubbleController bubbleController
|
||||
HeadsUpManagerPhone headsUpManager
|
||||
) {
|
||||
mContext = context;
|
||||
initResources();
|
||||
@@ -117,11 +114,6 @@ public final class StatusBarTouchableRegionManager implements Dumpable {
|
||||
mNotificationShadeWindowController.setForcePluginOpenListener((forceOpen) -> {
|
||||
updateTouchableRegion();
|
||||
});
|
||||
|
||||
mBubbleController = bubbleController;
|
||||
mBubbleController.setBubbleStateChangeListener((hasBubbles) -> {
|
||||
updateTouchableRegion();
|
||||
});
|
||||
}
|
||||
|
||||
protected void setup(
|
||||
@@ -172,12 +164,6 @@ public final class StatusBarTouchableRegionManager implements Dumpable {
|
||||
mStatusBarHeight);
|
||||
updateRegionForNotch(mTouchableRegion);
|
||||
}
|
||||
|
||||
// Update touchable region for bubbles
|
||||
Rect bubbleRect = mBubbleController.getTouchableRegion();
|
||||
if (bubbleRect != null) {
|
||||
mTouchableRegion.union(bubbleRect);
|
||||
}
|
||||
return mTouchableRegion;
|
||||
}
|
||||
|
||||
@@ -198,7 +184,6 @@ public final class StatusBarTouchableRegionManager implements Dumpable {
|
||||
&& (mNotificationShadeWindowView.getRootWindowInsets().getDisplayCutout() != null);
|
||||
boolean shouldObserve = mHeadsUpManager.hasPinnedHeadsUp()
|
||||
|| mHeadsUpManager.isHeadsUpGoingAway()
|
||||
|| mBubbleController.hasBubbles()
|
||||
|| mForceCollapsedUntilLayout
|
||||
|| hasCutoutInset
|
||||
|| mNotificationShadeWindowController.getForcePluginOpen();
|
||||
@@ -266,7 +251,7 @@ public final class StatusBarTouchableRegionManager implements Dumpable {
|
||||
}
|
||||
|
||||
// Update touch insets to include any area needed for touching features that live in
|
||||
// the status bar (ie: heads up notifications or bubbles)
|
||||
// the status bar (ie: heads up notifications)
|
||||
info.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
|
||||
info.touchableRegion.set(calculateTouchableRegion());
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@ import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
@@ -161,8 +160,6 @@ public class BubbleControllerTest extends SysuiTestCase {
|
||||
private ExpandableNotificationRow mRow3;
|
||||
private ExpandableNotificationRow mNonBubbleNotifRow;
|
||||
|
||||
@Mock
|
||||
private BubbleController.BubbleStateChangeListener mBubbleStateChangeListener;
|
||||
@Mock
|
||||
private BubbleController.BubbleExpandListener mBubbleExpandListener;
|
||||
@Mock
|
||||
@@ -280,7 +277,6 @@ public class BubbleControllerTest extends SysuiTestCase {
|
||||
mFloatingContentCoordinator,
|
||||
mSysUiState,
|
||||
mock(INotificationManager.class));
|
||||
mBubbleController.setBubbleStateChangeListener(mBubbleStateChangeListener);
|
||||
mBubbleController.setExpandListener(mBubbleExpandListener);
|
||||
|
||||
// Get a reference to the BubbleController's entry listener
|
||||
@@ -298,7 +294,6 @@ public class BubbleControllerTest extends SysuiTestCase {
|
||||
mBubbleController.updateBubble(mRow.getEntry());
|
||||
assertTrue(mBubbleController.hasBubbles());
|
||||
|
||||
verify(mBubbleStateChangeListener).onHasBubblesChanged(true);
|
||||
assertFalse(mSysUiStateBubblesExpanded);
|
||||
}
|
||||
|
||||
@@ -316,14 +311,11 @@ public class BubbleControllerTest extends SysuiTestCase {
|
||||
assertNotNull(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()));
|
||||
assertTrue(mBubbleController.hasBubbles());
|
||||
verify(mNotificationEntryManager).updateNotifications(any());
|
||||
verify(mBubbleStateChangeListener).onHasBubblesChanged(true);
|
||||
|
||||
mBubbleController.removeBubble(
|
||||
mRow.getEntry(), BubbleController.DISMISS_USER_GESTURE);
|
||||
assertFalse(mNotificationShadeWindowController.getBubblesShowing());
|
||||
assertNull(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()));
|
||||
verify(mNotificationEntryManager, times(2)).updateNotifications(anyString());
|
||||
verify(mBubbleStateChangeListener).onHasBubblesChanged(false);
|
||||
|
||||
assertFalse(mSysUiStateBubblesExpanded);
|
||||
}
|
||||
@@ -388,7 +380,6 @@ public class BubbleControllerTest extends SysuiTestCase {
|
||||
assertTrue(mBubbleController.hasBubbles());
|
||||
|
||||
mBubbleData.dismissAll(BubbleController.DISMISS_USER_GESTURE);
|
||||
assertFalse(mNotificationShadeWindowController.getBubblesShowing());
|
||||
verify(mNotificationEntryManager, times(3)).updateNotifications(any());
|
||||
assertNull(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()));
|
||||
assertNull(mBubbleData.getBubbleInStackWithKey(mRow2.getEntry().getKey()));
|
||||
@@ -408,14 +399,12 @@ public class BubbleControllerTest extends SysuiTestCase {
|
||||
assertTrue(mBubbleController.hasBubbles());
|
||||
assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
|
||||
mRow.getEntry()));
|
||||
assertFalse(mNotificationShadeWindowController.getBubbleExpanded());
|
||||
|
||||
// Expand the stack
|
||||
BubbleStackView stackView = mBubbleController.getStackView();
|
||||
mBubbleData.setExpanded(true);
|
||||
assertTrue(mBubbleController.isStackExpanded());
|
||||
verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().getKey());
|
||||
assertTrue(mNotificationShadeWindowController.getBubbleExpanded());
|
||||
|
||||
assertTrue(mSysUiStateBubblesExpanded);
|
||||
|
||||
@@ -427,7 +416,6 @@ public class BubbleControllerTest extends SysuiTestCase {
|
||||
mBubbleController.collapseStack();
|
||||
verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow.getEntry().getKey());
|
||||
assertFalse(mBubbleController.isStackExpanded());
|
||||
assertFalse(mNotificationShadeWindowController.getBubbleExpanded());
|
||||
|
||||
assertFalse(mSysUiStateBubblesExpanded);
|
||||
}
|
||||
@@ -553,7 +541,6 @@ public class BubbleControllerTest extends SysuiTestCase {
|
||||
mEntryListener.onPendingEntryAdded(mRow2.getEntry());
|
||||
mBubbleController.updateBubble(mRow.getEntry());
|
||||
mBubbleController.updateBubble(mRow2.getEntry());
|
||||
verify(mBubbleStateChangeListener).onHasBubblesChanged(true);
|
||||
|
||||
// Expand
|
||||
BubbleStackView stackView = mBubbleController.getStackView();
|
||||
@@ -588,7 +575,6 @@ public class BubbleControllerTest extends SysuiTestCase {
|
||||
|
||||
// Make sure state changes and collapse happens
|
||||
verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow.getEntry().getKey());
|
||||
verify(mBubbleStateChangeListener).onHasBubblesChanged(false);
|
||||
assertFalse(mBubbleController.hasBubbles());
|
||||
|
||||
assertFalse(mSysUiStateBubblesExpanded);
|
||||
@@ -609,9 +595,6 @@ public class BubbleControllerTest extends SysuiTestCase {
|
||||
mRow.getEntry().getKey());
|
||||
assertFalse(mBubbleController.isStackExpanded());
|
||||
|
||||
// # of bubbles should change
|
||||
verify(mBubbleStateChangeListener).onHasBubblesChanged(true /* hasBubbles */);
|
||||
|
||||
assertFalse(mSysUiStateBubblesExpanded);
|
||||
}
|
||||
|
||||
@@ -629,9 +612,6 @@ public class BubbleControllerTest extends SysuiTestCase {
|
||||
mRow.getEntry().getKey());
|
||||
assertTrue(mBubbleController.isStackExpanded());
|
||||
|
||||
// # of bubbles should change
|
||||
verify(mBubbleStateChangeListener).onHasBubblesChanged(true /* hasBubbles */);
|
||||
|
||||
assertTrue(mSysUiStateBubblesExpanded);
|
||||
}
|
||||
|
||||
@@ -651,9 +631,6 @@ public class BubbleControllerTest extends SysuiTestCase {
|
||||
assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot());
|
||||
assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showFlyout());
|
||||
|
||||
// # of bubbles should change
|
||||
verify(mBubbleStateChangeListener).onHasBubblesChanged(true /* hasBubbles */);
|
||||
|
||||
assertFalse(mSysUiStateBubblesExpanded);
|
||||
}
|
||||
|
||||
@@ -679,9 +656,6 @@ public class BubbleControllerTest extends SysuiTestCase {
|
||||
assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot());
|
||||
assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showFlyout());
|
||||
|
||||
// # of bubbles should change
|
||||
verify(mBubbleStateChangeListener).onHasBubblesChanged(true /* hasBubbles */);
|
||||
|
||||
assertFalse(mSysUiStateBubblesExpanded);
|
||||
}
|
||||
|
||||
@@ -716,7 +690,6 @@ public class BubbleControllerTest extends SysuiTestCase {
|
||||
mEntryListener.onPendingEntryAdded(mNonBubbleNotifRow.getEntry());
|
||||
mEntryListener.onPreEntryUpdated(mNonBubbleNotifRow.getEntry());
|
||||
|
||||
verify(mBubbleStateChangeListener, never()).onHasBubblesChanged(anyBoolean());
|
||||
assertThat(mBubbleController.hasBubbles()).isFalse();
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
@@ -150,8 +149,6 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase {
|
||||
private ExpandableNotificationRow mRow2;
|
||||
private ExpandableNotificationRow mNonBubbleNotifRow;
|
||||
@Mock
|
||||
private BubbleController.BubbleStateChangeListener mBubbleStateChangeListener;
|
||||
@Mock
|
||||
private BubbleController.BubbleExpandListener mBubbleExpandListener;
|
||||
@Mock
|
||||
private PendingIntent mDeleteIntent;
|
||||
@@ -256,7 +253,6 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase {
|
||||
mSysUiState,
|
||||
mock(INotificationManager.class));
|
||||
mBubbleController.addNotifCallback(mNotifCallback);
|
||||
mBubbleController.setBubbleStateChangeListener(mBubbleStateChangeListener);
|
||||
mBubbleController.setExpandListener(mBubbleExpandListener);
|
||||
|
||||
// Get a reference to the BubbleController's entry listener
|
||||
@@ -269,8 +265,6 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase {
|
||||
public void testAddBubble() {
|
||||
mBubbleController.updateBubble(mRow.getEntry());
|
||||
assertTrue(mBubbleController.hasBubbles());
|
||||
|
||||
verify(mBubbleStateChangeListener).onHasBubblesChanged(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -286,13 +280,10 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase {
|
||||
assertNotNull(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()));
|
||||
assertTrue(mBubbleController.hasBubbles());
|
||||
verify(mNotifCallback, times(1)).invalidateNotifications(anyString());
|
||||
verify(mBubbleStateChangeListener).onHasBubblesChanged(true);
|
||||
|
||||
mBubbleController.removeBubble(mRow.getEntry(), BubbleController.DISMISS_USER_GESTURE);
|
||||
assertFalse(mNotificationShadeWindowController.getBubblesShowing());
|
||||
assertNull(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()));
|
||||
verify(mNotifCallback, times(2)).invalidateNotifications(anyString());
|
||||
verify(mBubbleStateChangeListener).onHasBubblesChanged(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -347,7 +338,6 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase {
|
||||
assertTrue(mBubbleController.hasBubbles());
|
||||
|
||||
mBubbleData.dismissAll(BubbleController.DISMISS_USER_GESTURE);
|
||||
assertFalse(mNotificationShadeWindowController.getBubblesShowing());
|
||||
verify(mNotifCallback, times(3)).invalidateNotifications(anyString());
|
||||
assertNull(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()));
|
||||
assertNull(mBubbleData.getBubbleInStackWithKey(mRow2.getEntry().getKey()));
|
||||
@@ -365,14 +355,12 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase {
|
||||
assertTrue(mBubbleController.hasBubbles());
|
||||
assertFalse(mBubbleController.isBubbleNotificationSuppressedFromShade(
|
||||
mRow.getEntry()));
|
||||
assertFalse(mNotificationShadeWindowController.getBubbleExpanded());
|
||||
|
||||
// Expand the stack
|
||||
BubbleStackView stackView = mBubbleController.getStackView();
|
||||
mBubbleData.setExpanded(true);
|
||||
assertTrue(mBubbleController.isStackExpanded());
|
||||
verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().getKey());
|
||||
assertTrue(mNotificationShadeWindowController.getBubbleExpanded());
|
||||
|
||||
// Make sure the notif is suppressed
|
||||
assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow.getEntry()));
|
||||
@@ -381,7 +369,6 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase {
|
||||
mBubbleController.collapseStack();
|
||||
verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow.getEntry().getKey());
|
||||
assertFalse(mBubbleController.isStackExpanded());
|
||||
assertFalse(mNotificationShadeWindowController.getBubbleExpanded());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -495,7 +482,6 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase {
|
||||
mEntryListener.onEntryAdded(mRow2.getEntry());
|
||||
mBubbleController.updateBubble(mRow.getEntry());
|
||||
mBubbleController.updateBubble(mRow2.getEntry());
|
||||
verify(mBubbleStateChangeListener).onHasBubblesChanged(true);
|
||||
|
||||
// Expand
|
||||
BubbleStackView stackView = mBubbleController.getStackView();
|
||||
@@ -528,7 +514,6 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase {
|
||||
|
||||
// Make sure state changes and collapse happens
|
||||
verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow.getEntry().getKey());
|
||||
verify(mBubbleStateChangeListener).onHasBubblesChanged(false);
|
||||
assertFalse(mBubbleController.hasBubbles());
|
||||
}
|
||||
|
||||
@@ -546,9 +531,6 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase {
|
||||
verify(mBubbleExpandListener, never()).onBubbleExpandChanged(false /* expanded */,
|
||||
mRow.getEntry().getKey());
|
||||
assertFalse(mBubbleController.isStackExpanded());
|
||||
|
||||
// # of bubbles should change
|
||||
verify(mBubbleStateChangeListener).onHasBubblesChanged(true /* hasBubbles */);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -564,9 +546,6 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase {
|
||||
verify(mBubbleExpandListener).onBubbleExpandChanged(true /* expanded */,
|
||||
mRow.getEntry().getKey());
|
||||
assertTrue(mBubbleController.isStackExpanded());
|
||||
|
||||
// # of bubbles should change
|
||||
verify(mBubbleStateChangeListener).onHasBubblesChanged(true /* hasBubbles */);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -584,9 +563,6 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase {
|
||||
// Dot + flyout is hidden because notif is suppressed
|
||||
assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot());
|
||||
assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showFlyout());
|
||||
|
||||
// # of bubbles should change
|
||||
verify(mBubbleStateChangeListener).onHasBubblesChanged(true /* hasBubbles */);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -610,9 +586,6 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase {
|
||||
// Dot + flyout is hidden because notif is suppressed
|
||||
assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showDot());
|
||||
assertFalse(mBubbleData.getBubbleInStackWithKey(mRow.getEntry().getKey()).showFlyout());
|
||||
|
||||
// # of bubbles should change
|
||||
verify(mBubbleStateChangeListener).onHasBubblesChanged(true /* hasBubbles */);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -630,7 +603,6 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase {
|
||||
mEntryListener.onEntryAdded(mNonBubbleNotifRow.getEntry());
|
||||
mEntryListener.onEntryUpdated(mNonBubbleNotifRow.getEntry());
|
||||
|
||||
verify(mBubbleStateChangeListener, never()).onHasBubblesChanged(anyBoolean());
|
||||
assertThat(mBubbleController.hasBubbles()).isFalse();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user