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

Commit 0c74c972 authored by Caitlin Shkuratov's avatar Caitlin Shkuratov
Browse files

[Notif] Auto-promote notifications ealier in the pipeline.

The existing PromotedNotificationsProvider class that automatically
promotes certain notifications for testing purposes is only triggered at
the end of the notification pipeline, after rendering has finished. This
works for the status bar chips, but doesn't work for other notification
promotion features like higher ranking.

This CL re-works PromotedNotificationsProvider to:
1) Happen earlier in the notif pipeline so it can be used by other
   promotion features
2) Changes how notifications are marked as auto-promoted. In this CL,
   FLAG_PROMOTED_ONGOING is set to true so that all other parts of the
   pipeline can just check `Notification.isPromotedOngoing()` and they
   don't need to worry about whether a notification was promoted via the
   standard criteria or automatically promoted.

It also renames the provider + associated classes to
AutomaticPromotionCoordinator.

Bug: 364653005
Flag: com.android.systemui.promote_notifications_automatically
Test: Send a notification that should be auto promoted -> verify it gets
promoted and has a status bar chip

Change-Id: I159f44d6f56fbfbeb48a1a002df338c0c6742d26
parent a3f96c47
Loading
Loading
Loading
Loading
+5 −6
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.app.Notification
import android.app.Notification.BigPictureStyle
import android.app.Notification.BigTextStyle
import android.app.Notification.CallStyle
import android.app.Notification.FLAG_PROMOTED_ONGOING
import android.app.Notification.MessagingStyle
import android.app.Notification.ProgressStyle
import android.app.Notification.ProgressStyle.Segment
@@ -46,9 +47,6 @@ import org.junit.runner.RunWith
class PromotedNotificationContentExtractorImplTest : SysuiTestCase() {
    private val kosmos = testKosmos()

    private val provider =
        FakePromotedNotificationsProvider().also { kosmos.promotedNotificationsProvider = it }

    private val underTest = kosmos.promotedNotificationContentExtractor

