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

Commit f5f436be authored by Jeff DeCew's avatar Jeff DeCew
Browse files

Notification Minimalism Prototype

When the flag is enabled:
* Cap notifications on lock screen at 1, excluding the UMO
* Act as if LOCK_SCREEN_SHOW_ONLY_UNSEEN_NOTIFICATIONS is Enabled

Bug: 330387368
Test: atest SystemUITests
Flag: ACONFIG com.android.systemui.notification_minimalism_prototype DEVELOPMENT
Change-Id: Ibc47fd1858b62abcab557198ebaf5f2f4587bf11
parent aae2cb64
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -24,6 +24,16 @@ flag {
   }
}

flag {
   name: "notification_minimalism_prototype"
   namespace: "systemui"
   description: "Prototype of notification minimalism; the new 'Intermediate' lockscreen customization proposal."
   bug: "330387368"
   metadata {
        purpose: PURPOSE_BUGFIX
   }
}

flag {
   name: "notification_view_flipper_pausing"
   namespace: "systemui"
+20 −12
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.os.UserHandle
import android.provider.Settings
import androidx.annotation.VisibleForTesting
import com.android.systemui.Dumpable
import com.android.systemui.Flags.notificationMinimalismPrototype
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dump.DumpManager
@@ -59,6 +60,7 @@ import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
@@ -260,8 +262,11 @@ constructor(
        }
    }

    private suspend fun trackUnseenFilterSettingChanges() {
        secureSettings
    private fun unseenFeatureEnabled(): Flow<Boolean> {
        if (notificationMinimalismPrototype()) {
            return flowOf(true)
        }
        return secureSettings
            // emit whenever the setting has changed
            .observerFlow(
                UserHandle.USER_ALL,
@@ -283,7 +288,10 @@ constructor(
            // only track the most recent emission, if events are happening faster than they can be
            // consumed
            .conflate()
            .collectLatest { setting ->
    }

    private suspend fun trackUnseenFilterSettingChanges() {
        unseenFeatureEnabled().collectLatest { setting ->
            // update local field and invalidate if necessary
            if (setting != unseenFilterEnabled) {
                unseenFilterEnabled = setting
+26 −7
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.content.res.Resources
import android.util.Log
import android.view.View.GONE
import androidx.annotation.VisibleForTesting
import com.android.systemui.Flags.notificationMinimalismPrototype
import com.android.systemui.res.R
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
@@ -66,6 +67,11 @@ constructor(
     */
    private var maxKeyguardNotifications by notNull<Int>()

    /**
     * Whether [maxKeyguardNotifications] will have 1 added to it when media is shown in the stack.
     */
    private var maxNotificationsExcludesMedia = false

    /** Minimum space between two notifications, see [calculateGapAndDividerHeight]. */
    private var dividerHeight by notNull<Float>()

@@ -168,7 +174,11 @@ constructor(
        log { "\n" }

        val stackHeightSequence = computeHeightPerNotificationLimit(stack, shelfHeight)

        // TODO: Avoid making this split shade assumption by simply checking the stack for media
        val isMediaShowing = mediaDataManager.hasActiveMediaOrRecommendation()
        val isMediaShowingInStack = isMediaShowing && !splitShadeStateController
                .shouldUseSplitNotificationShade(resources)

        log { "\tGet maxNotifWithoutSavingSpace ---" }
        val maxNotifWithoutSavingSpace =
@@ -181,12 +191,11 @@ constructor(
            }

        // How many notifications we can show at heightWithoutLockscreenConstraints
        var minCountAtHeightWithoutConstraints =
            if (isMediaShowing && !splitShadeStateController
                    .shouldUseSplitNotificationShade(resources)) 2 else 1
        val minCountAtHeightWithoutConstraints = if (isMediaShowingInStack) 2 else 1
        log {
            "\t---maxNotifWithoutSavingSpace=$maxNotifWithoutSavingSpace " +
                "isMediaShowing=$isMediaShowing" +
                "isMediaShowingInStack=$isMediaShowingInStack" +
                "minCountAtHeightWithoutConstraints=$minCountAtHeightWithoutConstraints"
        }
        log { "\n" }
@@ -223,7 +232,9 @@ constructor(
        }

        if (onLockscreen()) {
            maxNotifications = min(maxKeyguardNotifications, maxNotifications)
            val increaseMaxForMedia = maxNotificationsExcludesMedia && isMediaShowingInStack
            val lockscreenMax = maxKeyguardNotifications.safeIncrementIf(increaseMaxForMedia)
            maxNotifications = min(lockscreenMax, maxNotifications)
        }

        // Could be < 0 if the space available is less than the shelf size. Returns 0 in this case.
@@ -276,7 +287,7 @@ constructor(
            height = notifsHeight + shelfHeightWithSpaceBefore
            log {
                "--- computeHeight(maxNotifs=$maxNotifs, shelfHeight=$shelfHeight)" +
                    " -> ${height}=($notifsHeight+$shelfHeightWithSpaceBefore)" +
                    " -> $height=($notifsHeight+$shelfHeightWithSpaceBefore)" +
                    " | saveSpaceOnLockscreen=$saveSpaceOnLockscreen"
            }
        }
@@ -367,8 +378,9 @@ constructor(
    }

    fun updateResources() {
        maxKeyguardNotifications =
            infiniteIfNegative(resources.getInteger(R.integer.keyguard_max_notification_count))
        maxKeyguardNotifications = if (notificationMinimalismPrototype()) 1
            else infiniteIfNegative(resources.getInteger(R.integer.keyguard_max_notification_count))
        maxNotificationsExcludesMedia = notificationMinimalismPrototype()

        dividerHeight =
            max(1f, resources.getDimensionPixelSize(R.dimen.notification_divider_height).toFloat())
@@ -486,6 +498,13 @@ constructor(
            v
        }

    private fun Int.safeIncrementIf(condition: Boolean): Int =
        if (condition && this != Int.MAX_VALUE) {
            this + 1
        } else {
            this
        }

    /** Returns the last index where [predicate] returns true, or -1 if it was always false. */
    private fun <T> Sequence<T>.lastIndexWhile(predicate: (T) -> Boolean): Int =
        takeWhile(predicate).count() - 1