1 /* 2 * Copyright (C) 2020 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 17 package com.android.systemui.statusbar.notification.interruption; 18 19 import com.android.systemui.statusbar.notification.collection.NotificationEntry; 20 21 /** 22 * Provides bubble-up and heads-up state for notification entries. 23 * 24 * When a notification is heads-up when dozing, this is also called "pulsing." 25 */ 26 public interface NotificationInterruptStateProvider { 27 /** 28 * Enum representing a decision of whether to show a full screen intent. While many of the 29 * relevant properties could overlap, the decision represents the deciding factor for whether 30 * the full screen intent should or shouldn't launch. 31 */ 32 enum FullScreenIntentDecision { 33 /** 34 * Full screen intents are disabled. 35 */ 36 NO_FSI_DISABLED(false), 37 /** 38 * No full screen intent included, so there is nothing to show. 39 */ 40 NO_FULL_SCREEN_INTENT(false), 41 /** 42 * Suppressed by DND settings. 43 */ 44 NO_FSI_SUPPRESSED_BY_DND(false), 45 /** 46 * Full screen intent was suppressed *only* by DND, and if not for DND would have shown. We 47 * track this separately in order to allow the intent to be shown if the DND decision 48 * changes. 49 */ 50 NO_FSI_SUPPRESSED_ONLY_BY_DND(false), 51 /** 52 * Notification importance not high enough to show FSI. 53 */ 54 NO_FSI_NOT_IMPORTANT_ENOUGH(false), 55 /** 56 * Notification should not FSI due to having suppressive GroupAlertBehavior. This blocks a 57 * potentially malicious use of flags that previously allowed apps to escalate a HUN to an 58 * FSI even while the device was unlocked. 59 */ 60 NO_FSI_SUPPRESSIVE_GROUP_ALERT_BEHAVIOR(false), 61 /** 62 * Notification should not FSI due to having suppressive BubbleMetadata. This blocks a 63 * potentially malicious use of flags that previously allowed apps to escalate a HUN to an 64 * FSI even while the device was unlocked. 65 */ 66 NO_FSI_SUPPRESSIVE_BUBBLE_METADATA(false), 67 /** 68 * Device screen is off, so the FSI should launch. 69 */ 70 FSI_DEVICE_NOT_INTERACTIVE(true), 71 /** 72 * Device is currently dreaming, so FSI should launch. 73 */ 74 FSI_DEVICE_IS_DREAMING(true), 75 /** 76 * Keyguard is showing, so FSI should launch. 77 */ 78 FSI_KEYGUARD_SHOWING(true), 79 /** 80 * The notification is expected to show heads-up, so FSI is not needed. 81 */ 82 NO_FSI_EXPECTED_TO_HUN(false), 83 /** 84 * The notification is not expected to HUN while the keyguard is occluded, so show FSI. 85 */ 86 FSI_KEYGUARD_OCCLUDED(true), 87 /** 88 * The notification is not expected to HUN when the keyguard is showing but not occluded, 89 * which likely means that the shade is showing over the lockscreen; show FSI in this case. 90 */ 91 FSI_LOCKED_SHADE(true), 92 /** 93 * FSI requires keyguard to be showing, but there is no keyguard. This is a (potentially 94 * malicious) warning state where we suppress the FSI because the device is in use knowing 95 * that the HUN will probably not display. 96 */ 97 NO_FSI_NO_HUN_OR_KEYGUARD(false), 98 /** 99 * No conditions blocking FSI launch. 100 */ 101 FSI_EXPECTED_NOT_TO_HUN(true); 102 103 public final boolean shouldLaunch; 104 FullScreenIntentDecision(boolean shouldLaunch)105 FullScreenIntentDecision(boolean shouldLaunch) { 106 this.shouldLaunch = shouldLaunch; 107 } 108 } 109 110 /** 111 * If the device is awake (not dozing): 112 * Whether the notification should peek in from the top and alert the user. 113 * 114 * If the device is dozing: 115 * Whether the notification should show the ambient view of the notification ("pulse"). 116 * 117 * @param entry the entry to check 118 * @return true if the entry should heads up, false otherwise 119 */ shouldHeadsUp(NotificationEntry entry)120 boolean shouldHeadsUp(NotificationEntry entry); 121 122 /** 123 * Returns the value of whether this entry should peek (from shouldHeadsUp(entry)), but only 124 * optionally logs the status. 125 * 126 * This method should be used in cases where the caller needs to check whether a notification 127 * qualifies for a heads up, but is not necessarily guaranteed to make the heads-up happen. 128 * 129 * @param entry the entry to check 130 * @param log whether or not to log the results of this check 131 * @return true if the entry should heads up, false otherwise 132 */ checkHeadsUp(NotificationEntry entry, boolean log)133 boolean checkHeadsUp(NotificationEntry entry, boolean log); 134 135 /** 136 * Whether the notification should appear as a bubble with a fly-out on top of the screen. 137 * 138 * @param entry the entry to check 139 * @return true if the entry should bubble up, false otherwise 140 */ shouldBubbleUp(NotificationEntry entry)141 boolean shouldBubbleUp(NotificationEntry entry); 142 143 /** 144 * Whether to launch the entry's full screen intent when the entry is added. 145 * 146 * @param entry the entry that was added 147 * @return {@code true} if we should launch the full screen intent 148 */ shouldLaunchFullScreenIntentWhenAdded(NotificationEntry entry)149 boolean shouldLaunchFullScreenIntentWhenAdded(NotificationEntry entry); 150 151 /** 152 * Whether an entry's full screen intent would be launched. 153 * 154 * This method differs from shouldLaunchFullScreenIntentWhenAdded by returning more information 155 * on the decision, and only optionally logging the outcome. It should be used in cases where 156 * the caller needs to know what the decision would be, but may not actually launch the full 157 * screen intent. 158 * 159 * @param entry the entry to evaluate 160 * @return FullScreenIntentDecision representing the decision for whether to show the intent 161 */ getFullScreenIntentDecision(NotificationEntry entry)162 FullScreenIntentDecision getFullScreenIntentDecision(NotificationEntry entry); 163 164 /** 165 * Write the full screen launch decision for the given entry to logs. 166 * 167 * @param entry the NotificationEntry for which the decision applies 168 * @param decision reason for launch or no-launch of FSI for entry 169 */ logFullScreenIntentDecision(NotificationEntry entry, FullScreenIntentDecision decision)170 void logFullScreenIntentDecision(NotificationEntry entry, FullScreenIntentDecision decision); 171 172 /** 173 * Add a component that can suppress visual interruptions. 174 */ addSuppressor(NotificationInterruptSuppressor suppressor)175 void addSuppressor(NotificationInterruptSuppressor suppressor); 176 } 177