Merge "Only collapse bubbles when its from gesture nav" into tm-dev

This commit is contained in:
Mady Mellor
2022-02-24 01:30:11 +00:00
committed by Android (Google) Code Review
7 changed files with 175 additions and 21 deletions

View File

@@ -47,7 +47,10 @@ import android.app.ActivityManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
@@ -131,6 +134,10 @@ public class BubbleController {
public static final String RIGHT_POSITION = "Right";
public static final String BOTTOM_POSITION = "Bottom";
// Should match with PhoneWindowManager
private static final String SYSTEM_DIALOG_REASON_KEY = "reason";
private static final String SYSTEM_DIALOG_REASON_GESTURE_NAV = "gestureNav";
private final Context mContext;
private final BubblesImpl mImpl = new BubblesImpl();
private Bubbles.BubbleExpandListener mExpandListener;
@@ -675,6 +682,7 @@ public class BubbleController {
try {
mAddedToWindowManager = true;
registerBroadcastReceiver();
mBubbleData.getOverflow().initialize(this);
mWindowManager.addView(mStackView, mWmLayoutParams);
mStackView.setOnApplyWindowInsetsListener((view, windowInsets) -> {
@@ -717,6 +725,7 @@ public class BubbleController {
try {
mAddedToWindowManager = false;
mContext.unregisterReceiver(mBroadcastReceiver);
if (mStackView != null) {
mWindowManager.removeView(mStackView);
mBubbleData.getOverflow().cleanUpExpandedState();
@@ -730,11 +739,34 @@ public class BubbleController {
}
}
private void registerBroadcastReceiver() {
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
filter.addAction(Intent.ACTION_SCREEN_OFF);
mContext.registerReceiver(mBroadcastReceiver, filter);
}
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (!isStackExpanded()) return; // Nothing to do
String action = intent.getAction();
String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
if ((Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
&& SYSTEM_DIALOG_REASON_GESTURE_NAV.equals(reason))
|| Intent.ACTION_SCREEN_OFF.equals(action)) {
mMainExecutor.execute(() -> collapseStack());
}
}
};
/**
* Called by the BubbleStackView and whenever all bubbles have animated out, and none have been
* added in the meantime.
*/
void onAllBubblesAnimatedOut() {
@VisibleForTesting
public void onAllBubblesAnimatedOut() {
if (mStackView != null) {
mStackView.setVisibility(INVISIBLE);
removeFromWindowManagerMaybe();

View File

@@ -27,7 +27,6 @@ import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.wm.shell.bubbles.Bubbles;
import java.util.ArrayList;
import java.util.Optional;
@@ -50,7 +49,6 @@ public class ShadeControllerImpl implements ShadeController {
private final int mDisplayId;
protected final Lazy<Optional<StatusBar>> mStatusBarOptionalLazy;
private final Lazy<AssistManager> mAssistManagerLazy;
private final Optional<Bubbles> mBubblesOptional;
private final ArrayList<Runnable> mPostCollapseRunnables = new ArrayList<>();
@@ -62,8 +60,7 @@ public class ShadeControllerImpl implements ShadeController {
StatusBarKeyguardViewManager statusBarKeyguardViewManager,
WindowManager windowManager,
Lazy<Optional<StatusBar>> statusBarOptionalLazy,
Lazy<AssistManager> assistManagerLazy,
Optional<Bubbles> bubblesOptional
Lazy<AssistManager> assistManagerLazy
) {
mCommandQueue = commandQueue;
mStatusBarStateController = statusBarStateController;
@@ -73,7 +70,6 @@ public class ShadeControllerImpl implements ShadeController {
// TODO: Remove circular reference to StatusBar when possible.
mStatusBarOptionalLazy = statusBarOptionalLazy;
mAssistManagerLazy = assistManagerLazy;
mBubblesOptional = bubblesOptional;
}
@Override
@@ -131,8 +127,6 @@ public class ShadeControllerImpl implements ShadeController {
getStatusBar().getNotificationShadeWindowViewController().cancelExpandHelper();
getNotificationPanelViewController()
.collapsePanel(true /* animate */, delayed, speedUpFactor);
} else if (mBubblesOptional.isPresent()) {
mBubblesOptional.get().collapseStack();
}
}

View File

@@ -270,6 +270,7 @@ public class StatusBar extends CoreStartable implements
protected static final int MSG_DISMISS_KEYBOARD_SHORTCUTS_MENU = 1027;
// Should match the values in PhoneWindowManager
public static final String SYSTEM_DIALOG_REASON_KEY = "reason";
public static final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
public static final String SYSTEM_DIALOG_REASON_DREAM = "dream";
static public final String SYSTEM_DIALOG_REASON_SCREENSHOT = "screenshot";
@@ -2661,15 +2662,12 @@ public class StatusBar extends CoreStartable implements
Trace.beginSection("StatusBar#onReceive");
if (DEBUG) Log.v(TAG, "onReceive: " + intent);
String action = intent.getAction();
String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
KeyboardShortcuts.dismiss();
mRemoteInputManager.closeRemoteInputs();
if (mBubblesOptional.isPresent() && mBubblesOptional.get().isStackExpanded()) {
mBubblesOptional.get().collapseStack();
}
if (mLockscreenUserManager.isCurrentProfile(getSendingUserId())) {
int flags = CommandQueue.FLAG_EXCLUDE_NONE;
String reason = intent.getStringExtra("reason");
if (reason != null) {
if (reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL;
@@ -2684,19 +2682,13 @@ public class StatusBar extends CoreStartable implements
}
mShadeController.animateCollapsePanels(flags);
}
}
else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
} else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
if (mNotificationShadeWindowController != null) {
mNotificationShadeWindowController.setNotTouchable(false);
}
if (mBubblesOptional.isPresent() && mBubblesOptional.get().isStackExpanded()) {
// Post to main thread, since updating the UI.
mMainExecutor.execute(() -> mBubblesOptional.get().collapseStack());
}
finishBarAnimations();
resetUserExpandedStates();
}
else if (DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG.equals(action)) {
} else if (DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG.equals(action)) {
mQSPanelController.showDeviceMonitoringDialog();
}
Trace.endSection();

View File

@@ -381,7 +381,7 @@ public class StatusBarTest extends SysuiTestCase {
mShadeController = new ShadeControllerImpl(mCommandQueue,
mStatusBarStateController, mNotificationShadeWindowController,
mStatusBarKeyguardViewManager, mContext.getSystemService(WindowManager.class),
() -> Optional.of(mStatusBar), () -> mAssistManager, Optional.of(mBubbles));
() -> Optional.of(mStatusBar), () -> mAssistManager);
when(mOperatorNameViewControllerFactory.create(any()))
.thenReturn(mOperatorNameViewController);

View File

@@ -50,8 +50,10 @@ import android.app.IActivityManager;
import android.app.INotificationManager;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
@@ -197,6 +199,11 @@ public class BubblesTest extends SysuiTestCase {
private ArgumentCaptor<NotificationRemoveInterceptor> mRemoveInterceptorCaptor;
@Captor
private ArgumentCaptor<List<Bubble>> mBubbleListCaptor;
@Captor
private ArgumentCaptor<IntentFilter> mFilterArgumentCaptor;
@Captor
private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverArgumentCaptor;
private BubblesManager mBubblesManager;
// TODO(178618782): Move tests on the controller directly to the shell
@@ -1357,6 +1364,66 @@ public class BubblesTest extends SysuiTestCase {
assertStackCollapsed();
}
@Test
public void testRegisterUnregisterBroadcastListener() {
spyOn(mContext);
mBubbleController.updateBubble(mBubbleEntry);
verify(mContext).registerReceiver(mBroadcastReceiverArgumentCaptor.capture(),
mFilterArgumentCaptor.capture());
assertThat(mFilterArgumentCaptor.getValue().getAction(0)).isEqualTo(
Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
assertThat(mFilterArgumentCaptor.getValue().getAction(1)).isEqualTo(
Intent.ACTION_SCREEN_OFF);
mBubbleData.dismissBubbleWithKey(mBubbleEntry.getKey(), REASON_APP_CANCEL);
// TODO: not certain why this isn't called normally when tests are run, perhaps because
// it's after an animation in BSV. This calls BubbleController#removeFromWindowManagerMaybe
mBubbleController.onAllBubblesAnimatedOut();
verify(mContext).unregisterReceiver(eq(mBroadcastReceiverArgumentCaptor.getValue()));
}
@Test
public void testBroadcastReceiverCloseDialogs_notGestureNav() {
spyOn(mContext);
mBubbleController.updateBubble(mBubbleEntry);
mBubbleData.setExpanded(true);
verify(mContext).registerReceiver(mBroadcastReceiverArgumentCaptor.capture(),
mFilterArgumentCaptor.capture());
Intent i = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, i);
assertStackExpanded();
}
@Test
public void testBroadcastReceiverCloseDialogs_reasonGestureNav() {
spyOn(mContext);
mBubbleController.updateBubble(mBubbleEntry);
mBubbleData.setExpanded(true);
verify(mContext).registerReceiver(mBroadcastReceiverArgumentCaptor.capture(),
mFilterArgumentCaptor.capture());
Intent i = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
i.putExtra("reason", "gestureNav");
mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, i);
assertStackCollapsed();
}
@Test
public void testBroadcastReceiver_screenOff() {
spyOn(mContext);
mBubbleController.updateBubble(mBubbleEntry);
mBubbleData.setExpanded(true);
verify(mContext).registerReceiver(mBroadcastReceiverArgumentCaptor.capture(),
mFilterArgumentCaptor.capture());
Intent i = new Intent(Intent.ACTION_SCREEN_OFF);
mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, i);
assertStackCollapsed();
}
/** Creates a bubble using the userId and package. */
private Bubble createBubble(int userId, String pkg) {
final UserHandle userHandle = new UserHandle(userId);

View File

@@ -46,6 +46,9 @@ import android.app.IActivityManager;
import android.app.INotificationManager;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.LauncherApps;
import android.hardware.display.AmbientDisplayConfiguration;
import android.os.Handler;
@@ -179,6 +182,10 @@ public class NewNotifPipelineBubblesTest extends SysuiTestCase {
private ArgumentCaptor<NotifCollectionListener> mNotifListenerCaptor;
@Captor
private ArgumentCaptor<List<Bubble>> mBubbleListCaptor;
@Captor
private ArgumentCaptor<IntentFilter> mFilterArgumentCaptor;
@Captor
private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverArgumentCaptor;
private BubblesManager mBubblesManager;
private TestableBubbleController mBubbleController;
@@ -1176,6 +1183,67 @@ public class NewNotifPipelineBubblesTest extends SysuiTestCase {
assertStackCollapsed();
}
@Test
public void testRegisterUnregisterBroadcastListener() {
spyOn(mContext);
mBubbleController.updateBubble(mBubbleEntry);
verify(mContext).registerReceiver(mBroadcastReceiverArgumentCaptor.capture(),
mFilterArgumentCaptor.capture());
assertThat(mFilterArgumentCaptor.getValue().getAction(0)).isEqualTo(
Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
assertThat(mFilterArgumentCaptor.getValue().getAction(1)).isEqualTo(
Intent.ACTION_SCREEN_OFF);
mBubbleData.dismissBubbleWithKey(mBubbleEntry.getKey(), REASON_APP_CANCEL);
// TODO: not certain why this isn't called normally when tests are run, perhaps because
// it's after an animation in BSV. This calls BubbleController#removeFromWindowManagerMaybe
mBubbleController.onAllBubblesAnimatedOut();
verify(mContext).unregisterReceiver(eq(mBroadcastReceiverArgumentCaptor.getValue()));
}
@Test
public void testBroadcastReceiverCloseDialogs_notGestureNav() {
spyOn(mContext);
mBubbleController.updateBubble(mBubbleEntry);
mBubbleData.setExpanded(true);
verify(mContext).registerReceiver(mBroadcastReceiverArgumentCaptor.capture(),
mFilterArgumentCaptor.capture());
Intent i = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, i);
assertStackExpanded();
}
@Test
public void testBroadcastReceiverCloseDialogs_reasonGestureNav() {
spyOn(mContext);
mBubbleController.updateBubble(mBubbleEntry);
mBubbleData.setExpanded(true);
verify(mContext).registerReceiver(mBroadcastReceiverArgumentCaptor.capture(),
mFilterArgumentCaptor.capture());
Intent i = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
i.putExtra("reason", "gestureNav");
mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, i);
assertStackCollapsed();
}
@Test
public void testBroadcastReceiver_screenOff() {
spyOn(mContext);
mBubbleController.updateBubble(mBubbleEntry);
mBubbleData.setExpanded(true);
verify(mContext).registerReceiver(mBroadcastReceiverArgumentCaptor.capture(),
mFilterArgumentCaptor.capture());
Intent i = new Intent(Intent.ACTION_SCREEN_OFF);
mBroadcastReceiverArgumentCaptor.getValue().onReceive(mContext, i);
assertStackCollapsed();
}
/**
* Sets the bubble metadata flags for this entry. These flags are normally set by
* NotificationManagerService when the notification is sent, however, these tests do not

View File

@@ -330,6 +330,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
static public final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
static public final String SYSTEM_DIALOG_REASON_ASSIST = "assist";
static public final String SYSTEM_DIALOG_REASON_SCREENSHOT = "screenshot";
static public final String SYSTEM_DIALOG_REASON_GESTURE_NAV = "gestureNav";
private static final String TALKBACK_LABEL = "TalkBack";