diff options
| author | 2022-10-20 16:26:09 +0000 | |
|---|---|---|
| committer | 2022-10-25 03:24:11 +0000 | |
| commit | 900fa741b5aba17022c4c93c697b60cbb4be0456 (patch) | |
| tree | 825239d8d506537da06cb3775cd38be155dd8466 | |
| parent | 3650a601e728444a58655b9bf35ed9e89058fa9d (diff) | |
Add test code for `Fix the height of NotificationContentView when there's no actions but bubble button`
Added function `NotificationContentView.shouldShowBubbleButton(NotificationEntry entry)` to make unit test possible. Added tests in the converted Kotlin version of NotificationContentViewTest.
Bug: 244522899
Test: `atest NotificationContentViewTest`
Change-Id: I8c34db53386dac95d52874ed250d8420ab9a1676
2 files changed, 179 insertions, 10 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java index 8de036542c8f..277ad8e54016 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java @@ -1374,13 +1374,8 @@ public class NotificationContentView extends FrameLayout implements Notification if (bubbleButton == null || actionContainer == null) { return; } - boolean isPersonWithShortcut = - mPeopleIdentifier.getPeopleNotificationType(entry) - >= PeopleNotificationIdentifier.TYPE_FULL_PERSON; - boolean showButton = BubblesManager.areBubblesEnabled(mContext, entry.getSbn().getUser()) - && isPersonWithShortcut - && entry.getBubbleMetadata() != null; - if (showButton) { + + if (shouldShowBubbleButton(entry)) { // explicitly resolve drawable resource using SystemUI's theme Drawable d = mContext.getDrawable(entry.isBubble() ? R.drawable.bubble_ic_stop_bubble @@ -1410,6 +1405,16 @@ public class NotificationContentView extends FrameLayout implements Notification } } + @VisibleForTesting + boolean shouldShowBubbleButton(NotificationEntry entry) { + boolean isPersonWithShortcut = + mPeopleIdentifier.getPeopleNotificationType(entry) + >= PeopleNotificationIdentifier.TYPE_FULL_PERSON; + return BubblesManager.areBubblesEnabled(mContext, entry.getSbn().getUser()) + && isPersonWithShortcut + && entry.getBubbleMetadata() != null; + } + private void applySnoozeAction(View layout) { if (layout == null || mContainingNotification == null) { return; diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.kt index 07201365faa8..562b4dfb35ef 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.kt @@ -16,9 +16,15 @@ package com.android.systemui.statusbar.notification.row +import android.content.res.Resources +import android.os.UserHandle +import android.service.notification.StatusBarNotification import android.testing.AndroidTestingRunner import android.view.NotificationHeaderView import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout import androidx.test.filters.SmallTest import com.android.internal.R import com.android.internal.widget.NotificationActionListLayout @@ -26,31 +32,45 @@ import com.android.internal.widget.NotificationExpandButton import com.android.systemui.SysuiTestCase import com.android.systemui.media.dialog.MediaOutputDialogFactory import com.android.systemui.statusbar.notification.FeedbackIcon +import com.android.systemui.statusbar.notification.collection.NotificationEntry +import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.whenever +import junit.framework.Assert.assertEquals import org.junit.Before import org.junit.Test import org.junit.runner.RunWith -import org.mockito.Mockito +import org.mockito.Mock import org.mockito.Mockito.doReturn import org.mockito.Mockito.never +import org.mockito.Mockito.spy import org.mockito.Mockito.verify +import org.mockito.MockitoAnnotations.initMocks @SmallTest @RunWith(AndroidTestingRunner::class) class NotificationContentViewTest : SysuiTestCase() { private lateinit var view: NotificationContentView + @Mock private lateinit var mPeopleNotificationIdentifier: PeopleNotificationIdentifier + + private val notificationContentMargin = + mContext.resources.getDimensionPixelSize(R.dimen.notification_content_margin) + @Before fun setup() { + initMocks(this) + mDependency.injectMockDependency(MediaOutputDialogFactory::class.java) - view = NotificationContentView(mContext, /* attrs= */ null) + view = spy(NotificationContentView(mContext, /* attrs= */ null)) val row = ExpandableNotificationRow(mContext, /* attrs= */ null) - val spyRow = Mockito.spy(row) + row.entry = createMockNotificationEntry(false) + val spyRow = spy(row) doReturn(10).whenever(spyRow).intrinsicHeight with(view) { + initialize(mPeopleNotificationIdentifier, mock(), mock(), mock()) setContainingNotification(spyRow) setHeights(/* smallHeight= */ 10, /* headsUpMaxHeight= */ 20, /* maxHeight= */ 30) contractedChild = createViewWithHeight(10) @@ -183,4 +203,148 @@ class NotificationContentViewTest : SysuiTestCase() { View.IMPORTANT_FOR_ACCESSIBILITY_AUTO verify(mockHeadsUpActions).importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_AUTO } + + @Test + fun setExpandedChild_notShowBubbleButton_marginTargetBottomMarginShouldNotChange() { + // Given: bottom margin of actionListMarginTarget is notificationContentMargin + // Bubble button should not be shown for the given NotificationEntry + val mockNotificationEntry = createMockNotificationEntry(/* showButton= */ false) + val mockContainingNotification = createMockContainingNotification(mockNotificationEntry) + val actionListMarginTarget = + spy(createLinearLayoutWithBottomMargin(notificationContentMargin)) + val mockExpandedChild = createMockExpandedChild(mockNotificationEntry) + whenever( + mockExpandedChild.findViewById<LinearLayout>( + R.id.notification_action_list_margin_target + ) + ) + .thenReturn(actionListMarginTarget) + view.setContainingNotification(mockContainingNotification) + + // When: call NotificationContentView.setExpandedChild() to set the expandedChild + view.expandedChild = mockExpandedChild + + // Then: bottom margin of actionListMarginTarget should not change, + // still be notificationContentMargin + assertEquals(notificationContentMargin, getMarginBottom(actionListMarginTarget)) + } + + @Test + fun setExpandedChild_showBubbleButton_marginTargetBottomMarginShouldChangeToZero() { + // Given: bottom margin of actionListMarginTarget is notificationContentMargin + // Bubble button should be shown for the given NotificationEntry + val mockNotificationEntry = createMockNotificationEntry(/* showButton= */ true) + val mockContainingNotification = createMockContainingNotification(mockNotificationEntry) + val actionListMarginTarget = + spy(createLinearLayoutWithBottomMargin(notificationContentMargin)) + val mockExpandedChild = createMockExpandedChild(mockNotificationEntry) + whenever( + mockExpandedChild.findViewById<LinearLayout>( + R.id.notification_action_list_margin_target + ) + ) + .thenReturn(actionListMarginTarget) + view.setContainingNotification(mockContainingNotification) + + // When: call NotificationContentView.setExpandedChild() to set the expandedChild + view.expandedChild = mockExpandedChild + + // Then: bottom margin of actionListMarginTarget should be set to 0 + assertEquals(0, getMarginBottom(actionListMarginTarget)) + } + + @Test + fun onNotificationUpdated_notShowBubbleButton_marginTargetBottomMarginShouldNotChange() { + // Given: bottom margin of actionListMarginTarget is notificationContentMargin + val mockNotificationEntry = createMockNotificationEntry(/* showButton= */ false) + val mockContainingNotification = createMockContainingNotification(mockNotificationEntry) + val actionListMarginTarget = + spy(createLinearLayoutWithBottomMargin(notificationContentMargin)) + val mockExpandedChild = createMockExpandedChild(mockNotificationEntry) + whenever( + mockExpandedChild.findViewById<LinearLayout>( + R.id.notification_action_list_margin_target + ) + ) + .thenReturn(actionListMarginTarget) + view.setContainingNotification(mockContainingNotification) + view.expandedChild = mockExpandedChild + assertEquals(notificationContentMargin, getMarginBottom(actionListMarginTarget)) + + // When: call NotificationContentView.onNotificationUpdated() to update the + // NotificationEntry, which should not show bubble button + view.onNotificationUpdated(createMockNotificationEntry(/* showButton= */ false)) + + // Then: bottom margin of actionListMarginTarget should not change, still be 20 + assertEquals(notificationContentMargin, getMarginBottom(actionListMarginTarget)) + } + + @Test + fun onNotificationUpdated_showBubbleButton_marginTargetBottomMarginShouldChangeToZero() { + // Given: bottom margin of actionListMarginTarget is notificationContentMargin + val mockNotificationEntry = createMockNotificationEntry(/* showButton= */ false) + val mockContainingNotification = createMockContainingNotification(mockNotificationEntry) + val actionListMarginTarget = + spy(createLinearLayoutWithBottomMargin(notificationContentMargin)) + val mockExpandedChild = createMockExpandedChild(mockNotificationEntry) + whenever( + mockExpandedChild.findViewById<LinearLayout>( + R.id.notification_action_list_margin_target + ) + ) + .thenReturn(actionListMarginTarget) + view.setContainingNotification(mockContainingNotification) + view.expandedChild = mockExpandedChild + assertEquals(notificationContentMargin, getMarginBottom(actionListMarginTarget)) + + // When: call NotificationContentView.onNotificationUpdated() to update the + // NotificationEntry, which should show bubble button + view.onNotificationUpdated(createMockNotificationEntry(true)) + + // Then: bottom margin of actionListMarginTarget should not change, still be 20 + assertEquals(0, getMarginBottom(actionListMarginTarget)) + } + + private fun createMockContainingNotification(notificationEntry: NotificationEntry) = + mock<ExpandableNotificationRow>().apply { + whenever(this.entry).thenReturn(notificationEntry) + whenever(this.context).thenReturn(mContext) + whenever(this.bubbleClickListener).thenReturn(View.OnClickListener {}) + } + + private fun createMockNotificationEntry(showButton: Boolean) = + mock<NotificationEntry>().apply { + whenever(mPeopleNotificationIdentifier.getPeopleNotificationType(this)) + .thenReturn(PeopleNotificationIdentifier.TYPE_FULL_PERSON) + whenever(this.bubbleMetadata).thenReturn(mock()) + val sbnMock: StatusBarNotification = mock() + val userMock: UserHandle = mock() + whenever(this.sbn).thenReturn(sbnMock) + whenever(sbnMock.user).thenReturn(userMock) + doReturn(showButton).whenever(view).shouldShowBubbleButton(this) + } + + private fun createLinearLayoutWithBottomMargin(bottomMargin: Int): LinearLayout { + val outerLayout = LinearLayout(mContext) + val innerLayout = LinearLayout(mContext) + outerLayout.addView(innerLayout) + val mlp = innerLayout.layoutParams as ViewGroup.MarginLayoutParams + mlp.setMargins(0, 0, 0, bottomMargin) + return innerLayout + } + + private fun createMockExpandedChild(notificationEntry: NotificationEntry) = + mock<ExpandableNotificationRow>().apply { + whenever(this.findViewById<ImageView>(R.id.bubble_button)).thenReturn(mock()) + whenever(this.findViewById<View>(R.id.actions_container)).thenReturn(mock()) + whenever(this.entry).thenReturn(notificationEntry) + whenever(this.context).thenReturn(mContext) + + val resourcesMock: Resources = mock() + whenever(resourcesMock.configuration).thenReturn(mock()) + whenever(this.resources).thenReturn(resourcesMock) + } + + private fun getMarginBottom(layout: LinearLayout): Int = + (layout.layoutParams as ViewGroup.MarginLayoutParams).bottomMargin } |