Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4aafce53 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix ranking of people notifications and peoplehub"

parents e880831d 960f4ced
Loading
Loading
Loading
Loading
+26 −45
Original line number Original line Diff line number Diff line
@@ -16,37 +16,29 @@


package com.android.systemui.statusbar.notification.collection
package com.android.systemui.statusbar.notification.collection


import android.app.Notification
import android.app.NotificationManager.IMPORTANCE_DEFAULT
import android.app.NotificationManager.IMPORTANCE_DEFAULT
import android.app.NotificationManager.IMPORTANCE_HIGH
import android.app.NotificationManager.IMPORTANCE_HIGH
import android.app.NotificationManager.IMPORTANCE_LOW
import android.app.NotificationManager.IMPORTANCE_LOW
import android.app.NotificationManager.IMPORTANCE_MIN
import android.app.NotificationManager.IMPORTANCE_MIN
import android.app.Person
import android.service.notification.NotificationListenerService.Ranking
import android.service.notification.NotificationListenerService.Ranking
import android.service.notification.NotificationListenerService.RankingMap
import android.service.notification.NotificationListenerService.RankingMap
import android.service.notification.StatusBarNotification
import android.service.notification.StatusBarNotification
import com.android.internal.annotations.VisibleForTesting
import com.android.internal.annotations.VisibleForTesting

import com.android.systemui.statusbar.NotificationMediaManager
import com.android.systemui.statusbar.NotificationMediaManager
import com.android.systemui.statusbar.notification.NotificationFilter
import com.android.systemui.statusbar.notification.NotificationFilter
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
import com.android.systemui.statusbar.notification.logging.NotifEvent
import com.android.systemui.statusbar.notification.logging.NotifEvent
import com.android.systemui.statusbar.notification.logging.NotifLog
import com.android.systemui.statusbar.notification.logging.NotifLog
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_ALERTING
import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_ALERTING
import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_PEOPLE
import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_PEOPLE
import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_SILENT
import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_SILENT
import com.android.systemui.statusbar.phone.NotificationGroupManager
import com.android.systemui.statusbar.phone.NotificationGroupManager
import com.android.systemui.statusbar.policy.HeadsUpManager
import com.android.systemui.statusbar.policy.HeadsUpManager

import dagger.Lazy
import java.util.Objects
import java.util.Objects
import java.util.ArrayList

import javax.inject.Inject
import javax.inject.Inject


import kotlin.Comparator

import dagger.Lazy

private const val TAG = "NotifRankingManager"
private const val TAG = "NotifRankingManager"


