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.wm.shell.bubbles; 18 19 import static java.lang.annotation.ElementType.FIELD; 20 import static java.lang.annotation.ElementType.LOCAL_VARIABLE; 21 import static java.lang.annotation.ElementType.PARAMETER; 22 import static java.lang.annotation.RetentionPolicy.SOURCE; 23 24 import android.content.pm.UserInfo; 25 import android.content.res.Configuration; 26 import android.os.Bundle; 27 import android.service.notification.NotificationListenerService.RankingMap; 28 import android.util.ArraySet; 29 import android.util.Pair; 30 import android.util.SparseArray; 31 32 import androidx.annotation.IntDef; 33 import androidx.annotation.Nullable; 34 35 import com.android.wm.shell.common.annotations.ExternalThread; 36 37 import java.io.FileDescriptor; 38 import java.io.PrintWriter; 39 import java.lang.annotation.Retention; 40 import java.lang.annotation.Target; 41 import java.util.HashMap; 42 import java.util.List; 43 import java.util.concurrent.Executor; 44 import java.util.function.Consumer; 45 import java.util.function.IntConsumer; 46 47 /** 48 * Interface to engage bubbles feature. 49 */ 50 @ExternalThread 51 public interface Bubbles { 52 53 @Retention(SOURCE) 54 @IntDef({DISMISS_USER_GESTURE, DISMISS_AGED, DISMISS_TASK_FINISHED, DISMISS_BLOCKED, 55 DISMISS_NOTIF_CANCEL, DISMISS_ACCESSIBILITY_ACTION, DISMISS_NO_LONGER_BUBBLE, 56 DISMISS_USER_CHANGED, DISMISS_GROUP_CANCELLED, DISMISS_INVALID_INTENT, 57 DISMISS_OVERFLOW_MAX_REACHED, DISMISS_SHORTCUT_REMOVED, DISMISS_PACKAGE_REMOVED, 58 DISMISS_NO_BUBBLE_UP, DISMISS_RELOAD_FROM_DISK}) 59 @Target({FIELD, LOCAL_VARIABLE, PARAMETER}) 60 @interface DismissReason {} 61 62 int DISMISS_USER_GESTURE = 1; 63 int DISMISS_AGED = 2; 64 int DISMISS_TASK_FINISHED = 3; 65 int DISMISS_BLOCKED = 4; 66 int DISMISS_NOTIF_CANCEL = 5; 67 int DISMISS_ACCESSIBILITY_ACTION = 6; 68 int DISMISS_NO_LONGER_BUBBLE = 7; 69 int DISMISS_USER_CHANGED = 8; 70 int DISMISS_GROUP_CANCELLED = 9; 71 int DISMISS_INVALID_INTENT = 10; 72 int DISMISS_OVERFLOW_MAX_REACHED = 11; 73 int DISMISS_SHORTCUT_REMOVED = 12; 74 int DISMISS_PACKAGE_REMOVED = 13; 75 int DISMISS_NO_BUBBLE_UP = 14; 76 int DISMISS_RELOAD_FROM_DISK = 15; 77 78 /** 79 * @return {@code true} if there is a bubble associated with the provided key and if its 80 * notification is hidden from the shade or there is a group summary associated with the 81 * provided key that is hidden from the shade because it has been dismissed but still has child 82 * bubbles active. 83 */ isBubbleNotificationSuppressedFromShade(String key, String groupKey)84 boolean isBubbleNotificationSuppressedFromShade(String key, String groupKey); 85 86 /** 87 * @return {@code true} if the current notification entry same as selected bubble 88 * notification entry and the stack is currently expanded. 89 */ isBubbleExpanded(String key)90 boolean isBubbleExpanded(String key); 91 92 /** @return {@code true} if stack of bubbles is expanded or not. */ isStackExpanded()93 boolean isStackExpanded(); 94 95 /** 96 * Removes a group key indicating that the summary for this group should no longer be 97 * suppressed. 98 * 99 * @param callback If removed, this callback will be called with the summary key of the group 100 */ removeSuppressedSummaryIfNecessary(String groupKey, Consumer<String> callback, Executor callbackExecutor)101 void removeSuppressedSummaryIfNecessary(String groupKey, Consumer<String> callback, 102 Executor callbackExecutor); 103 104 /** Tell the stack of bubbles to collapse. */ collapseStack()105 void collapseStack(); 106 107 /** Tell the controller need update its UI to fit theme. */ updateForThemeChanges()108 void updateForThemeChanges(); 109 110 /** 111 * Request the stack expand if needed, then select the specified Bubble as current. 112 * If no bubble exists for this entry, one is created. 113 * 114 * @param entry the notification for the bubble to be selected 115 */ expandStackAndSelectBubble(BubbleEntry entry)116 void expandStackAndSelectBubble(BubbleEntry entry); 117 118 /** 119 * Request the stack expand if needed, then select the specified Bubble as current. 120 * 121 * @param bubble the bubble to be selected 122 */ expandStackAndSelectBubble(Bubble bubble)123 void expandStackAndSelectBubble(Bubble bubble); 124 125 /** 126 * @return a bubble that matches the provided shortcutId, if one exists. 127 */ 128 @Nullable getBubbleWithShortcutId(String shortcutId)129 Bubble getBubbleWithShortcutId(String shortcutId); 130 131 /** Called for any taskbar changes. */ onTaskbarChanged(Bundle b)132 void onTaskbarChanged(Bundle b); 133 134 /** Open the overflow view. */ openBubbleOverflow()135 void openBubbleOverflow(); 136 137 /** 138 * We intercept notification entries (including group summaries) dismissed by the user when 139 * there is an active bubble associated with it. We do this so that developers can still 140 * cancel it (and hence the bubbles associated with it). However, these intercepted 141 * notifications should then be hidden from the shade since the user has cancelled them, so we 142 * {@link Bubble#setSuppressNotification}. For the case of suppressed summaries, we also add 143 * {@link BubbleData#addSummaryToSuppress}. 144 * 145 * @param entry the notification of the BubbleEntry should be removed. 146 * @param children the list of child notification of the BubbleEntry from 1st param entry, 147 * this will be null if entry does have no children. 148 * @param removeCallback the remove callback for SystemUI side to remove notification, the int 149 * number should be list position of children list and use -1 for 150 * removing the parent notification. 151 * 152 * @return true if we want to intercept the dismissal of the entry, else false. 153 */ handleDismissalInterception(BubbleEntry entry, @Nullable List<BubbleEntry> children, IntConsumer removeCallback, Executor callbackExecutor)154 boolean handleDismissalInterception(BubbleEntry entry, @Nullable List<BubbleEntry> children, 155 IntConsumer removeCallback, Executor callbackExecutor); 156 157 /** Set the proxy to commnuicate with SysUi side components. */ setSysuiProxy(SysuiProxy proxy)158 void setSysuiProxy(SysuiProxy proxy); 159 160 /** Set a listener to be notified of bubble expand events. */ setExpandListener(BubbleExpandListener listener)161 void setExpandListener(BubbleExpandListener listener); 162 163 /** 164 * Called when new notification entry added. 165 * 166 * @param entry the {@link BubbleEntry} by the notification. 167 */ onEntryAdded(BubbleEntry entry)168 void onEntryAdded(BubbleEntry entry); 169 170 /** 171 * Called when new notification entry updated. 172 * 173 * @param entry the {@link BubbleEntry} by the notification. 174 * @param shouldBubbleUp {@code true} if this notification should bubble up. 175 */ onEntryUpdated(BubbleEntry entry, boolean shouldBubbleUp)176 void onEntryUpdated(BubbleEntry entry, boolean shouldBubbleUp); 177 178 /** 179 * Called when new notification entry removed. 180 * 181 * @param entry the {@link BubbleEntry} by the notification. 182 */ onEntryRemoved(BubbleEntry entry)183 void onEntryRemoved(BubbleEntry entry); 184 185 /** 186 * Called when NotificationListener has received adjusted notification rank and reapplied 187 * filtering and sorting. This is used to dismiss or create bubbles based on changes in 188 * permissions on the notification channel or the global setting. 189 * 190 * @param rankingMap the updated ranking map from NotificationListenerService 191 * @param entryDataByKey a map of ranking key to bubble entry and whether the entry should 192 * bubble up 193 */ onRankingUpdated(RankingMap rankingMap, HashMap<String, Pair<BubbleEntry, Boolean>> entryDataByKey)194 void onRankingUpdated(RankingMap rankingMap, 195 HashMap<String, Pair<BubbleEntry, Boolean>> entryDataByKey); 196 197 /** 198 * Called when the status bar has become visible or invisible (either permanently or 199 * temporarily). 200 */ onStatusBarVisibilityChanged(boolean visible)201 void onStatusBarVisibilityChanged(boolean visible); 202 203 /** Called when system zen mode state changed. */ onZenStateChanged()204 void onZenStateChanged(); 205 206 /** 207 * Called when statusBar state changed. 208 * 209 * @param isShade {@code true} is state is SHADE. 210 */ onStatusBarStateChanged(boolean isShade)211 void onStatusBarStateChanged(boolean isShade); 212 213 /** 214 * Called when the current user changed. 215 * 216 * @param newUserId the new user's id. 217 */ onUserChanged(int newUserId)218 void onUserChanged(int newUserId); 219 220 /** 221 * Called when the current user profiles change. 222 * 223 * @param currentProfiles the user infos for the current profile. 224 */ onCurrentProfilesChanged(SparseArray<UserInfo> currentProfiles)225 void onCurrentProfilesChanged(SparseArray<UserInfo> currentProfiles); 226 227 /** 228 * Called when config changed. 229 * 230 * @param newConfig the new config. 231 */ onConfigChanged(Configuration newConfig)232 void onConfigChanged(Configuration newConfig); 233 234 /** Description of current bubble state. */ dump(FileDescriptor fd, PrintWriter pw, String[] args)235 void dump(FileDescriptor fd, PrintWriter pw, String[] args); 236 237 /** Listener to find out about stack expansion / collapse events. */ 238 interface BubbleExpandListener { 239 /** 240 * Called when the expansion state of the bubble stack changes. 241 * 242 * @param isExpanding whether it's expanding or collapsing 243 * @param key the notification key associated with bubble being expanded 244 */ onBubbleExpandChanged(boolean isExpanding, String key)245 void onBubbleExpandChanged(boolean isExpanding, String key); 246 } 247 248 /** Listener to be notified when the flags for notification or bubble suppression changes.*/ 249 interface SuppressionChangedListener { 250 /** Called when the notification suppression state of a bubble changes. */ onBubbleNotificationSuppressionChange(Bubble bubble)251 void onBubbleNotificationSuppressionChange(Bubble bubble); 252 } 253 254 /** Listener to be notified when a pending intent has been canceled for a bubble. */ 255 interface PendingIntentCanceledListener { 256 /** Called when the pending intent for a bubble has been canceled. */ onPendingIntentCanceled(Bubble bubble)257 void onPendingIntentCanceled(Bubble bubble); 258 } 259 260 /** Callback to tell SysUi components execute some methods. */ 261 interface SysuiProxy { isNotificationShadeExpand(Consumer<Boolean> callback)262 void isNotificationShadeExpand(Consumer<Boolean> callback); 263 getPendingOrActiveEntry(String key, Consumer<BubbleEntry> callback)264 void getPendingOrActiveEntry(String key, Consumer<BubbleEntry> callback); 265 getShouldRestoredEntries(ArraySet<String> savedBubbleKeys, Consumer<List<BubbleEntry>> callback)266 void getShouldRestoredEntries(ArraySet<String> savedBubbleKeys, 267 Consumer<List<BubbleEntry>> callback); 268 setNotificationInterruption(String key)269 void setNotificationInterruption(String key); 270 requestNotificationShadeTopUi(boolean requestTopUi, String componentTag)271 void requestNotificationShadeTopUi(boolean requestTopUi, String componentTag); 272 notifyRemoveNotification(String key, int reason)273 void notifyRemoveNotification(String key, int reason); 274 notifyInvalidateNotifications(String reason)275 void notifyInvalidateNotifications(String reason); 276 notifyMaybeCancelSummary(String key)277 void notifyMaybeCancelSummary(String key); 278 removeNotificationEntry(String key)279 void removeNotificationEntry(String key); 280 updateNotificationBubbleButton(String key)281 void updateNotificationBubbleButton(String key); 282 updateNotificationSuppression(String key)283 void updateNotificationSuppression(String key); 284 onStackExpandChanged(boolean shouldExpand)285 void onStackExpandChanged(boolean shouldExpand); 286 onManageMenuExpandChanged(boolean menuExpanded)287 void onManageMenuExpandChanged(boolean menuExpanded); 288 onUnbubbleConversation(String key)289 void onUnbubbleConversation(String key); 290 } 291 } 292