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

Commit 6e0acefd authored by Julia Tuttle's avatar Julia Tuttle
Browse files

Wrap NotificationInterruptStateProvider

NotificationInterruptStateProvider is being refactored into
VisualInterruptionDecisionProvider. This wrapper will let us use the old
or new class based on a flag before we commit to the new class.

Bug: 261728888
Test: atest NotificationInterruptStateProviderWrapper
Test: # plus future callers' unit tests
Change-Id: I2ffa4b57af9eaeb5ce61ca8ef7ad0fabb792043c
parent 81805ecd
Loading
Loading
Loading
Loading
+73 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.interruption

import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider.FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND
import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider.Decision
import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider.FullScreenIntentDecision

/**
 * Wraps a [NotificationInterruptStateProvider] to convert it to the new
 * [VisualInterruptionDecisionProvider] interface.
 */
class NotificationInterruptStateProviderWrapper(
    private val wrapped: NotificationInterruptStateProvider
) : VisualInterruptionDecisionProvider {

    @VisibleForTesting
    enum class DecisionImpl(override val shouldInterrupt: Boolean) : Decision {
        SHOULD_INTERRUPT(shouldInterrupt = true),
        SHOULD_NOT_INTERRUPT(shouldInterrupt = false);

        companion object {
            fun of(booleanDecision: Boolean) =
                if (booleanDecision) SHOULD_INTERRUPT else SHOULD_NOT_INTERRUPT
        }
    }

    @VisibleForTesting
    class FullScreenIntentDecisionImpl(
        val originalEntry: NotificationEntry,
        val originalDecision: NotificationInterruptStateProvider.FullScreenIntentDecision
    ) : FullScreenIntentDecision {
        override val shouldInterrupt = originalDecision.shouldLaunch
        override val wouldInterruptWithoutDnd = originalDecision == NO_FSI_SUPPRESSED_ONLY_BY_DND
    }

    override fun addSuppressor(suppressor: NotificationInterruptSuppressor) {
        wrapped.addSuppressor(suppressor)
    }

    override fun makeUnloggedHeadsUpDecision(entry: NotificationEntry): Decision =
        wrapped.checkHeadsUp(entry, /* log= */ false).let { DecisionImpl.of(it) }

    override fun makeAndLogHeadsUpDecision(entry: NotificationEntry): Decision =
        wrapped.checkHeadsUp(entry, /* log= */ true).let { DecisionImpl.of(it) }

    override fun makeUnloggedFullScreenIntentDecision(entry: NotificationEntry) =
        wrapped.getFullScreenIntentDecision(entry).let { FullScreenIntentDecisionImpl(entry, it) }

    override fun logFullScreenIntentDecision(decision: FullScreenIntentDecision) {
        (decision as FullScreenIntentDecisionImpl).let {
            wrapped.logFullScreenIntentDecision(it.originalEntry, it.originalDecision)
        }
    }

    override fun makeAndLogBubbleDecision(entry: NotificationEntry): Decision =
        wrapped.shouldBubbleUp(entry).let { DecisionImpl.of(it) }
}
+78 −0
Original line number Diff line number Diff line
package com.android.systemui.statusbar.notification.interruption

import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider.FullScreenIntentDecision
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider.FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider.FullScreenIntentDecision.NO_FSI_NOT_IMPORTANT_ENOUGH
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider.FullScreenIntentDecision.NO_FSI_SUPPRESSED_BY_DND
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider.FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderWrapper.DecisionImpl
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderWrapper.FullScreenIntentDecisionImpl
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith

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

    @Test
    fun decisionOfTrue() {
        assertTrue(DecisionImpl.of(true).shouldInterrupt)
    }

    @Test
    fun decisionOfFalse() {
        assertFalse(DecisionImpl.of(false).shouldInterrupt)
    }

    @Test
    fun decisionOfTrueInterned() {
        assertEquals(DecisionImpl.of(true), DecisionImpl.of(true))
    }

    @Test
    fun decisionOfFalseInterned() {
        assertEquals(DecisionImpl.of(false), DecisionImpl.of(false))
    }

    @Test
    fun fullScreenIntentDecisionShouldInterrupt() {
        makeFsiDecision(FSI_DEVICE_NOT_INTERACTIVE).let {
            assertTrue(it.shouldInterrupt)
            assertFalse(it.wouldInterruptWithoutDnd)
        }
    }

    @Test
    fun fullScreenIntentDecisionShouldNotInterrupt() {
        makeFsiDecision(NO_FSI_NOT_IMPORTANT_ENOUGH).let {
            assertFalse(it.shouldInterrupt)
            assertFalse(it.wouldInterruptWithoutDnd)
        }
    }

    @Test
    fun fullScreenIntentDecisionWouldInterruptWithoutDnd() {
        makeFsiDecision(NO_FSI_SUPPRESSED_ONLY_BY_DND).let {
            assertFalse(it.shouldInterrupt)
            assertTrue(it.wouldInterruptWithoutDnd)
        }
    }

    @Test
    fun fullScreenIntentDecisionWouldNotInterruptEvenWithoutDnd() {
        makeFsiDecision(NO_FSI_SUPPRESSED_BY_DND).let {
            assertFalse(it.shouldInterrupt)
            assertFalse(it.wouldInterruptWithoutDnd)
        }
    }

    private fun makeFsiDecision(originalDecision: FullScreenIntentDecision) =
        FullScreenIntentDecisionImpl(NotificationEntryBuilder().build(), originalDecision)
}