/**
/**
@@ -64,7 +56,8 @@ open class NotificationRankingManager @Inject constructor(
    private val headsUpManager: HeadsUpManager,
    private val headsUpManager: HeadsUpManager,
    private val notifFilter: NotificationFilter,
    private val notifFilter: NotificationFilter,
    private val notifLog: NotifLog,
    private val notifLog: NotifLog,
    sectionsFeatureManager: NotificationSectionsFeatureManager
    sectionsFeatureManager: NotificationSectionsFeatureManager,
    private val peopleNotificationIdentifier: PeopleNotificationIdentifier
) {
) {


    var rankingMap: RankingMap? = null
    var rankingMap: RankingMap? = null
@@ -79,6 +72,9 @@ open class NotificationRankingManager @Inject constructor(
        val aRank = a.ranking.rank
        val aRank = a.ranking.rank
        val bRank = b.ranking.rank
        val bRank = b.ranking.rank


        val aIsPeople = a.isPeopleNotification()
        val bIsPeople = b.isPeopleNotification()

        val aMedia = isImportantMedia(a)
        val aMedia = isImportantMedia(a)
        val bMedia = isImportantMedia(b)
        val bMedia = isImportantMedia(b)


@@ -88,25 +84,19 @@ open class NotificationRankingManager @Inject constructor(
        val aHeadsUp = a.isRowHeadsUp
        val aHeadsUp = a.isRowHeadsUp
        val bHeadsUp = b.isRowHeadsUp
        val bHeadsUp = b.isRowHeadsUp


        if (usePeopleFiltering && a.isPeopleNotification() != b.isPeopleNotification()) {
        when {
            if (a.isPeopleNotification()) -1 else 1
            usePeopleFiltering && aIsPeople != bIsPeople -> if (aIsPeople) -1 else 1
        } else if (aHeadsUp != bHeadsUp) {
            aHeadsUp != bHeadsUp -> if (aHeadsUp) -1 else 1
            if (aHeadsUp) -1 else 1
        } else if (aHeadsUp) {
            // Provide consistent ranking with headsUpManager
            // Provide consistent ranking with headsUpManager
            headsUpManager.compare(a, b)
            aHeadsUp -> headsUpManager.compare(a, b)
        } else if (aMedia != bMedia) {
            // Upsort current media notification.
            // Upsort current media notification.
            if (aMedia) -1 else 1
            aMedia != bMedia -> if (aMedia) -1 else 1
        } else if (aSystemMax != bSystemMax) {
            // Upsort PRIORITY_MAX system notifications
            // Upsort PRIORITY_MAX system notifications
            if (aSystemMax) -1 else 1
            aSystemMax != bSystemMax -> if (aSystemMax) -1 else 1
        } else if (a.isHighPriority != b.isHighPriority) {
            a.isHighPriority != b.isHighPriority ->
            -1 * java.lang.Boolean.compare(a.isHighPriority, b.isHighPriority)
                -1 * a.isHighPriority.compareTo(b.isHighPriority)
        } else if (aRank != bRank) {
            aRank != bRank -> aRank - bRank
            aRank - bRank
            else -> nb.notification.`when`.compareTo(na.notification.`when`)
        } else {
            nb.notification.`when`.compareTo(na.notification.`when`)
        }
        }
    }
    }


@@ -138,10 +128,9 @@ open class NotificationRankingManager @Inject constructor(
        val c = entry.channel
        val c = entry.channel
        val n = entry.sbn.notification
        val n = entry.sbn.notification


        if (((n.isForegroundService && entry.ranking.importance >= IMPORTANCE_LOW) ||
        if ((n.isForegroundService && entry.ranking.importance >= IMPORTANCE_LOW) ||
                n.hasMediaSession() ||
                n.hasMediaSession() ||
            n.hasPerson() ||
                entry.isPeopleNotification()) {
            n.hasStyle(Notification.MessagingStyle::class.java))) {
            // Users who have long pressed and demoted to silent should not see the notification
            // Users who have long pressed and demoted to silent should not see the notification
            // in the top section
            // in the top section
            if (c != null && c.hasUserSetImportance()) {
            if (c != null && c.hasUserSetImportance()) {
@@ -204,7 +193,7 @@ open class NotificationRankingManager @Inject constructor(
        isMedia: Boolean,
        isMedia: Boolean,
        isSystemMax: Boolean
        isSystemMax: Boolean
    ) {
    ) {
        if (usePeopleFiltering && entry.hasAssociatedPeople()) {
        if (usePeopleFiltering && entry.isPeopleNotification()) {
            entry.bucket = BUCKET_PEOPLE
            entry.bucket = BUCKET_PEOPLE
        } else if (isHeadsUp || isMedia || isSystemMax || entry.isHighPriority) {
        } else if (isHeadsUp || isMedia || isSystemMax || entry.isHighPriority) {
            entry.bucket = BUCKET_ALERTING
            entry.bucket = BUCKET_ALERTING
@@ -235,6 +224,11 @@ open class NotificationRankingManager @Inject constructor(
            }
            }
        }
        }
    }
    }

    private fun NotificationEntry.isPeopleNotification() =
            sbn.isPeopleNotification()
    private fun StatusBarNotification.isPeopleNotification() =
            peopleNotificationIdentifier.isPeopleNotification(this)
}
}


// Convenience functions
// Convenience functions
@@ -245,16 +239,3 @@ private fun NotificationEntry.isSystemMax(): Boolean {
private fun StatusBarNotification.isSystemNotification(): Boolean {
private fun StatusBarNotification.isSystemNotification(): Boolean {
    return "android" == packageName || "com.android.systemui" == packageName
    return "android" == packageName || "com.android.systemui" == packageName
}
}

private fun Notification.hasPerson(): Boolean {
    val people: ArrayList<Person> =
            (extras?.getParcelableArrayList(Notification.EXTRA_PEOPLE_LIST)) ?: ArrayList()
    return people.isNotEmpty()
}

private fun Notification.hasStyle(targetStyleClass: Class<*>): Boolean {
    return targetStyleClass == notificationStyle
}

private fun NotificationEntry.isPeopleNotification(): Boolean =
        sbn.notification.hasStyle(Notification.MessagingStyle::class.java)
+1 −1
Original line number Original line Diff line number Diff line
@@ -318,7 +318,7 @@ public class NotificationSectionsManager implements StackScrollAlgorithm.Section
                }
                }
                mParent.addView(mPeopleHubView, targetIndex);
                mParent.addView(mPeopleHubView, targetIndex);
                return true;
                return true;
            } else if (currentHubIndex != targetIndex - 1) {
            } else if (currentHubIndex != targetIndex) {
                if (currentHubIndex < targetIndex) {
                if (currentHubIndex < targetIndex) {
                    targetIndex--;
                    targetIndex--;
                }
                }
+3 −1
Original line number Original line Diff line number Diff line
@@ -85,6 +85,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationRowBin
import com.android.systemui.statusbar.notification.collection.NotificationRowBinderImpl;
import com.android.systemui.statusbar.notification.collection.NotificationRowBinderImpl;
import com.android.systemui.statusbar.notification.logging.NotifLog;
import com.android.systemui.statusbar.notification.logging.NotifLog;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.row.RowInflaterTask;
import com.android.systemui.statusbar.notification.row.RowInflaterTask;
@@ -228,7 +229,8 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
                        mHeadsUpManager,
                        mHeadsUpManager,
                        mock(NotificationFilter.class),
                        mock(NotificationFilter.class),
                        mNotifLog,
                        mNotifLog,
                        mock(NotificationSectionsFeatureManager.class)),
                        mock(NotificationSectionsFeatureManager.class),
                        mock(PeopleNotificationIdentifier.class)),
                mEnvironment
                mEnvironment
        );
        );
        Dependency.get(InitController.class).executePostInitTasks();
        Dependency.get(InitController.class).executePostInitTasks();
+27 −52
Original line number Original line Diff line number Diff line
@@ -20,7 +20,6 @@ import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationChannel
import android.app.NotificationManager.IMPORTANCE_DEFAULT
import android.app.NotificationManager.IMPORTANCE_DEFAULT
import android.app.NotificationManager.IMPORTANCE_LOW
import android.app.NotificationManager.IMPORTANCE_LOW
import android.app.Person
import android.service.notification.NotificationListenerService.RankingMap
import android.service.notification.NotificationListenerService.RankingMap
import android.service.notification.StatusBarNotification
import android.service.notification.StatusBarNotification
import android.testing.AndroidTestingRunner
import android.testing.AndroidTestingRunner
@@ -36,6 +35,7 @@ import com.android.systemui.statusbar.NotificationMediaManager
import com.android.systemui.statusbar.notification.NotificationFilter
import com.android.systemui.statusbar.notification.NotificationFilter
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
import com.android.systemui.statusbar.notification.logging.NotifLog
import com.android.systemui.statusbar.notification.logging.NotifLog
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_ALERTING
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.notification.stack.NotificationSectionsManager.BUCKET_SILENT
import com.android.systemui.statusbar.phone.NotificationGroupManager
import com.android.systemui.statusbar.phone.NotificationGroupManager
@@ -52,62 +52,41 @@ import org.mockito.Mockito.mock


@SmallTest
@SmallTest
@RunWith(AndroidTestingRunner::class)
@RunWith(AndroidTestingRunner::class)
class NotificationRankingManagerTest
class NotificationRankingManagerTest : SysuiTestCase() {
    : SysuiTestCase() {


    private var lazyMedia: Lazy<NotificationMediaManager> = Lazy {
    private val lazyMedia: Lazy<NotificationMediaManager> = Lazy {
        mock<NotificationMediaManager>(NotificationMediaManager::class.java)
        mock(NotificationMediaManager::class.java)
    }
    }

    private lateinit var personNotificationIdentifier: PeopleNotificationIdentifier
    private val rankingManager = TestableNotificationRankingManager(
    private lateinit var rankingManager: TestableNotificationRankingManager
            lazyMedia,
            mock<NotificationGroupManager>(NotificationGroupManager::class.java),
            mock<HeadsUpManager>(HeadsUpManager::class.java),
            mock<NotificationFilter>(NotificationFilter::class.java),
            mock<NotifLog>(NotifLog::class.java),
            mock<NotificationSectionsFeatureManager>(NotificationSectionsFeatureManager::class.java)
    )


    @Before
    @Before
    fun setup() {
    fun setup() {
        personNotificationIdentifier =
                mock(PeopleNotificationIdentifier::class.java)
        rankingManager = TestableNotificationRankingManager(
                lazyMedia,
                mock(NotificationGroupManager::class.java),
                mock(HeadsUpManager::class.java),
                mock(NotificationFilter::class.java),
                mock(NotifLog::class.java),
                mock(NotificationSectionsFeatureManager::class.java),
                personNotificationIdentifier
        )
    }
    }


    @Test
    @Test
    fun testPeopleNotification_isHighPriority() {
    fun testPeopleNotification_isHighPriority() {
        val person = Person.Builder()
                .setName("name")
                .setKey("abc")
                .setUri("uri")
                .setBot(true)
                .build()

        val notification = Notification.Builder(mContext, "test")
        val notification = Notification.Builder(mContext, "test")
                .addPerson(person)
                .build()
                .build()


        val sbn = StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0,
        val sbn = StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0,
                notification, mContext.user, "", 0)
                notification, mContext.user, "", 0)


        val e = NotificationEntryBuilder()
        `when`(personNotificationIdentifier.isPeopleNotification(sbn)).thenReturn(true)
                .setNotification(notification)
                .setSbn(sbn)
                .build()

        assertTrue(rankingManager.isHighPriority2(e))
    }

    @Test
    fun messagingStyleHighPriority() {

        val notif = Notification.Builder(mContext, "test")
                .setStyle(Notification.MessagingStyle(""))
                .build()

        val sbn = StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0,
                notif, mContext.getUser(), "", 0)


        val e = NotificationEntryBuilder()
        val e = NotificationEntryBuilder()
                .setNotification(notif)
                .setNotification(notification)
                .setSbn(sbn)
                .setSbn(sbn)
                .build()
                .build()


@@ -117,7 +96,7 @@ class NotificationRankingManagerTest
    @Test
    @Test
    fun lowForegroundHighPriority() {
    fun lowForegroundHighPriority() {
        val notification = mock(Notification::class.java)
        val notification = mock(Notification::class.java)
        `when`<Boolean>(notification.isForegroundService).thenReturn(true)
        `when`(notification.isForegroundService).thenReturn(true)


        val sbn = StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0,
        val sbn = StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0,
                notification, mContext.user, "", 0)
                notification, mContext.user, "", 0)
@@ -136,15 +115,7 @@ class NotificationRankingManagerTest


    @Test
    @Test
    fun userChangeTrumpsHighPriorityCharacteristics() {
    fun userChangeTrumpsHighPriorityCharacteristics() {
        val person = Person.Builder()
                .setName("name")
                .setKey("abc")
                .setUri("uri")
                .setBot(true)
                .build()

        val notification = Notification.Builder(mContext, "test")
        val notification = Notification.Builder(mContext, "test")
                .addPerson(person)
                .setStyle(Notification.MessagingStyle(""))
                .setStyle(Notification.MessagingStyle(""))
                .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true)
                .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true)
                .build()
                .build()
@@ -152,6 +123,8 @@ class NotificationRankingManagerTest
        val sbn = StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0,
        val sbn = StatusBarNotification("pkg", "pkg", 0, "tag", 0, 0,
                notification, mContext.user, "", 0)
                notification, mContext.user, "", 0)


        `when`(personNotificationIdentifier.isPeopleNotification(sbn)).thenReturn(true)

        val channel = NotificationChannel("a", "a", IMPORTANCE_LOW)
        val channel = NotificationChannel("a", "a", IMPORTANCE_LOW)
        channel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE)
        channel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE)


@@ -297,14 +270,16 @@ class NotificationRankingManagerTest
        headsUpManager: HeadsUpManager,
        headsUpManager: HeadsUpManager,
        filter: NotificationFilter,
        filter: NotificationFilter,
        notifLog: NotifLog,
        notifLog: NotifLog,
        sectionsFeatureManager: NotificationSectionsFeatureManager
        sectionsFeatureManager: NotificationSectionsFeatureManager,
        peopleNotificationIdentifier: PeopleNotificationIdentifier
    ) : NotificationRankingManager(
    ) : NotificationRankingManager(
        mediaManager,
        mediaManager,
        groupManager,
        groupManager,
        headsUpManager,
        headsUpManager,
        filter,
        filter,
        notifLog,
        notifLog,
        sectionsFeatureManager
        sectionsFeatureManager,
        peopleNotificationIdentifier
    ) {
    ) {


        fun isHighPriority2(e: NotificationEntry): Boolean {
        fun isHighPriority2(e: NotificationEntry): Boolean {
+3 −1
Original line number Original line Diff line number Diff line
@@ -74,6 +74,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationRankingManager;
import com.android.systemui.statusbar.notification.collection.NotificationRankingManager;
import com.android.systemui.statusbar.notification.logging.NotifLog;
import com.android.systemui.statusbar.notification.logging.NotifLog;
import com.android.systemui.statusbar.notification.people.PeopleHubSectionFooterViewAdapter;
import com.android.systemui.statusbar.notification.people.PeopleHubSectionFooterViewAdapter;
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.FooterView;
import com.android.systemui.statusbar.notification.row.FooterView;
import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager;
import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager;
@@ -164,7 +165,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
                        mHeadsUpManager,
                        mHeadsUpManager,
                        mock(NotificationFilter.class),
                        mock(NotificationFilter.class),
                        mock(NotifLog.class),
                        mock(NotifLog.class),
                        mock(NotificationSectionsFeatureManager.class)
                        mock(NotificationSectionsFeatureManager.class),
                        mock(PeopleNotificationIdentifier.class)
                ),
                ),
                mock(NotificationEntryManager.KeyguardEnvironment.class));
                mock(NotificationEntryManager.KeyguardEnvironment.class));
        mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager);
        mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager);