blob: 5a6f888b53ed28ab48425ca17e4ac2b1c5c04df8 [file] [log] [blame]
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.statusbar.notification.collection
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager.IMPORTANCE_DEFAULT
import android.app.NotificationManager.IMPORTANCE_HIGH
import android.app.NotificationManager.IMPORTANCE_LOW
import android.service.notification.NotificationListenerService.RankingMap
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.NotificationEntryHelper.modifyRanking
import com.android.systemui.statusbar.NotificationMediaManager
import com.android.systemui.statusbar.notification.NotificationEntryManagerLogger
import com.android.systemui.statusbar.notification.NotificationFilter
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_ALERTING
import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_SILENT
import com.android.systemui.statusbar.phone.NotificationGroupManager
import com.android.systemui.statusbar.policy.HeadsUpManager
import dagger.Lazy
import junit.framework.Assert.assertEquals
import org.junit.Before
import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.mock
import org.mockito.Mockito.`when` as whenever
@SmallTest
@RunWith(AndroidTestingRunner::class)
class NotificationRankingManagerTest : SysuiTestCase() {
private val lazyMedia: Lazy<NotificationMediaManager> = Lazy {
mock(NotificationMediaManager::class.java)
}
private lateinit var personNotificationIdentifier: PeopleNotificationIdentifier
private lateinit var rankingManager: TestableNotificationRankingManager
private lateinit var sectionsManager: NotificationSectionsFeatureManager
@Before
fun setup() {
personNotificationIdentifier =
mock(PeopleNotificationIdentifier::class.java)
sectionsManager = mock(NotificationSectionsFeatureManager::class.java)
rankingManager = TestableNotificationRankingManager(
lazyMedia,
mock(NotificationGroupManager::class.java),
mock(HeadsUpManager::class.java),
mock(NotificationFilter::class.java),
mock(NotificationEntryManagerLogger::class.java),
sectionsManager,
personNotificationIdentifier,
HighPriorityProvider(personNotificationIdentifier)
)
}
@Test
fun testSort_highPriorityTrumpsNMSRank() {
// NMS rank says A and then B. But A is not high priority and B is, so B should sort in
// front
val a = NotificationEntryBuilder()
.setImportance(IMPORTANCE_LOW) // low priority
.setRank(1) // NMS says rank first
.setPkg("pkg")
.setOpPkg("pkg")
.setTag("tag")
.setNotification(
Notification.Builder(mContext, "test")
.build())
.setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
.setUser(mContext.getUser())
.setOverrideGroupKey("")
.build()
val b = NotificationEntryBuilder()
.setImportance(IMPORTANCE_HIGH) // high priority
.setRank(2) // NMS says rank second
.setPkg("pkg2")
.setOpPkg("pkg2")
.setTag("tag")
.setNotification(
Notification.Builder(mContext, "test")
.build())
.setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
.setUser(mContext.getUser())
.setOverrideGroupKey("")
.build()
assertEquals(
listOf(b, a),
rankingManager.updateRanking(null, listOf(a, b), "test"))
}
@Test
fun testSort_samePriorityUsesNMSRank() {
// NMS rank says A and then B, and they are the same priority so use that rank
val aN = Notification.Builder(mContext, "test")
.setStyle(Notification.MessagingStyle(""))
.build()
val a = NotificationEntryBuilder()
.setRank(1)
.setImportance(IMPORTANCE_HIGH)
.setPkg("pkg")
.setOpPkg("pkg")
.setTag("tag")
.setNotification(aN)
.setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
.setUser(mContext.getUser())
.setOverrideGroupKey("")
.build()
val bN = Notification.Builder(mContext, "test")
.setStyle(Notification.MessagingStyle(""))
.build()
val b = NotificationEntryBuilder()
.setRank(2)
.setImportance(IMPORTANCE_HIGH)
.setPkg("pkg2")
.setOpPkg("pkg2")
.setTag("tag")
.setNotification(bN)
.setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
.setUser(mContext.getUser())
.setOverrideGroupKey("")
.build()
assertEquals(
listOf(a, b),
rankingManager.updateRanking(null, listOf(a, b), "test"))
}
@Test
fun testSort_headsUp_trumpsPeople() {
whenever(sectionsManager.isFilteringEnabled()).thenReturn(true)
val aN = Notification.Builder(mContext, "test")
.setStyle(Notification.MessagingStyle(""))
.build()
val a = NotificationEntryBuilder()
.setImportance(IMPORTANCE_HIGH)
.setPkg("pkg")
.setOpPkg("pkg")
.setTag("tag")
.setNotification(aN)
.setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
.setUser(mContext.getUser())
.setOverrideGroupKey("")
.build()
whenever(personNotificationIdentifier.isImportantPeopleNotification(a.sbn, a.ranking))
.thenReturn(true)
whenever(personNotificationIdentifier.isPeopleNotification(a.sbn, a.ranking))
.thenReturn(true)
val bN = Notification.Builder(mContext, "test")
.setStyle(Notification.MessagingStyle(""))
.build()
val b = NotificationEntryBuilder()
.setImportance(IMPORTANCE_HIGH)
.setPkg("pkg2")
.setOpPkg("pkg2")
.setTag("tag")
.setNotification(bN)
.setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
.setUser(mContext.getUser())
.setOverrideGroupKey("")
.build()
b.row = mock(ExpandableNotificationRow::class.java).also {
whenever(it.isHeadsUp).thenReturn(true)
}
whenever(personNotificationIdentifier.isImportantPeopleNotification(a.sbn, a.ranking))
.thenReturn(false)
whenever(personNotificationIdentifier.isPeopleNotification(a.sbn, a.ranking))
.thenReturn(false)
assertEquals(listOf(b, a), rankingManager.updateRanking(null, listOf(a, b), "test"))
}
@Ignore // TODO: (b/149046729) fix test and re-enable
@Test
fun testSort_importantPeople() {
whenever(sectionsManager.isFilteringEnabled()).thenReturn(true)
val aN = Notification.Builder(mContext, "test")
.setStyle(Notification.MessagingStyle(""))
.build()
val a = NotificationEntryBuilder()
.setImportance(IMPORTANCE_HIGH)
.setPkg("pkg")
.setOpPkg("pkg")
.setTag("tag")
.setNotification(aN)
.setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
.setUser(mContext.user)
.setOverrideGroupKey("")
.build()
whenever(personNotificationIdentifier.isImportantPeopleNotification(a.sbn, a.ranking))
.thenReturn(false)
whenever(personNotificationIdentifier.isPeopleNotification(a.sbn, a.ranking))
.thenReturn(true)
val bN = Notification.Builder(mContext, "test")
.setStyle(Notification.MessagingStyle(""))
.build()
val b = NotificationEntryBuilder()
.setImportance(IMPORTANCE_HIGH)
.setPkg("pkg2")
.setOpPkg("pkg2")
.setTag("tag")
.setNotification(bN)
.setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
.setUser(mContext.user)
.setOverrideGroupKey("")
.build()
whenever(personNotificationIdentifier.isImportantPeopleNotification(b.sbn, b.ranking))
.thenReturn(true)
whenever(personNotificationIdentifier.isPeopleNotification(b.sbn, b.ranking))
.thenReturn(true)
assertEquals(
listOf(b, a),
rankingManager.updateRanking(null, listOf(a, b), "test"))
}
@Test
fun testSort_properlySetsAlertingBucket() {
val notif = Notification.Builder(mContext, "test") .build()
val e = NotificationEntryBuilder()
.setPkg("pkg")
.setOpPkg("pkg")
.setTag("tag")
.setNotification(notif)
.setUser(mContext.user)
.setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
.setOverrideGroupKey("")
.build()
modifyRanking(e).setImportance(IMPORTANCE_DEFAULT).build()
rankingManager.updateRanking(RankingMap(arrayOf(e.ranking)), listOf(e), "test")
assertEquals(e.bucket, BUCKET_ALERTING)
}
@Test
fun testSort_properlySetsSilentBucket() {
val notif = Notification.Builder(mContext, "test") .build()
val e = NotificationEntryBuilder()
.setPkg("pkg")
.setOpPkg("pkg")
.setTag("tag")
.setNotification(notif)
.setUser(mContext.user)
.setChannel(NotificationChannel("test", "", IMPORTANCE_DEFAULT))
.setOverrideGroupKey("")
.build()
modifyRanking(e).setImportance(IMPORTANCE_LOW).build()
rankingManager.updateRanking(RankingMap(arrayOf(e.ranking)), listOf(e), "test")
assertEquals(e.bucket, BUCKET_SILENT)
}
internal class TestableNotificationRankingManager(
mediaManager: Lazy<NotificationMediaManager>,
groupManager: NotificationGroupManager,
headsUpManager: HeadsUpManager,
filter: NotificationFilter,
logger: NotificationEntryManagerLogger,
sectionsFeatureManager: NotificationSectionsFeatureManager,
peopleNotificationIdentifier: PeopleNotificationIdentifier,
highPriorityProvider: HighPriorityProvider
) : NotificationRankingManager(
mediaManager,
groupManager,
headsUpManager,
filter,
logger,
sectionsFeatureManager,
peopleNotificationIdentifier,
highPriorityProvider
) {
fun applyTestRankingMap(r: RankingMap) {
rankingMap = r
}
}
}