1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.systemui.statusbar.notification.interruption 17 18 import com.android.app.tracing.traceSection 19 import com.android.internal.annotations.VisibleForTesting 20 import com.android.systemui.dagger.SysUISingleton 21 import com.android.systemui.flags.RefactorFlagUtils 22 import com.android.systemui.statusbar.notification.collection.NotificationEntry 23 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider.FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND 24 import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider.Decision 25 import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider.FullScreenIntentDecision 26 27 /** 28 * Wraps a [NotificationInterruptStateProvider] to convert it to the new 29 * [VisualInterruptionDecisionProvider] interface. 30 */ 31 @SysUISingleton 32 class NotificationInterruptStateProviderWrapper( 33 private val wrapped: NotificationInterruptStateProvider 34 ) : VisualInterruptionDecisionProvider { 35 init { 36 VisualInterruptionRefactor.assertInLegacyMode() 37 } 38 39 @VisibleForTesting 40 enum class DecisionImpl(override val shouldInterrupt: Boolean) : Decision { 41 SHOULD_INTERRUPT(shouldInterrupt = true), 42 SHOULD_NOT_INTERRUPT(shouldInterrupt = false); 43 44 override val logReason = "unknown" 45 46 companion object { ofnull47 fun of(booleanDecision: Boolean) = 48 if (booleanDecision) SHOULD_INTERRUPT else SHOULD_NOT_INTERRUPT 49 } 50 } 51 52 @VisibleForTesting 53 class FullScreenIntentDecisionImpl( 54 val originalEntry: NotificationEntry, 55 val originalDecision: NotificationInterruptStateProvider.FullScreenIntentDecision 56 ) : FullScreenIntentDecision { 57 override val shouldInterrupt = originalDecision.shouldLaunch 58 override val wouldInterruptWithoutDnd = originalDecision == NO_FSI_SUPPRESSED_ONLY_BY_DND 59 override val logReason = originalDecision.name 60 } 61 addLegacySuppressornull62 override fun addLegacySuppressor(suppressor: NotificationInterruptSuppressor) { 63 wrapped.addSuppressor(suppressor) 64 } 65 removeLegacySuppressornull66 override fun removeLegacySuppressor(suppressor: NotificationInterruptSuppressor) { 67 wrapped.removeSuppressor(suppressor) 68 } 69 addConditionnull70 override fun addCondition(condition: VisualInterruptionCondition) = notValidInLegacyMode() 71 72 override fun removeCondition(condition: VisualInterruptionCondition) = notValidInLegacyMode() 73 74 override fun addFilter(filter: VisualInterruptionFilter) = notValidInLegacyMode() 75 76 override fun removeFilter(filter: VisualInterruptionFilter) = notValidInLegacyMode() 77 78 private fun notValidInLegacyMode() { 79 RefactorFlagUtils.assertOnEngBuild( 80 "This method is only implemented in VisualInterruptionDecisionProviderImpl, " + 81 "and so should only be called when FLAG_VISUAL_INTERRUPTIONS_REFACTOR is enabled." 82 ) 83 } 84 makeUnloggedHeadsUpDecisionnull85 override fun makeUnloggedHeadsUpDecision(entry: NotificationEntry): Decision = 86 traceSection("NotificationInterruptStateProviderWrapper#makeUnloggedHeadsUpDecision") { 87 wrapped.checkHeadsUp(entry, /* log= */ false).let { DecisionImpl.of(it) } 88 } 89 makeAndLogHeadsUpDecisionnull90 override fun makeAndLogHeadsUpDecision(entry: NotificationEntry): Decision = 91 traceSection("NotificationInterruptStateProviderWrapper#makeAndLogHeadsUpDecision") { 92 wrapped.checkHeadsUp(entry, /* log= */ true).let { DecisionImpl.of(it) } 93 } 94 makeUnloggedFullScreenIntentDecisionnull95 override fun makeUnloggedFullScreenIntentDecision(entry: NotificationEntry) = 96 traceSection( 97 "NotificationInterruptStateProviderWrapper#makeUnloggedFullScreenIntentDecision" 98 ) { 99 wrapped.getFullScreenIntentDecision(entry).let { 100 FullScreenIntentDecisionImpl(entry, it) 101 } 102 } 103 logFullScreenIntentDecisionnull104 override fun logFullScreenIntentDecision(decision: FullScreenIntentDecision) = 105 traceSection("NotificationInterruptStateProviderWrapper#logFullScreenIntentDecision") { 106 (decision as FullScreenIntentDecisionImpl).let { 107 wrapped.logFullScreenIntentDecision(it.originalEntry, it.originalDecision) 108 } 109 } 110 makeAndLogBubbleDecisionnull111 override fun makeAndLogBubbleDecision(entry: NotificationEntry): Decision = 112 traceSection("NotificationInterruptStateProviderWrapper#makeAndLogBubbleDecision") { 113 wrapped.shouldBubbleUp(entry).let { DecisionImpl.of(it) } 114 } 115 } 116