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

Commit e7a7053c authored by Yining Liu's avatar Yining Liu
Browse files

Fix minimalism feature not responding to settings change

Fix the bug when we change the secure settings value through settings
app or command line, the minimalism feature does not respond to the
setting change.

Fix: 377546277
Bug: 354047572
Flag: com.android.server.notification.notification_minimalism
Test: adb shell settings secure put lock_screen_notification_minimalism
 \<1|0>
Change-Id: I6d46c7a069c3f3ce5aa0e01723df177d8225aa7b
parent 0a09b507
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -23,14 +23,17 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.res.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.kosmos.testScope
import com.android.systemui.media.controls.domain.pipeline.MediaDataManager
import com.android.systemui.statusbar.LockscreenShadeTransitionController
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.domain.interactor.SeenNotificationsInteractor
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.ExpandableView
import com.android.systemui.statusbar.policy.ResourcesSplitShadeStateController
import com.android.systemui.testKosmos
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.nullable
@@ -52,8 +55,11 @@ class NotificationStackSizeCalculatorTest : SysuiTestCase() {
    private lateinit var lockscreenShadeTransitionController: LockscreenShadeTransitionController
    @Mock private lateinit var mediaDataManager: MediaDataManager
    @Mock private lateinit var stackLayout: NotificationStackScrollLayout
    @Mock private lateinit var seenNotificationsInteractor: SeenNotificationsInteractor

    private val testableResources = mContext.orCreateTestableResources
    private val kosmos = testKosmos()
    private val testScope = kosmos.testScope

    private lateinit var sizeCalculator: NotificationStackSizeCalculator

@@ -72,7 +78,9 @@ class NotificationStackSizeCalculatorTest : SysuiTestCase() {
                lockscreenShadeTransitionController = lockscreenShadeTransitionController,
                mediaDataManager = mediaDataManager,
                testableResources.resources,
                    ResourcesSplitShadeStateController()
                ResourcesSplitShadeStateController(),
                seenNotificationsInteractor = seenNotificationsInteractor,
                scope = kosmos.testScope,
            )
    }

+13 −10
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.notification.collection.coordinator
import android.annotation.SuppressLint
import android.app.NotificationManager
import androidx.annotation.VisibleForTesting
import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.Dumpable
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dump.DumpManager
@@ -50,7 +51,6 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import com.android.app.tracing.coroutines.launchTraced as launch

