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.internal.annotations.VisibleForTesting
19 import com.android.systemui.dagger.SysUISingleton
20 import com.android.systemui.statusbar.notification.collection.NotificationEntry
21 import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider.FullScreenIntentDecision.NO_FSI_SUPPRESSED_ONLY_BY_DND
22 import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider.Decision
23 import com.android.systemui.statusbar.notification.interruption.VisualInterruptionDecisionProvider.FullScreenIntentDecision
24 
25 /**
26  * Wraps a [NotificationInterruptStateProvider] to convert it to the new
27  * [VisualInterruptionDecisionProvider] interface.
28  */
29 @SysUISingleton
30 class NotificationInterruptStateProviderWrapper(
31     private val wrapped: NotificationInterruptStateProvider
32 ) : VisualInterruptionDecisionProvider {
33 
34     @VisibleForTesting
35     enum class DecisionImpl(override val shouldInterrupt: Boolean) : Decision {
36         SHOULD_INTERRUPT(shouldInterrupt = true),
37         SHOULD_NOT_INTERRUPT(shouldInterrupt = false);
38 
39         override val logReason = "unknown"
40 
41         companion object {
42             fun of(booleanDecision: Boolean) =
43                 if (booleanDecision) SHOULD_INTERRUPT else SHOULD_NOT_INTERRUPT
44         }
45     }
46 
47     @VisibleForTesting
48     class FullScreenIntentDecisionImpl(
49         val originalEntry: NotificationEntry,
50         val originalDecision: NotificationInterruptStateProvider.FullScreenIntentDecision
51     ) : FullScreenIntentDecision {
52         override val shouldInterrupt = originalDecision.shouldLaunch
53         override val wouldInterruptWithoutDnd = originalDecision == NO_FSI_SUPPRESSED_ONLY_BY_DND
54         override val logReason = originalDecision.name
55     }
56 
57     override fun addSuppressor(suppressor: NotificationInterruptSuppressor) {
58         wrapped.addSuppressor(suppressor)
59     }
60 
61     override fun makeUnloggedHeadsUpDecision(entry: NotificationEntry): Decision =
62         wrapped.checkHeadsUp(entry, /* log= */ false).let { DecisionImpl.of(it) }
63 
64     override fun makeAndLogHeadsUpDecision(entry: NotificationEntry): Decision =
65         wrapped.checkHeadsUp(entry, /* log= */ true).let { DecisionImpl.of(it) }
66 
67     override fun makeUnloggedFullScreenIntentDecision(entry: NotificationEntry) =
68         wrapped.getFullScreenIntentDecision(entry).let { FullScreenIntentDecisionImpl(entry, it) }
69 
70     override fun logFullScreenIntentDecision(decision: FullScreenIntentDecision) {
71         (decision as FullScreenIntentDecisionImpl).let {
72             wrapped.logFullScreenIntentDecision(it.originalEntry, it.originalDecision)
73         }
74     }
75 
76     override fun makeAndLogBubbleDecision(entry: NotificationEntry): Decision =
77         wrapped.shouldBubbleUp(entry).let { DecisionImpl.of(it) }
78 }
79