Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt +15 −4 Original line number Original line Diff line number Diff line Loading @@ -144,13 +144,24 @@ class NotificationLaunchAnimatorController( } } } } private fun removeHun(animate: Boolean) { private val headsUpNotificationRow: ExpandableNotificationRow? get() { if (!headsUpManager.isAlerting(notificationKey)) { val summaryEntry = notificationEntry.parent?.summary return return when { headsUpManager.isAlerting(notificationKey) -> notification summaryEntry == null -> null headsUpManager.isAlerting(summaryEntry.key) -> summaryEntry.row else -> null } } } private fun removeHun(animate: Boolean) { val row = headsUpNotificationRow ?: return // TODO: b/297247841 - Call on the row we're removing, which may differ from notification. HeadsUpUtil.setNeedsHeadsUpDisappearAnimationAfterClick(notification, animate) HeadsUpUtil.setNeedsHeadsUpDisappearAnimationAfterClick(notification, animate) headsUpManager.removeNotification(notificationKey, true /* releaseImmediately */, animate) headsUpManager.removeNotification(row.entry.key, true /* releaseImmediately */, animate) } } override fun onLaunchAnimationCancelled(newKeyguardOccludedState: Boolean?) { override fun onLaunchAnimationCancelled(newKeyguardOccludedState: Boolean?) { Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt +36 −0 Original line number Original line Diff line number Diff line package com.android.systemui.statusbar.notification package com.android.systemui.statusbar.notification import android.app.Notification.GROUP_ALERT_SUMMARY import android.testing.AndroidTestingRunner import android.testing.AndroidTestingRunner import android.testing.TestableLooper import android.testing.TestableLooper import android.testing.TestableLooper.RunWithLooper import android.testing.TestableLooper.RunWithLooper Loading @@ -7,20 +8,26 @@ import androidx.test.filters.SmallTest import com.android.internal.jank.InteractionJankMonitor import com.android.internal.jank.InteractionJankMonitor import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectLastValue import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder import com.android.systemui.statusbar.notification.data.repository.NotificationExpansionRepository import com.android.systemui.statusbar.notification.data.repository.NotificationExpansionRepository import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.row.NotificationTestHelper import com.android.systemui.statusbar.notification.row.NotificationTestHelper import com.android.systemui.statusbar.notification.stack.NotificationListContainer import com.android.systemui.statusbar.notification.stack.NotificationListContainer import com.android.systemui.statusbar.phone.HeadsUpManagerPhone import com.android.systemui.statusbar.phone.HeadsUpManagerPhone import com.android.systemui.statusbar.policy.HeadsUpUtil import com.android.systemui.statusbar.policy.HeadsUpUtil import com.android.systemui.tests.R import junit.framework.Assert.assertFalse import junit.framework.Assert.assertFalse import junit.framework.Assert.assertTrue import junit.framework.Assert.assertTrue import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.TestScope import org.junit.Assert.assertNotSame import org.junit.Assert.assertSame import org.junit.Before import org.junit.Before import org.junit.Rule import org.junit.Rule import org.junit.Test import org.junit.Test import org.junit.runner.RunWith import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.Mock import org.mockito.Mockito.never import org.mockito.Mockito.verify import org.mockito.Mockito.verify import org.mockito.Mockito.`when` import org.mockito.Mockito.`when` import org.mockito.junit.MockitoJUnit import org.mockito.junit.MockitoJUnit Loading Loading @@ -117,6 +124,35 @@ class NotificationLaunchAnimatorControllerTest : SysuiTestCase() { verify(onFinishAnimationCallback).run() verify(onFinishAnimationCallback).run() } } @Test fun testAlertingSummaryHunRemovedOnNonAlertingChildLaunch() { val GROUP_KEY = "test_group_key" val summary = NotificationEntryBuilder().setGroup(mContext, GROUP_KEY).setId(0).apply { modifyNotification(mContext).setSmallIcon(R.drawable.ic_person) }.build() assertNotSame(summary.key, notification.entry.key) notificationTestHelper.createRow(summary) GroupEntryBuilder().setKey(GROUP_KEY).setSummary(summary).addChild(notification.entry) .build() assertSame(summary, notification.entry.parent?.summary) `when`(headsUpManager.isAlerting(notificationKey)).thenReturn(false) `when`(headsUpManager.isAlerting(summary.key)).thenReturn(true) assertNotSame(GROUP_ALERT_SUMMARY, summary.sbn.notification.groupAlertBehavior) assertNotSame(GROUP_ALERT_SUMMARY, notification.entry.sbn.notification.groupAlertBehavior) controller.onLaunchAnimationEnd(isExpandingFullyAbove = true) verify(headsUpManager).removeNotification( summary.key, true /* releaseImmediately */, false /* animate */) verify(headsUpManager, never()).removeNotification( notification.entry.key, true /* releaseImmediately */, false /* animate */) } @Test @Test fun testNotificationIsExpandingDuringAnimation() { fun testNotificationIsExpandingDuringAnimation() { controller.onIntentStarted(willAnimate = true) controller.onIntentStarted(willAnimate = true) Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java +23 −12 Original line number Original line Diff line number Diff line Loading @@ -269,6 +269,10 @@ public class NotificationTestHelper { return generateRow(notification, PKG, UID, USER_HANDLE, mDefaultInflationFlags); return generateRow(notification, PKG, UID, USER_HANDLE, mDefaultInflationFlags); } } public ExpandableNotificationRow createRow(NotificationEntry entry) throws Exception { return generateRow(entry, mDefaultInflationFlags); } /** /** * Create a row with the specified content views inflated in addition to the default. * Create a row with the specified content views inflated in addition to the default. * * Loading Loading @@ -538,18 +542,6 @@ public class NotificationTestHelper { @InflationFlag int extraInflationFlags, @InflationFlag int extraInflationFlags, int importance) int importance) throws Exception { throws Exception { // NOTE: This flag is read when the ExpandableNotificationRow is inflated, so it needs to be // set, but we do not want to override an existing value that is needed by a specific test. mFeatureFlags.setDefault(Flags.IMPROVED_HUN_ANIMATIONS); LayoutInflater inflater = (LayoutInflater) mContext.getSystemService( mContext.LAYOUT_INFLATER_SERVICE); mRow = (ExpandableNotificationRow) inflater.inflate( R.layout.status_bar_notification_row, null /* root */, false /* attachToRoot */); ExpandableNotificationRow row = mRow; final NotificationChannel channel = final NotificationChannel channel = new NotificationChannel( new NotificationChannel( notification.getChannelId(), notification.getChannelId(), Loading @@ -569,6 +561,25 @@ public class NotificationTestHelper { .setChannel(channel) .setChannel(channel) .build(); .build(); return generateRow(entry, extraInflationFlags); } private ExpandableNotificationRow generateRow( NotificationEntry entry, @InflationFlag int extraInflationFlags) throws Exception { // NOTE: This flag is read when the ExpandableNotificationRow is inflated, so it needs to be // set, but we do not want to override an existing value that is needed by a specific test. mFeatureFlags.setDefault(Flags.IMPROVED_HUN_ANIMATIONS); LayoutInflater inflater = (LayoutInflater) mContext.getSystemService( mContext.LAYOUT_INFLATER_SERVICE); mRow = (ExpandableNotificationRow) inflater.inflate( R.layout.status_bar_notification_row, null /* root */, false /* attachToRoot */); ExpandableNotificationRow row = mRow; entry.setRow(row); entry.setRow(row); mIconManager.createIcons(entry); mIconManager.createIcons(entry); Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt +15 −4 Original line number Original line Diff line number Diff line Loading @@ -144,13 +144,24 @@ class NotificationLaunchAnimatorController( } } } } private fun removeHun(animate: Boolean) { private val headsUpNotificationRow: ExpandableNotificationRow? get() { if (!headsUpManager.isAlerting(notificationKey)) { val summaryEntry = notificationEntry.parent?.summary return return when { headsUpManager.isAlerting(notificationKey) -> notification summaryEntry == null -> null headsUpManager.isAlerting(summaryEntry.key) -> summaryEntry.row else -> null } } } private fun removeHun(animate: Boolean) { val row = headsUpNotificationRow ?: return // TODO: b/297247841 - Call on the row we're removing, which may differ from notification. HeadsUpUtil.setNeedsHeadsUpDisappearAnimationAfterClick(notification, animate) HeadsUpUtil.setNeedsHeadsUpDisappearAnimationAfterClick(notification, animate) headsUpManager.removeNotification(notificationKey, true /* releaseImmediately */, animate) headsUpManager.removeNotification(row.entry.key, true /* releaseImmediately */, animate) } } override fun onLaunchAnimationCancelled(newKeyguardOccludedState: Boolean?) { override fun onLaunchAnimationCancelled(newKeyguardOccludedState: Boolean?) { Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt +36 −0 Original line number Original line Diff line number Diff line package com.android.systemui.statusbar.notification package com.android.systemui.statusbar.notification import android.app.Notification.GROUP_ALERT_SUMMARY import android.testing.AndroidTestingRunner import android.testing.AndroidTestingRunner import android.testing.TestableLooper import android.testing.TestableLooper import android.testing.TestableLooper.RunWithLooper import android.testing.TestableLooper.RunWithLooper Loading @@ -7,20 +8,26 @@ import androidx.test.filters.SmallTest import com.android.internal.jank.InteractionJankMonitor import com.android.internal.jank.InteractionJankMonitor import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectLastValue import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder import com.android.systemui.statusbar.notification.data.repository.NotificationExpansionRepository import com.android.systemui.statusbar.notification.data.repository.NotificationExpansionRepository import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.row.NotificationTestHelper import com.android.systemui.statusbar.notification.row.NotificationTestHelper import com.android.systemui.statusbar.notification.stack.NotificationListContainer import com.android.systemui.statusbar.notification.stack.NotificationListContainer import com.android.systemui.statusbar.phone.HeadsUpManagerPhone import com.android.systemui.statusbar.phone.HeadsUpManagerPhone import com.android.systemui.statusbar.policy.HeadsUpUtil import com.android.systemui.statusbar.policy.HeadsUpUtil import com.android.systemui.tests.R import junit.framework.Assert.assertFalse import junit.framework.Assert.assertFalse import junit.framework.Assert.assertTrue import junit.framework.Assert.assertTrue import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.TestScope import org.junit.Assert.assertNotSame import org.junit.Assert.assertSame import org.junit.Before import org.junit.Before import org.junit.Rule import org.junit.Rule import org.junit.Test import org.junit.Test import org.junit.runner.RunWith import org.junit.runner.RunWith import org.mockito.Mock import org.mockito.Mock import org.mockito.Mockito.never import org.mockito.Mockito.verify import org.mockito.Mockito.verify import org.mockito.Mockito.`when` import org.mockito.Mockito.`when` import org.mockito.junit.MockitoJUnit import org.mockito.junit.MockitoJUnit Loading Loading @@ -117,6 +124,35 @@ class NotificationLaunchAnimatorControllerTest : SysuiTestCase() { verify(onFinishAnimationCallback).run() verify(onFinishAnimationCallback).run() } } @Test fun testAlertingSummaryHunRemovedOnNonAlertingChildLaunch() { val GROUP_KEY = "test_group_key" val summary = NotificationEntryBuilder().setGroup(mContext, GROUP_KEY).setId(0).apply { modifyNotification(mContext).setSmallIcon(R.drawable.ic_person) }.build() assertNotSame(summary.key, notification.entry.key) notificationTestHelper.createRow(summary) GroupEntryBuilder().setKey(GROUP_KEY).setSummary(summary).addChild(notification.entry) .build() assertSame(summary, notification.entry.parent?.summary) `when`(headsUpManager.isAlerting(notificationKey)).thenReturn(false) `when`(headsUpManager.isAlerting(summary.key)).thenReturn(true) assertNotSame(GROUP_ALERT_SUMMARY, summary.sbn.notification.groupAlertBehavior) assertNotSame(GROUP_ALERT_SUMMARY, notification.entry.sbn.notification.groupAlertBehavior) controller.onLaunchAnimationEnd(isExpandingFullyAbove = true) verify(headsUpManager).removeNotification( summary.key, true /* releaseImmediately */, false /* animate */) verify(headsUpManager, never()).removeNotification( notification.entry.key, true /* releaseImmediately */, false /* animate */) } @Test @Test fun testNotificationIsExpandingDuringAnimation() { fun testNotificationIsExpandingDuringAnimation() { controller.onIntentStarted(willAnimate = true) controller.onIntentStarted(willAnimate = true) Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java +23 −12 Original line number Original line Diff line number Diff line Loading @@ -269,6 +269,10 @@ public class NotificationTestHelper { return generateRow(notification, PKG, UID, USER_HANDLE, mDefaultInflationFlags); return generateRow(notification, PKG, UID, USER_HANDLE, mDefaultInflationFlags); } } public ExpandableNotificationRow createRow(NotificationEntry entry) throws Exception { return generateRow(entry, mDefaultInflationFlags); } /** /** * Create a row with the specified content views inflated in addition to the default. * Create a row with the specified content views inflated in addition to the default. * * Loading Loading @@ -538,18 +542,6 @@ public class NotificationTestHelper { @InflationFlag int extraInflationFlags, @InflationFlag int extraInflationFlags, int importance) int importance) throws Exception { throws Exception { // NOTE: This flag is read when the ExpandableNotificationRow is inflated, so it needs to be // set, but we do not want to override an existing value that is needed by a specific test. mFeatureFlags.setDefault(Flags.IMPROVED_HUN_ANIMATIONS); LayoutInflater inflater = (LayoutInflater) mContext.getSystemService( mContext.LAYOUT_INFLATER_SERVICE); mRow = (ExpandableNotificationRow) inflater.inflate( R.layout.status_bar_notification_row, null /* root */, false /* attachToRoot */); ExpandableNotificationRow row = mRow; final NotificationChannel channel = final NotificationChannel channel = new NotificationChannel( new NotificationChannel( notification.getChannelId(), notification.getChannelId(), Loading @@ -569,6 +561,25 @@ public class NotificationTestHelper { .setChannel(channel) .setChannel(channel) .build(); .build(); return generateRow(entry, extraInflationFlags); } private ExpandableNotificationRow generateRow( NotificationEntry entry, @InflationFlag int extraInflationFlags) throws Exception { // NOTE: This flag is read when the ExpandableNotificationRow is inflated, so it needs to be // set, but we do not want to override an existing value that is needed by a specific test. mFeatureFlags.setDefault(Flags.IMPROVED_HUN_ANIMATIONS); LayoutInflater inflater = (LayoutInflater) mContext.getSystemService( mContext.LAYOUT_INFLATER_SERVICE); mRow = (ExpandableNotificationRow) inflater.inflate( R.layout.status_bar_notification_row, null /* root */, false /* attachToRoot */); ExpandableNotificationRow row = mRow; entry.setRow(row); entry.setRow(row); mIconManager.createIcons(entry); mIconManager.createIcons(entry); Loading