/**
 * If the setting is enabled, this will track seen notifications and ensure that they only show in
@@ -74,7 +74,7 @@ constructor(

    private val unseenNotifications = mutableSetOf<NotificationEntry>()
    private var isShadeVisible = false
    private var unseenFilterEnabled = false
    private var minimalismEnabled = false

    override fun attach(pipeline: NotifPipeline) {
        if (NotificationMinimalism.isUnexpectedlyInLegacyMode()) {
@@ -83,7 +83,7 @@ constructor(
        pipeline.addPromoter(unseenNotifPromoter)
        pipeline.addOnBeforeTransformGroupsListener(::pickOutTopUnseenNotifs)
        pipeline.addCollectionListener(collectionListener)
        scope.launch { trackUnseenFilterSettingChanges() }
        scope.launch { trackLockScreenNotificationMinimalismSettingChanges() }
        dumpManager.registerDumpable(this)
    }

@@ -136,12 +136,12 @@ constructor(
        return seenNotificationsInteractor.isLockScreenNotificationMinimalismEnabled()
    }

    private suspend fun trackUnseenFilterSettingChanges() {
    private suspend fun trackLockScreenNotificationMinimalismSettingChanges() {
        // Only filter the seen notifs when the lock screen minimalism feature settings is on.
        minimalismFeatureSettingEnabled().collectLatest { isMinimalismSettingEnabled ->
            // update local field and invalidate if necessary
            if (isMinimalismSettingEnabled != unseenFilterEnabled) {
                unseenFilterEnabled = isMinimalismSettingEnabled
            if (isMinimalismSettingEnabled != minimalismEnabled) {
                minimalismEnabled = isMinimalismSettingEnabled
                unseenNotifications.clear()
                unseenNotifPromoter.invalidateList("unseen setting changed")
            }
@@ -156,21 +156,21 @@ constructor(
    private val collectionListener =
        object : NotifCollectionListener {
            override fun onEntryAdded(entry: NotificationEntry) {
                if (unseenFilterEnabled && !isShadeVisible) {
                if (minimalismEnabled && !isShadeVisible) {
                    logger.logUnseenAdded(entry.key)
                    unseenNotifications.add(entry)
                }
            }

            override fun onEntryUpdated(entry: NotificationEntry) {
                if (unseenFilterEnabled && !isShadeVisible) {
                if (minimalismEnabled && !isShadeVisible) {
                    logger.logUnseenUpdated(entry.key)
                    unseenNotifications.add(entry)
                }
            }

            override fun onEntryRemoved(entry: NotificationEntry, reason: Int) {
                if (unseenFilterEnabled && unseenNotifications.remove(entry)) {
                if (minimalismEnabled && unseenNotifications.remove(entry)) {
                    logger.logUnseenRemoved(entry.key)
                }
            }
@@ -178,7 +178,7 @@ constructor(

    private fun pickOutTopUnseenNotifs(list: List<ListEntry>) {
        if (NotificationMinimalism.isUnexpectedlyInLegacyMode()) return
        if (!unseenFilterEnabled) return
        if (!minimalismEnabled) return
        // Only ever elevate a top unseen notification on keyguard, not even locked shade
        if (statusBarStateController.state != StatusBarState.KEYGUARD) {
            seenNotificationsInteractor.setTopOngoingNotification(null)
@@ -215,6 +215,7 @@ constructor(
            override fun shouldPromoteToTopLevel(child: NotificationEntry): Boolean =
                when {
                    NotificationMinimalism.isUnexpectedlyInLegacyMode() -> false
                    !minimalismEnabled -> false
                    seenNotificationsInteractor.isTopOngoingNotification(child) -> true
                    !NotificationMinimalism.ungroupTopUnseen -> false
                    else -> seenNotificationsInteractor.isTopUnseenNotification(child)
@@ -225,6 +226,7 @@ constructor(
        object : NotifSectioner("TopOngoing", BUCKET_TOP_ONGOING) {
            override fun isInSection(entry: ListEntry): Boolean {
                if (NotificationMinimalism.isUnexpectedlyInLegacyMode()) return false
                if (!minimalismEnabled) return false
                return entry.anyEntry { notificationEntry ->
                    seenNotificationsInteractor.isTopOngoingNotification(notificationEntry)
                }
@@ -235,6 +237,7 @@ constructor(
        object : NotifSectioner("TopUnseen", BUCKET_TOP_UNSEEN) {
            override fun isInSection(entry: ListEntry): Boolean {
                if (NotificationMinimalism.isUnexpectedlyInLegacyMode()) return false
                if (!minimalismEnabled) return false
                return entry.anyEntry { notificationEntry ->
                    seenNotificationsInteractor.isTopUnseenNotification(notificationEntry)
                }
+33 −3
Original line number Diff line number Diff line
@@ -21,18 +21,25 @@ import android.util.Log
import android.view.View.GONE
import androidx.annotation.VisibleForTesting
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.media.controls.domain.pipeline.MediaDataManager
import com.android.systemui.res.R
import com.android.systemui.statusbar.LockscreenShadeTransitionController
import com.android.systemui.statusbar.StatusBarState.KEYGUARD
import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.notification.domain.interactor.SeenNotificationsInteractor
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.ExpandableView
import com.android.systemui.statusbar.notification.shared.NotificationMinimalism
import com.android.systemui.statusbar.policy.SplitShadeStateController
import com.android.systemui.util.Compile
import com.android.systemui.util.children
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.launch
import java.io.PrintWriter
import javax.inject.Inject
import kotlin.math.max
@@ -56,7 +63,9 @@ constructor(
    private val lockscreenShadeTransitionController: LockscreenShadeTransitionController,
    private val mediaDataManager: MediaDataManager,
    @Main private val resources: Resources,
    private val splitShadeStateController: SplitShadeStateController
    private val splitShadeStateController: SplitShadeStateController,
    private val seenNotificationsInteractor: SeenNotificationsInteractor,
    @Application private val scope: CoroutineScope,
) {

    /**
@@ -74,7 +83,7 @@ constructor(

    /** Whether we allow keyguard to show less important notifications above the shelf. */
    private val limitLockScreenToOneImportant
        get() = NotificationMinimalism.isEnabled
        get() = NotificationMinimalism.isEnabled && minimalismSettingEnabled

    /** Minimum space between two notifications, see [calculateGapAndDividerHeight]. */
    private var dividerHeight by notNull<Float>()
@@ -85,8 +94,16 @@ constructor(
     */
    private var saveSpaceOnLockscreen = false

    /**
     * True when the lock screen notification minimalism feature setting is enabled
     */
    private var minimalismSettingEnabled = false

    init {
        updateResources()
        if (NotificationMinimalism.isEnabled) {
            scope.launch { trackLockScreenNotificationMinimalismSettingChanges() }
        }
    }

    private fun allowedByPolicy(stackHeight: StackHeight): Boolean =
@@ -338,6 +355,16 @@ constructor(
        val shouldForceIntoShelf: Boolean
    )

    private suspend fun trackLockScreenNotificationMinimalismSettingChanges() {
        if (NotificationMinimalism.isUnexpectedlyInLegacyMode()) return
        seenNotificationsInteractor.isLockScreenNotificationMinimalismEnabled().collectLatest {
            if (it != minimalismSettingEnabled) {
                minimalismSettingEnabled = it
            }
            Log.i(TAG, "minimalismSettingEnabled: $minimalismSettingEnabled")
        }
    }

    private fun computeHeightPerNotificationLimit(
        stack: NotificationStackScrollLayout,
        shelfHeight: Float,
@@ -390,7 +417,8 @@ constructor(
            log {
                "\tcomputeHeightPerNotificationLimit i=$i notifs=$notifications " +
                    "notifsHeightSavingSpace=$notifsWithCollapsedHun" +
                    " shelfWithSpaceBefore=$shelfWithSpaceBefore"
                    " shelfWithSpaceBefore=$shelfWithSpaceBefore" +
                    " limitLockScreenToOneImportant: $limitLockScreenToOneImportant"
            }
            yield(
                StackHeight(
@@ -462,6 +490,8 @@ constructor(

    fun dump(pw: PrintWriter, args: Array<out String>) {
        pw.println("NotificationStackSizeCalculator saveSpaceOnLockscreen=$saveSpaceOnLockscreen")
        pw.println("NotificationStackSizeCalculator " +
                "limitLockScreenToOneImportant=$limitLockScreenToOneImportant")
    }

    private fun ExpandableView.isShowable(onLockscreen: Boolean): Boolean {