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.systemui.statusbar.notification.collection.NotificationEntry
19 
20 /**
21  * Decides whether a notification should visually interrupt the user in various ways.
22  *
23  * These include displaying the notification as heads-up (peeking while the device is awake or
24  * pulsing while the device is dozing), displaying the notification as a bubble, and launching a
25  * full-screen intent for the notification.
26  */
27 interface VisualInterruptionDecisionProvider {
28     /**
29      * Represents the decision to visually interrupt or not.
30      *
31      * Used for heads-up and bubble decisions; subclassed by [FullScreenIntentDecision] for
32      * full-screen intent decisions.
33      *
34      * @property[shouldInterrupt] whether a visual interruption should be triggered
35      * @property[logReason] a log-friendly string explaining the reason for the decision; should be
36      *   used *only* for logging, not decision-making
37      */
38     interface Decision {
39         val shouldInterrupt: Boolean
40         val logReason: String
41     }
42 
43     /**
44      * Represents the decision to launch a full-screen intent for a notification or not.
45      *
46      * @property[wouldInterruptWithoutDnd] whether a full-screen intent should not be launched only
47      *   because Do Not Disturb has suppressed it
48      */
49     interface FullScreenIntentDecision : Decision {
50         val wouldInterruptWithoutDnd: Boolean
51     }
52 
53     /**
54      * Adds a [component][suppressor] that can suppress visual interruptions.
55      *
56      * This class may call suppressors in any order.
57      *
58      * @param[suppressor] the suppressor to add
59      */
60     fun addSuppressor(suppressor: NotificationInterruptSuppressor)
61 
62     /**
63      * Decides whether a [notification][entry] should display as heads-up or not, but does not log
64      * that decision.
65      *
66      * @param[entry] the notification that this decision is about
67      * @return the decision to display that notification as heads-up or not
68      */
69     fun makeUnloggedHeadsUpDecision(entry: NotificationEntry): Decision
70 
71     /**
72      * Decides whether a [notification][entry] should display as heads-up or not, and logs that
73      * decision.
74      *
75      * If the device is awake, the decision will consider whether the notification should "peek"
76      * (slide in from the top of the screen over the current activity).
77      *
78      * If the device is dozing, the decision will consider whether the notification should "pulse"
79      * (wake the screen up and display the ambient view of the notification).
80      *
81      * @see[makeUnloggedHeadsUpDecision]
82      *
83      * @param[entry] the notification that this decision is about
84      * @return the decision to display that notification as heads-up or not
85      */
86     fun makeAndLogHeadsUpDecision(entry: NotificationEntry): Decision
87 
88     /**
89      * Decides whether a [notification][entry] should launch a full-screen intent or not, but does
90      * not log that decision.
91      *
92      * The returned decision can be logged by passing it to [logFullScreenIntentDecision].
93      *
94      * @see[makeAndLogHeadsUpDecision]
95      *
96      * @param[entry] the notification that this decision is about
97      * @return the decision to launch a full-screen intent for that notification or not
98      */
99     fun makeUnloggedFullScreenIntentDecision(entry: NotificationEntry): FullScreenIntentDecision
100 
101     /**
102      * Logs a previous [decision] to launch a full-screen intent or not.
103      *
104      * @param[decision] the decision to log
105      */
106     fun logFullScreenIntentDecision(decision: FullScreenIntentDecision)
107 
108     /**
109      * Decides whether a [notification][entry] should display as a bubble or not.
110      *
111      * @param[entry] the notification that this decision is about
112      * @return the decision to display that notification as a bubble or not
113      */
114     fun makeAndLogBubbleDecision(entry: NotificationEntry): Decision
115 }
116