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