    @Test
@@ -87,7 +85,7 @@ class PromotedNotificationContentExtractorImplTest : SysuiTestCase() {

    @Test
    @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
    fun shouldNotExtract_providerDidNotPromote() {
    fun shouldNotExtract_becauseNotPromoted() {
        val entry = createEntry(promoted = false)
        val content = extractContent(entry)
        assertThat(content).isNull()
@@ -231,9 +229,10 @@ class PromotedNotificationContentExtractorImplTest : SysuiTestCase() {
        builderBlock: Notification.Builder.() -> Unit = {},
    ): NotificationEntry {
        val notif = Notification.Builder(context, "channel").also(builderBlock).build()
        return NotificationEntryBuilder().setNotification(notif).build().also {
            provider.shouldPromoteForEntry[it] = promoted
        if (promoted) {
            notif.flags = FLAG_PROMOTED_ONGOING
        }
        return NotificationEntryBuilder().setNotification(notif).build()
    }

    companion object {
+0 −69
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.promoted

import android.app.Notification
import android.app.Notification.FLAG_PROMOTED_ONGOING
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test

@SmallTest
class PromotedNotificationsProviderTest : SysuiTestCase() {
    private val kosmos = testKosmos()

    private val underTest = kosmos.promotedNotificationsProvider

    @Test
    @DisableFlags(PromotedNotificationUi.FLAG_NAME)
    fun shouldPromote_uiFlagOff_false() {
        val entry = createNotification(FLAG_PROMOTED_ONGOING)

        assertThat(underTest.shouldPromote(entry)).isFalse()
    }

    @Test
    @EnableFlags(PromotedNotificationUi.FLAG_NAME)
    fun shouldPromote_uiFlagOn_notifDoesNotHaveFlag_false() {
        val entry = createNotification(flag = null)

        assertThat(underTest.shouldPromote(entry)).isFalse()
    }

    @Test
    @EnableFlags(PromotedNotificationUi.FLAG_NAME)
    fun shouldPromote_uiFlagOn_notifHasFlag_true() {
        val entry = createNotification(FLAG_PROMOTED_ONGOING)

        assertThat(underTest.shouldPromote(entry)).isTrue()
    }

    private fun createNotification(flag: Int? = null): NotificationEntry {
        val n = Notification.Builder(context, "a")
        if (flag != null) {
            n.setFlag(flag, true)
        }

        return NotificationEntryBuilder().setNotification(n.build()).build()
    }
}
+3 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import com.android.systemui.statusbar.notification.collection.SortBySectionTimeF
import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner
import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider
import com.android.systemui.statusbar.notification.promoted.AutomaticPromotionCoordinator
import com.android.systemui.statusbar.notification.shared.NotificationMinimalism
import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataStoreRefactor
import com.android.systemui.statusbar.notification.shared.PriorityPeopleSection
@@ -69,6 +70,7 @@ constructor(
    dismissibilityCoordinator: DismissibilityCoordinator,
    statsLoggerCoordinator: NotificationStatsLoggerCoordinator,
    bundleCoordinator: BundleCoordinator,
    automaticPromotionCoordinator: AutomaticPromotionCoordinator,
) : NotifCoordinators {

    private val mCoreCoordinators: MutableList<CoreCoordinator> = ArrayList()
@@ -110,6 +112,7 @@ constructor(
        mCoordinators.add(preparationCoordinator)
        mCoordinators.add(remoteInputCoordinator)
        mCoordinators.add(dismissibilityCoordinator)
        mCoordinators.add(automaticPromotionCoordinator)

        if (NotificationsLiveDataStoreRefactor.isEnabled) {
            mCoordinators.add(statsLoggerCoordinator)
+7 −9
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.statusbar.notification.collection.coordinator.NotifCoordinators
import com.android.systemui.statusbar.notification.collection.coordinator.NotifCoordinatorsImpl
import com.android.systemui.statusbar.notification.collection.coordinator.SensitiveContentCoordinatorModule
import com.android.systemui.statusbar.notification.promoted.ReferenceAutomaticPromotionModule
import dagger.Binds
import dagger.Module
import dagger.Provides
@@ -28,7 +29,7 @@ import javax.inject.Qualifier
import javax.inject.Scope

@Module(subcomponents = [CoordinatorsSubcomponent::class])
object CoordinatorsModule {
object ReferenceCoordinatorsModule {
    @SysUISingleton
    @JvmStatic
    @Provides
@@ -47,9 +48,9 @@ interface CoordinatorsSubcomponent {
    }
}

@Module(includes = [
    SensitiveContentCoordinatorModule::class,
])
@Module(
    includes = [SensitiveContentCoordinatorModule::class, ReferenceAutomaticPromotionModule::class]
)
abstract class InternalCoordinatorsModule {
    @Binds
    @Internal
@@ -61,7 +62,4 @@ abstract class InternalCoordinatorsModule {
@Retention(AnnotationRetention.RUNTIME)
private annotation class Internal

@Scope
@MustBeDocumented
@Retention(AnnotationRetention.RUNTIME)
annotation class CoordinatorScope
@Scope @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class CoordinatorScope
+0 −2
Original line number Diff line number Diff line
@@ -41,7 +41,6 @@ import com.android.systemui.statusbar.notification.collection.NotifLiveDataStore
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotifPipelineChoreographerModule;
import com.android.systemui.statusbar.notification.collection.coordinator.ShadeEventCoordinator;
import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorsModule;
import com.android.systemui.statusbar.notification.collection.inflation.BindEventManager;
import com.android.systemui.statusbar.notification.collection.inflation.BindEventManagerImpl;
import com.android.systemui.statusbar.notification.collection.inflation.NotifInflater;
@@ -110,7 +109,6 @@ import javax.inject.Provider;
 * Dagger Module for classes found within the com.android.systemui.statusbar.notification package.
 */
@Module(includes = {
        CoordinatorsModule.class,
        FooterViewModelModule.class,
        KeyguardNotificationVisibilityProviderModule.class,
        NotificationDataLayerModule.class,
Loading