summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java62
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java16
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java175
8 files changed, 229 insertions, 59 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index e84c64838fd6..3aa9f73939ac 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -293,6 +293,17 @@ public class BubbleController implements BubbleExpandedView.OnBubbleBlockedListe
}
/**
+ * Request the stack expand if needed, then select the specified Bubble as current.
+ *
+ * @param notificationKey the notification key for the bubble to be selected
+ */
+ public void expandStackAndSelectBubble(String notificationKey) {
+ if (mStackView != null && mBubbleData.getBubble(notificationKey) != null) {
+ mStackView.setExpandedBubble(notificationKey);
+ }
+ }
+
+ /**
* Tell the stack of bubbles to be dismissed, this will remove all of the bubbles in the stack.
*/
void dismissStack(@DismissReason int reason) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
index b788f537316b..fd2f72062be7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
@@ -78,8 +78,7 @@ public final class NotificationClicker implements View.OnClickListener {
row.setJustClicked(true);
DejankUtils.postAfterTraversal(() -> row.setJustClicked(false));
- // If it was a bubble we should close it
- if (row.getEntry().isBubble()) {
+ if (!row.getEntry().isBubble()) {
mBubbleController.collapseStack();
}
@@ -95,7 +94,8 @@ public final class NotificationClicker implements View.OnClickListener {
*/
public void register(ExpandableNotificationRow row, StatusBarNotification sbn) {
Notification notification = sbn.getNotification();
- if (notification.contentIntent != null || notification.fullScreenIntent != null) {
+ if (notification.contentIntent != null || notification.fullScreenIntent != null
+ || row.getEntry().isBubble()) {
row.setOnClickListener(this);
} else {
row.setOnClickListener(null);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java
index b91cdaf9ae80..d3e5af8c729e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java
@@ -220,8 +220,6 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
StatusBarNotification sbn,
ExpandableNotificationRow row) {
row.setIsLowPriority(entry.ambient);
- // bind the click event to the content area
- checkNotNull(mNotificationClicker).register(row, sbn);
// Extract target SDK version.
try {
@@ -257,6 +255,9 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
row.setNeedsRedaction(
Dependency.get(NotificationLockscreenUserManager.class).needsRedaction(entry));
row.inflateViews();
+
+ // bind the click event to the content area
+ checkNotNull(mNotificationClicker).register(row, sbn);
}
private void logNotificationExpansion(String key, boolean userAction, boolean expanded) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index db91d0160391..7e0623250c31 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -25,6 +25,7 @@ import static android.app.StatusBarManager.WindowVisibleState;
import static android.app.StatusBarManager.windowStateToString;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
+import static com.android.systemui.Dependency.BG_HANDLER;
import static com.android.systemui.Dependency.MAIN_HANDLER;
import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP;
import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE;
@@ -1076,7 +1077,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mLockscreenUserManager, shadeController, mKeyguardMonitor,
mNotificationInterruptionStateProvider, mMetricsLogger,
new LockPatternUtils(mContext), Dependency.get(MAIN_HANDLER),
- mActivityIntentHelper);
+ Dependency.get(BG_HANDLER), mActivityIntentHelper, mBubbleController);
mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
index 215f5c4dfc5b..e4af15cf7dd1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -48,6 +48,7 @@ import com.android.systemui.Dependency;
import com.android.systemui.EventLogTags;
import com.android.systemui.UiOffloadThread;
import com.android.systemui.assist.AssistManager;
+import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.CommandQueue;
@@ -98,7 +99,9 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
private final CommandQueue mCommandQueue;
private final IDreamManager mDreamManager;
private final Handler mMainThreadHandler;
+ private final Handler mBackgroundHandler;
private final ActivityIntentHelper mActivityIntentHelper;
+ private final BubbleController mBubbleController;
private boolean mIsCollapsingToShowActivityOverLockscreen;
@@ -125,7 +128,9 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
MetricsLogger metricsLogger,
LockPatternUtils lockPatternUtils,
Handler mainThreadHandler,
- ActivityIntentHelper activityIntentHelper) {
+ Handler backgroundHandler,
+ ActivityIntentHelper activityIntentHelper,
+ BubbleController bubbleController) {
mContext = context;
mNotificationPanel = panel;
mPresenter = presenter;
@@ -147,6 +152,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
mAssistManager = assistManager;
mGroupManager = groupManager;
mLockPatternUtils = lockPatternUtils;
+ mBackgroundHandler = backgroundHandler;
mEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
@Override
public void onPendingEntryAdded(NotificationEntry entry) {
@@ -156,6 +162,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
mStatusBarRemoteInputCallback = remoteInputCallback;
mMainThreadHandler = mainThreadHandler;
mActivityIntentHelper = activityIntentHelper;
+ mBubbleController = bubbleController;
}
/**
@@ -178,14 +185,24 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
final PendingIntent intent = notification.contentIntent != null
? notification.contentIntent
: notification.fullScreenIntent;
+ final boolean isBubble = row.getEntry().isBubble();
+
+ // This code path is now executed for notification without a contentIntent.
+ // The only valid case is Bubble notifications. Guard against other cases
+ // entering here.
+ if (intent == null && !isBubble) {
+ Log.e(TAG, "onNotificationClicked called for non-clickable notification!");
+ return;
+ }
+
final String notificationKey = sbn.getKey();
- boolean isActivityIntent = intent.isActivity();
+ boolean isActivityIntent = intent != null && intent.isActivity() && !isBubble;
final boolean afterKeyguardGone = isActivityIntent
&& mActivityIntentHelper.wouldLaunchResolverActivity(intent.getIntent(),
mLockscreenUserManager.getCurrentUserId());
final boolean wasOccluded = mShadeController.isOccluded();
- boolean showOverLockscreen = mKeyguardMonitor.isShowing()
+ boolean showOverLockscreen = mKeyguardMonitor.isShowing() && intent != null
&& mActivityIntentHelper.wouldShowOverLockscreen(intent.getIntent(),
mLockscreenUserManager.getCurrentUserId());
ActivityStarter.OnDismissAction postKeyguardAction =
@@ -244,9 +261,8 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
mShadeController.addAfterKeyguardGoneRunnable(runnable);
mShadeController.collapsePanel();
} else {
- new Thread(runnable).start();
+ mBackgroundHandler.postAtFrontOfQueue(runnable);
}
-
return !mNotificationPanel.isFullyCollapsed();
}
@@ -287,6 +303,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
}
Intent fillInIntent = null;
NotificationEntry entry = row.getEntry();
+ final boolean isBubble = entry.isBubble();
CharSequence remoteInputText = null;
if (!TextUtils.isEmpty(entry.remoteInputText)) {
remoteInputText = entry.remoteInputText;
@@ -295,8 +312,12 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
fillInIntent = new Intent().putExtra(Notification.EXTRA_REMOTE_INPUT_DRAFT,
remoteInputText.toString());
}
- startNotificationIntent(intent, fillInIntent, row, wasOccluded, isActivityIntent);
- if (isActivityIntent) {
+ if (isBubble) {
+ expandBubbleStackOnMainThread(notificationKey);
+ } else {
+ startNotificationIntent(intent, fillInIntent, row, wasOccluded, isActivityIntent);
+ }
+ if (isActivityIntent || isBubble) {
mAssistManager.hideAssist();
}
if (shouldCollapse()) {
@@ -316,18 +337,29 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
} catch (RemoteException ex) {
// system process is dead if we're here.
}
- if (parentToCancelFinal != null) {
- removeNotification(parentToCancelFinal);
- }
- if (shouldAutoCancel(sbn)
- || mRemoteInputManager.isNotificationKeptForRemoteInputHistory(
- notificationKey)) {
- // Automatically remove all notifications that we may have kept around longer
- removeNotification(sbn);
+ if (!isBubble) {
+ if (parentToCancelFinal != null) {
+ removeNotification(parentToCancelFinal);
+ }
+ if (shouldAutoCancel(sbn)
+ || mRemoteInputManager.isNotificationKeptForRemoteInputHistory(
+ notificationKey)) {
+ // Automatically remove all notifications that we may have kept around longer
+ removeNotification(sbn);
+ }
}
mIsCollapsingToShowActivityOverLockscreen = false;
}
+ private void expandBubbleStackOnMainThread(String notificationKey) {
+ if (Looper.getMainLooper().isCurrentThread()) {
+ mBubbleController.expandStackAndSelectBubble(notificationKey);
+ } else {
+ mMainThreadHandler.post(
+ () -> mBubbleController.expandStackAndSelectBubble(notificationKey));
+ }
+ }
+
private void startNotificationIntent(PendingIntent intent, Intent fillInIntent,
ExpandableNotificationRow row, boolean wasOccluded, boolean isActivityIntent) {
RemoteAnimationAdapter adapter = mActivityLaunchAnimator.getLaunchAnimation(row,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
index 14bc71b6a142..9fa85d307d2a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
@@ -438,6 +438,22 @@ public class BubbleControllerTest extends SysuiTestCase {
}
@Test
+ public void testExpandStackAndSelectBubble_removedFirst() {
+ final String key = mRow.getEntry().key;
+
+ mEntryListener.onPendingEntryAdded(mRow.getEntry());
+ mBubbleController.updateBubble(mRow.getEntry(), true /* updatePosition */);
+
+ assertTrue(mRow.getEntry().isBubble());
+
+ // Simulate notification cancellation.
+ mEntryListener.onEntryRemoved(mRow.getEntry(), null /* notificationVisibility (unused) */,
+ false /* removedbyUser */);
+
+ mBubbleController.expandStackAndSelectBubble(key);
+ }
+
+ @Test
public void testMarkNewNotificationAsBubble() {
mEntryListener.onPendingEntryAdded(mRow.getEntry());
assertTrue(mRow.getEntry().isBubble());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
index 5ea4636149a2..7e089a653b9e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
@@ -151,6 +151,16 @@ public class NotificationTestHelper {
/**
* Returns an {@link ExpandableNotificationRow} that should be shown as a bubble.
+ */
+ public ExpandableNotificationRow createBubble()
+ throws Exception {
+ Notification n = createNotification(false /* isGroupSummary */,
+ null /* groupKey */, makeBubbleMetadata(null));
+ return generateRow(n, PKG, UID, USER_HANDLE, 0 /* extraInflationFlags */, IMPORTANCE_HIGH);
+ }
+
+ /**
+ * Returns an {@link ExpandableNotificationRow} that should be shown as a bubble.
*
* @param deleteIntent the intent to assign to {@link BubbleMetadata#deleteIntent}
*/
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
index 20af1ac5a42f..41e82cbeac36 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
@@ -24,7 +24,10 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import android.app.KeyguardManager;
@@ -49,6 +52,7 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.systemui.ActivityIntentHelper;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.assist.AssistManager;
+import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.CommandQueue;
@@ -101,22 +105,23 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
private KeyguardMonitor mKeyguardMonitor;
@Mock
private Handler mHandler;
+ @Mock
+ private BubbleController mBubbleController;
@Mock
private ActivityIntentHelper mActivityIntentHelper;
@Mock
private PendingIntent mContentIntent;
@Mock
- private NotificationData mNotificationData;
- @Mock
- private NotificationEntry mNotificationEntry;
+ private Intent mContentIntentInner;
@Mock
- private NotificationEntry mBubbleEntry;
+ private NotificationData mNotificationData;
private NotificationActivityStarter mNotificationActivityStarter;
private NotificationTestHelper mNotificationTestHelper;
- ExpandableNotificationRow mNotificationRow;
+ private ExpandableNotificationRow mNotificationRow;
+ private ExpandableNotificationRow mBubbleNotificationRow;
private final Answer<Void> mCallOnDismiss = answerVoid(
(ActivityStarter.OnDismissAction dismissAction, Runnable cancel,
@@ -129,14 +134,32 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
when(mRemoteInputManager.getController()).thenReturn(mRemoteInputController);
when(mEntryManager.getNotificationData()).thenReturn(mNotificationData);
- mActiveNotifications = new ArrayList<>();
- mActiveNotifications.add(mNotificationEntry);
- mActiveNotifications.add(mBubbleEntry);
- when(mNotificationData.getActiveNotifications()).thenReturn(mActiveNotifications);
- when(mNotificationEntry.getRow()).thenReturn(mNotificationRow);
+ when(mContentIntent.isActivity()).thenReturn(true);
+ when(mContentIntent.getCreatorUserHandle()).thenReturn(UserHandle.of(1));
+ when(mContentIntent.getIntent()).thenReturn(mContentIntentInner);
mNotificationTestHelper = new NotificationTestHelper(mContext);
+
+ // Create standard notification with contentIntent
mNotificationRow = mNotificationTestHelper.createRow();
+ StatusBarNotification sbn = mNotificationRow.getStatusBarNotification();
+ sbn.getNotification().contentIntent = mContentIntent;
+ sbn.getNotification().flags |= Notification.FLAG_AUTO_CANCEL;
+
+ // Create bubble notification row with contentIntent
+ mBubbleNotificationRow = mNotificationTestHelper.createBubble();
+ StatusBarNotification bubbleSbn = mBubbleNotificationRow.getStatusBarNotification();
+ bubbleSbn.getNotification().contentIntent = mContentIntent;
+ bubbleSbn.getNotification().flags |= Notification.FLAG_AUTO_CANCEL;
+ // Do what BubbleController's NotificationEntryListener#onPendingEntryAdded does:
+ mBubbleNotificationRow.getEntry().setIsBubble(true);
+ mBubbleNotificationRow.getEntry().setShowInShadeWhenBubble(true);
+
+ mActiveNotifications = new ArrayList<>();
+ mActiveNotifications.add(mNotificationRow.getEntry());
+ mActiveNotifications.add(mBubbleNotificationRow.getEntry());
+ when(mNotificationData.getActiveNotifications()).thenReturn(mActiveNotifications);
+ when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
mNotificationActivityStarter = new StatusBarNotificationActivityStarter(getContext(),
mock(CommandQueue.class), mAssistManager, mock(NotificationPanelView.class),
@@ -147,16 +170,8 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
mock(StatusBarRemoteInputCallback.class), mock(NotificationGroupManager.class),
mock(NotificationLockscreenUserManager.class), mShadeController, mKeyguardMonitor,
mock(NotificationInterruptionStateProvider.class), mock(MetricsLogger.class),
- mock(LockPatternUtils.class), mHandler, mActivityIntentHelper);
-
-
- when(mContentIntent.isActivity()).thenReturn(true);
- when(mContentIntent.getCreatorUserHandle()).thenReturn(UserHandle.of(1));
-
- // SBNActivityStarter expects contentIntent or fullScreenIntent to be set
- mNotificationRow.getEntry().notification.getNotification().contentIntent = mContentIntent;
-
- when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
+ mock(LockPatternUtils.class), mHandler, mHandler, mActivityIntentHelper,
+ mBubbleController);
// set up dismissKeyguardThenExecute to synchronously invoke the OnDismissAction arg
doAnswer(mCallOnDismiss).when(mActivityStarter).dismissKeyguardThenExecute(
@@ -173,33 +188,26 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
// set up Handler to synchronously invoke the Runnable arg
doAnswer(answerVoid(Runnable::run))
.when(mHandler).post(any(Runnable.class));
+
+ doAnswer(answerVoid(Runnable::run))
+ .when(mHandler).postAtFrontOfQueue(any(Runnable.class));
}
@Test
- public void testOnNotificationClicked_whileKeyguardVisible()
+ public void testOnNotificationClicked_keyGuardShowing()
throws PendingIntent.CanceledException, RemoteException {
// Given
+ StatusBarNotification sbn = mNotificationRow.getStatusBarNotification();
+ sbn.getNotification().contentIntent = mContentIntent;
+ sbn.getNotification().flags |= Notification.FLAG_AUTO_CANCEL;
+
when(mKeyguardMonitor.isShowing()).thenReturn(true);
when(mShadeController.isOccluded()).thenReturn(true);
- when(mContentIntent.isActivity()).thenReturn(true);
- when(mActivityIntentHelper.wouldShowOverLockscreen(any(Intent.class), anyInt()))
- .thenReturn(false);
- when(mActivityIntentHelper.wouldLaunchResolverActivity(any(Intent.class), anyInt()))
- .thenReturn(false);
-
- StatusBarNotification statusBarNotification = mNotificationRow.getEntry().notification;
- statusBarNotification.getNotification().flags |= Notification.FLAG_AUTO_CANCEL;
// When
- mNotificationActivityStarter.onNotificationClicked(statusBarNotification,
- mNotificationRow);
+ mNotificationActivityStarter.onNotificationClicked(sbn, mNotificationRow);
// Then
- verify(mActivityStarter).dismissKeyguardThenExecute(
- any(ActivityStarter.OnDismissAction.class),
- any() /* cancel */,
- anyBoolean() /* afterKeyguardGone */);
-
verify(mShadeController, atLeastOnce()).collapsePanel();
verify(mContentIntent).sendAndReturnResult(
@@ -214,9 +222,100 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
verify(mAssistManager).hideAssist();
verify(mStatusBarService).onNotificationClick(
- eq(mNotificationRow.getEntry().key), any(NotificationVisibility.class));
+ eq(sbn.getKey()), any(NotificationVisibility.class));
// Notification is removed due to FLAG_AUTO_CANCEL
- verify(mEntryManager).performRemoveNotification(eq(statusBarNotification));
+ verify(mEntryManager).performRemoveNotification(eq(sbn));
+ }
+
+ @Test
+ public void testOnNotificationClicked_bubble_noContentIntent_noKeyGuard()
+ throws RemoteException {
+ StatusBarNotification sbn = mBubbleNotificationRow.getStatusBarNotification();
+
+ // Given
+ sbn.getNotification().contentIntent = null;
+
+ // When
+ mNotificationActivityStarter.onNotificationClicked(sbn, mBubbleNotificationRow);
+
+ // Then
+ verify(mBubbleController).expandStackAndSelectBubble(eq(sbn.getKey()));
+
+ // This is called regardless, and simply short circuits when there is nothing to do.
+ verify(mShadeController, atLeastOnce()).collapsePanel();
+
+ verify(mAssistManager).hideAssist();
+
+ verify(mStatusBarService).onNotificationClick(
+ eq(sbn.getKey()), any(NotificationVisibility.class));
+
+ // The content intent should NOT be sent on click.
+ verifyZeroInteractions(mContentIntent);
+
+ // Notification should not be cancelled.
+ verify(mEntryManager, never()).performRemoveNotification(eq(sbn));
+ }
+
+ @Test
+ public void testOnNotificationClicked_bubble_noContentIntent_keyGuardShowing()
+ throws RemoteException {
+ StatusBarNotification sbn = mBubbleNotificationRow.getStatusBarNotification();
+
+ // Given
+ sbn.getNotification().contentIntent = null;
+ when(mKeyguardMonitor.isShowing()).thenReturn(true);
+ when(mShadeController.isOccluded()).thenReturn(true);
+
+ // When
+ mNotificationActivityStarter.onNotificationClicked(sbn, mBubbleNotificationRow);
+
+ // Then
+ verify(mBubbleController).expandStackAndSelectBubble(eq(sbn.getKey()));
+
+ verify(mShadeController, atLeastOnce()).collapsePanel();
+
+ verify(mAssistManager).hideAssist();
+
+ verify(mStatusBarService).onNotificationClick(
+ eq(sbn.getKey()), any(NotificationVisibility.class));
+
+ // The content intent should NOT be sent on click.
+ verifyZeroInteractions(mContentIntent);
+
+ // Notification should not be cancelled.
+ verify(mEntryManager, never()).performRemoveNotification(eq(sbn));
+ }
+
+ @Test
+ public void testOnNotificationClicked_bubble_withContentIntent_keyGuardShowing()
+ throws RemoteException {
+ StatusBarNotification sbn = mBubbleNotificationRow.getStatusBarNotification();
+
+ // Given
+ sbn.getNotification().contentIntent = mContentIntent;
+ when(mKeyguardMonitor.isShowing()).thenReturn(true);
+ when(mShadeController.isOccluded()).thenReturn(true);
+
+ // When
+ mNotificationActivityStarter.onNotificationClicked(sbn, mBubbleNotificationRow);
+
+ // Then
+ verify(mBubbleController).expandStackAndSelectBubble(eq(sbn.getKey()));
+
+ verify(mShadeController, atLeastOnce()).collapsePanel();
+
+ verify(mAssistManager).hideAssist();
+
+ verify(mStatusBarService).onNotificationClick(
+ eq(sbn.getKey()), any(NotificationVisibility.class));
+
+ // The content intent should NOT be sent on click.
+ verify(mContentIntent).getIntent();
+ verify(mContentIntent).isActivity();
+ verifyNoMoreInteractions(mContentIntent);
+
+ // Notification should not be cancelled.
+ verify(mEntryManager, never()).performRemoveNotification(eq(sbn));
}
}