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

Commit d75e0179 authored by Julia Tuttle's avatar Julia Tuttle
Browse files

Refactor VisualInterruptionDecisionProviderImpl

I found a few ways to tighten up the new provider code, so... it's
refactorception.

In particular:

There are a couple bits of data we need to *log* a decision that we
don't need to *return* with it, so create a small data class to hold
that data alongside the decision itself.

Bug: 261728888
Test: atest NotificationInterruptStateProviderWrapperTest
Test: atest VisualInterruptionDecisionProviderImplTest
Flag: ACONFIG com.android.systemui.visual_interruptions_refactor DEVELOPMENT
Change-Id: Ibfd590bee4399fd5c22046bff62a23b31d17f779
parent 30ef17f2
Loading
Loading
Loading
Loading
+85 −105
Original line number Diff line number Diff line
@@ -58,6 +58,26 @@ constructor(
        override val logReason: String
    ) : Decision

    private data class LoggableDecision private constructor(val decision: DecisionImpl) {
        companion object {
            val unsuppressed =
                LoggableDecision(DecisionImpl(shouldInterrupt = true, logReason = "not suppressed"))

            fun suppressed(legacySuppressor: NotificationInterruptSuppressor, methodName: String) =
                LoggableDecision(
                    DecisionImpl(
                        shouldInterrupt = false,
                        logReason = "${legacySuppressor.name}.$methodName"
                    )
                )

            fun suppressed(suppressor: VisualInterruptionSuppressor) =
                LoggableDecision(
                    DecisionImpl(shouldInterrupt = false, logReason = suppressor.reason)
                )
        }
    }

    private class FullScreenIntentDecisionImpl(
        private val fsiDecision: FullScreenIntentDecisionProvider.Decision
    ) : FullScreenIntentDecision {
@@ -139,137 +159,97 @@ constructor(

    override fun makeUnloggedHeadsUpDecision(entry: NotificationEntry): Decision {
        check(started)
        return makeHeadsUpDecision(entry)
    }

    override fun makeAndLogHeadsUpDecision(entry: NotificationEntry): Decision {
        check(started)
        return makeHeadsUpDecision(entry).also { logHeadsUpDecision(entry, it) }
        return if (statusBarStateController.isDozing) {
                makeLoggablePulseDecision(entry)
            } else {
                makeLoggablePeekDecision(entry)
            }

    override fun makeAndLogBubbleDecision(entry: NotificationEntry): Decision {
        check(started)
        return makeBubbleDecision(entry).also { logBubbleDecision(entry, it) }
            .decision
    }

    override fun makeUnloggedFullScreenIntentDecision(
        entry: NotificationEntry
    ): FullScreenIntentDecision {
    override fun makeAndLogHeadsUpDecision(entry: NotificationEntry): Decision {
        check(started)
        return makeFullScreenIntentDecision(entry)
    }

    override fun logFullScreenIntentDecision(decision: FullScreenIntentDecision) {
        check(started)
        // Not yet implemented.
    }

    private fun makeHeadsUpDecision(entry: NotificationEntry): DecisionImpl {
        if (statusBarStateController.isDozing) {
            return makePulseDecision(entry)
        return if (statusBarStateController.isDozing) {
                makeLoggablePulseDecision(entry).also { logDecision(PULSE, entry, it) }
            } else {
            return makePeekDecision(entry)
                makeLoggablePeekDecision(entry).also { logDecision(PEEK, entry, it) }
            }
            .decision
    }

    private fun makePeekDecision(entry: NotificationEntry): DecisionImpl {
        checkConditions(PEEK)?.let {
            return DecisionImpl(shouldInterrupt = false, logReason = it.reason)
        }
        checkFilters(PEEK, entry)?.let {
            return DecisionImpl(shouldInterrupt = false, logReason = it.reason)
        }
        checkSuppressors(entry)?.let {
            return DecisionImpl(
                shouldInterrupt = false,
                logReason = "${it.name}.suppressInterruptions"
            )
        }
        checkAwakeSuppressors(entry)?.let {
            return DecisionImpl(
                shouldInterrupt = false,
                logReason = "${it.name}.suppressAwakeInterruptions"
            )
        }
        checkAwakeHeadsUpSuppressors(entry)?.let {
            return DecisionImpl(
                shouldInterrupt = false,
                logReason = "${it.name}.suppressAwakeHeadsUpInterruptions"
            )
        }
        return DecisionImpl(shouldInterrupt = true, logReason = "not suppressed")
    }
    private fun makeLoggablePeekDecision(entry: NotificationEntry): LoggableDecision =
        checkConditions(PEEK)
            ?: checkFilters(PEEK, entry) ?: checkSuppressInterruptions(entry)
                ?: checkSuppressAwakeInterruptions(entry) ?: checkSuppressAwakeHeadsUp(entry)
                ?: LoggableDecision.unsuppressed

    private fun makePulseDecision(entry: NotificationEntry): DecisionImpl {
        checkConditions(PULSE)?.let {
            return DecisionImpl(shouldInterrupt = false, logReason = it.reason)
        }
        checkFilters(PULSE, entry)?.let {
            return DecisionImpl(shouldInterrupt = false, logReason = it.reason)
        }
        checkSuppressors(entry)?.let {
            return DecisionImpl(
                shouldInterrupt = false,
                logReason = "${it.name}.suppressInterruptions"
            )
        }
        return DecisionImpl(shouldInterrupt = true, logReason = "not suppressed")
    }
    private fun makeLoggablePulseDecision(entry: NotificationEntry): LoggableDecision =
        checkConditions(PULSE)
            ?: checkFilters(PULSE, entry) ?: checkSuppressInterruptions(entry)
                ?: LoggableDecision.unsuppressed

    private fun makeBubbleDecision(entry: NotificationEntry): DecisionImpl {
        checkConditions(BUBBLE)?.let {
            return DecisionImpl(shouldInterrupt = false, logReason = it.reason)
        }
        checkFilters(BUBBLE, entry)?.let {
            return DecisionImpl(shouldInterrupt = false, logReason = it.reason)
        }
        checkSuppressors(entry)?.let {
            return DecisionImpl(
                shouldInterrupt = false,
                logReason = "${it.name}.suppressInterruptions"
            )
        }
        checkAwakeSuppressors(entry)?.let {
            return DecisionImpl(
                shouldInterrupt = false,
                logReason = "${it.name}.suppressAwakeInterruptions"
            )
        }
        return DecisionImpl(shouldInterrupt = true, logReason = "not suppressed")
    }
    override fun makeAndLogBubbleDecision(entry: NotificationEntry): Decision {
        check(started)

    private fun logHeadsUpDecision(entry: NotificationEntry, decision: DecisionImpl) {
        // Not yet implemented.
        return makeLoggableBubbleDecision(entry).also { logDecision(BUBBLE, entry, it) }.decision
    }

    private fun logBubbleDecision(entry: NotificationEntry, decision: DecisionImpl) {
    private fun makeLoggableBubbleDecision(entry: NotificationEntry): LoggableDecision =
        checkConditions(BUBBLE)
            ?: checkFilters(BUBBLE, entry) ?: checkSuppressInterruptions(entry)
                ?: checkSuppressAwakeInterruptions(entry) ?: LoggableDecision.unsuppressed

    private fun logDecision(
        type: VisualInterruptionType,
        entry: NotificationEntry,
        loggable: LoggableDecision
    ) {
        // Not yet implemented.
    }

    private fun makeFullScreenIntentDecision(entry: NotificationEntry): FullScreenIntentDecision {
        val wouldHeadsUp = makeUnloggedHeadsUpDecision(entry).shouldInterrupt
    override fun makeUnloggedFullScreenIntentDecision(
        entry: NotificationEntry
    ): FullScreenIntentDecision {
        check(started)

        val couldHeadsUp = makeUnloggedHeadsUpDecision(entry).shouldInterrupt
        val fsiDecision =
            fullScreenIntentDecisionProvider.makeFullScreenIntentDecision(entry, wouldHeadsUp)
            fullScreenIntentDecisionProvider.makeFullScreenIntentDecision(entry, couldHeadsUp)
        return FullScreenIntentDecisionImpl(fsiDecision)
    }

    private fun checkSuppressors(entry: NotificationEntry) =
        legacySuppressors.firstOrNull { it.suppressInterruptions(entry) }
    override fun logFullScreenIntentDecision(decision: FullScreenIntentDecision) {
        check(started)

        // Not yet implemented.
    }

    private fun checkAwakeSuppressors(entry: NotificationEntry) =
        legacySuppressors.firstOrNull { it.suppressAwakeInterruptions(entry) }
    private fun checkSuppressInterruptions(entry: NotificationEntry) =
        legacySuppressors
            .firstOrNull { it.suppressInterruptions(entry) }
            ?.let { LoggableDecision.suppressed(it, "suppressInterruptions") }

    private fun checkAwakeHeadsUpSuppressors(entry: NotificationEntry) =
        legacySuppressors.firstOrNull { it.suppressAwakeHeadsUp(entry) }
    private fun checkSuppressAwakeInterruptions(entry: NotificationEntry) =
        legacySuppressors
            .firstOrNull { it.suppressAwakeInterruptions(entry) }
            ?.let { LoggableDecision.suppressed(it, "suppressAwakeInterruptions") }

    private fun checkConditions(type: VisualInterruptionType): VisualInterruptionCondition? =
        conditions.firstOrNull { it.types.contains(type) && it.shouldSuppress() }
    private fun checkSuppressAwakeHeadsUp(entry: NotificationEntry) =
        legacySuppressors
            .firstOrNull { it.suppressAwakeHeadsUp(entry) }
            ?.let { LoggableDecision.suppressed(it, "suppressAwakeHeadsUp") }

    private fun checkFilters(
        type: VisualInterruptionType,
        entry: NotificationEntry
    ): VisualInterruptionFilter? =
        filters.firstOrNull { it.types.contains(type) && it.shouldSuppress(entry) }
    private fun checkConditions(type: VisualInterruptionType) =
        conditions
            .firstOrNull { it.types.contains(type) && it.shouldSuppress() }
            ?.let { LoggableDecision.suppressed(it) }

    private fun checkFilters(type: VisualInterruptionType, entry: NotificationEntry) =
        filters
            .firstOrNull { it.types.contains(type) && it.shouldSuppress(entry) }
            ?.let { LoggableDecision.suppressed(it) }
}

private const val TAG = "VisualInterruptionDecisionProviderImpl"