• 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.app.NotificationChannel;
25 import android.content.Intent;
26 import android.content.pm.UserInfo;
27 import android.os.UserHandle;
28 import android.service.notification.NotificationListenerService;
29 import android.service.notification.NotificationListenerService.RankingMap;
30 import android.util.Pair;
31 import android.util.SparseArray;
32 
33 import androidx.annotation.IntDef;
34 import androidx.annotation.Nullable;
35 
36 import com.android.wm.shell.common.annotations.ExternalThread;
37 
38 import java.lang.annotation.Retention;
39 import java.lang.annotation.Target;
40 import java.util.HashMap;
41 import java.util.List;
42 import java.util.Set;
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, DISMISS_USER_REMOVED})
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     int DISMISS_USER_REMOVED = 16;
78 
79     /**
80      * @return {@code true} if there is a bubble associated with the provided key and if its
81      * notification is hidden from the shade or there is a group summary associated with the
82      * provided key that is hidden from the shade because it has been dismissed but still has child
83      * bubbles active.
84      */
isBubbleNotificationSuppressedFromShade(String key, String groupKey)85     boolean isBubbleNotificationSuppressedFromShade(String key, String groupKey);
86 
87     /**
88      * @return {@code true} if the current notification entry same as selected bubble
89      * notification entry and the stack is currently expanded.
90      */
isBubbleExpanded(String key)91     boolean isBubbleExpanded(String key);
92 
93     /** Tell the stack of bubbles to collapse. */
collapseStack()94     void collapseStack();
95 
96     /**
97      * Request the stack expand if needed, then select the specified Bubble as current.
98      * If no bubble exists for this entry, one is created.
99      *
100      * @param entry the notification for the bubble to be selected
101      */
expandStackAndSelectBubble(BubbleEntry entry)102     void expandStackAndSelectBubble(BubbleEntry entry);
103 
104     /**
105      * Request the stack expand if needed, then select the specified Bubble as current.
106      *
107      * @param bubble the bubble to be selected
108      */
expandStackAndSelectBubble(Bubble bubble)109     void expandStackAndSelectBubble(Bubble bubble);
110 
111     /**
112      * This method has different behavior depending on:
113      *    - if an app bubble exists
114      *    - if an app bubble is expanded
115      *
116      * If no app bubble exists, this will add and expand a bubble with the provided intent. The
117      * intent must be explicit (i.e. include a package name or fully qualified component class name)
118      * and the activity for it should be resizable.
119      *
120      * If an app bubble exists, this will toggle the visibility of it, i.e. if the app bubble is
121      * expanded, calling this method will collapse it. If the app bubble is not expanded, calling
122      * this method will expand it.
123      *
124      * These bubbles are <b>not</b> backed by a notification and remain until the user dismisses
125      * the bubble or bubble stack.
126      *
127      * Some notes:
128      *    - Only one app bubble is supported at a time
129      *    - Calling this method with a different intent than the existing app bubble will do nothing
130      *
131      * @param intent the intent to display in the bubble expanded view.
132      */
showOrHideAppBubble(Intent intent)133     void showOrHideAppBubble(Intent intent);
134 
135     /**
136      * @return a bubble that matches the provided shortcutId, if one exists.
137      */
138     @Nullable
getBubbleWithShortcutId(String shortcutId)139     Bubble getBubbleWithShortcutId(String shortcutId);
140 
141     /**
142      * We intercept notification entries (including group summaries) dismissed by the user when
143      * there is an active bubble associated with it. We do this so that developers can still
144      * cancel it (and hence the bubbles associated with it). However, these intercepted
145      * notifications should then be hidden from the shade since the user has cancelled them, so we
146      * {@link Bubble#setSuppressNotification}.  For the case of suppressed summaries, we also add
147      * {@link BubbleData#addSummaryToSuppress}.
148      *
149      * @param entry the notification of the BubbleEntry should be removed.
150      * @param children the list of child notification of the BubbleEntry from 1st param entry,
151      *                 this will be null if entry does have no children.
152      * @param removeCallback the remove callback for SystemUI side to remove notification, the int
153      *                       number should be list position of children list and use -1 for
154      *                       removing the parent notification.
155      *
156      * @return true if we want to intercept the dismissal of the entry, else false.
157      */
handleDismissalInterception(BubbleEntry entry, @Nullable List<BubbleEntry> children, IntConsumer removeCallback, Executor callbackExecutor)158     boolean handleDismissalInterception(BubbleEntry entry, @Nullable List<BubbleEntry> children,
159             IntConsumer removeCallback, Executor callbackExecutor);
160 
161     /** Set the proxy to commnuicate with SysUi side components. */
setSysuiProxy(SysuiProxy proxy)162     void setSysuiProxy(SysuiProxy proxy);
163 
164     /** Set a listener to be notified of bubble expand events. */
setExpandListener(BubbleExpandListener listener)165     void setExpandListener(BubbleExpandListener listener);
166 
167     /**
168      * Called when new notification entry added.
169      *
170      * @param entry the {@link BubbleEntry} by the notification.
171      */
onEntryAdded(BubbleEntry entry)172     void onEntryAdded(BubbleEntry entry);
173 
174     /**
175      * Called when new notification entry updated.
176      *
177      * @param entry the {@link BubbleEntry} by the notification.
178      * @param shouldBubbleUp {@code true} if this notification should bubble up.
179      * @param fromSystem {@code true} if this update is from NotificationManagerService.
180      */
onEntryUpdated(BubbleEntry entry, boolean shouldBubbleUp, boolean fromSystem)181     void onEntryUpdated(BubbleEntry entry, boolean shouldBubbleUp, boolean fromSystem);
182 
183     /**
184      * Called when new notification entry removed.
185      *
186      * @param entry the {@link BubbleEntry} by the notification.
187      */
onEntryRemoved(BubbleEntry entry)188     void onEntryRemoved(BubbleEntry entry);
189 
190     /**
191      * Called when NotificationListener has received adjusted notification rank and reapplied
192      * filtering and sorting. This is used to dismiss or create bubbles based on changes in
193      * permissions on the notification channel or the global setting.
194      *
195      * @param rankingMap the updated ranking map from NotificationListenerService
196      * @param entryDataByKey a map of ranking key to bubble entry and whether the entry should
197      *                       bubble up
198      */
onRankingUpdated( RankingMap rankingMap, HashMap<String, Pair<BubbleEntry, Boolean>> entryDataByKey)199     void onRankingUpdated(
200             RankingMap rankingMap,
201             HashMap<String, Pair<BubbleEntry, Boolean>> entryDataByKey);
202 
203     /**
204      * Called when a notification channel is modified, in response to
205      * {@link NotificationListenerService#onNotificationChannelModified}.
206      *
207      * @param pkg the package the notification channel belongs to.
208      * @param user the user the notification channel belongs to.
209      * @param channel the channel being modified.
210      * @param modificationType the type of modification that occurred to the channel.
211      */
onNotificationChannelModified( String pkg, UserHandle user, NotificationChannel channel, int modificationType)212     void onNotificationChannelModified(
213             String pkg,
214             UserHandle user,
215             NotificationChannel channel,
216             int modificationType);
217 
218     /**
219      * Called when notification panel is expanded or collapsed
220      */
onNotificationPanelExpandedChanged(boolean expanded)221     void onNotificationPanelExpandedChanged(boolean expanded);
222 
223     /**
224      * Called when the status bar has become visible or invisible (either permanently or
225      * temporarily).
226      */
onStatusBarVisibilityChanged(boolean visible)227     void onStatusBarVisibilityChanged(boolean visible);
228 
229     /** Called when system zen mode state changed. */
onZenStateChanged()230     void onZenStateChanged();
231 
232     /**
233      * Called when statusBar state changed.
234      *
235      * @param isShade {@code true} is state is SHADE.
236      */
onStatusBarStateChanged(boolean isShade)237     void onStatusBarStateChanged(boolean isShade);
238 
239     /**
240      * Called when the current user changed.
241      *
242      * @param newUserId the new user's id.
243      */
onUserChanged(int newUserId)244     void onUserChanged(int newUserId);
245 
246     /**
247      * Called when the current user profiles change.
248      *
249      * @param currentProfiles the user infos for the current profile.
250      */
onCurrentProfilesChanged(SparseArray<UserInfo> currentProfiles)251     void onCurrentProfilesChanged(SparseArray<UserInfo> currentProfiles);
252 
253     /**
254      * Called when a user is removed.
255      *
256      * @param removedUserId the id of the removed user.
257      */
onUserRemoved(int removedUserId)258     void onUserRemoved(int removedUserId);
259 
260     /** Listener to find out about stack expansion / collapse events. */
261     interface BubbleExpandListener {
262         /**
263          * Called when the expansion state of the bubble stack changes.
264          *
265          * @param isExpanding whether it's expanding or collapsing
266          * @param key the notification key associated with bubble being expanded
267          */
onBubbleExpandChanged(boolean isExpanding, String key)268         void onBubbleExpandChanged(boolean isExpanding, String key);
269     }
270 
271     /** Listener to be notified when the flags on BubbleMetadata have changed. */
272     interface BubbleMetadataFlagListener {
273         /** Called when the flags on BubbleMetadata have changed for the provided bubble. */
onBubbleMetadataFlagChanged(Bubble bubble)274         void onBubbleMetadataFlagChanged(Bubble bubble);
275     }
276 
277     /** Listener to be notified when a pending intent has been canceled for a bubble. */
278     interface PendingIntentCanceledListener {
279         /** Called when the pending intent for a bubble has been canceled. */
onPendingIntentCanceled(Bubble bubble)280         void onPendingIntentCanceled(Bubble bubble);
281     }
282 
283     /** Callback to tell SysUi components execute some methods. */
284     interface SysuiProxy {
isNotificationPanelExpand(Consumer<Boolean> callback)285         void isNotificationPanelExpand(Consumer<Boolean> callback);
286 
getPendingOrActiveEntry(String key, Consumer<BubbleEntry> callback)287         void getPendingOrActiveEntry(String key, Consumer<BubbleEntry> callback);
288 
getShouldRestoredEntries(Set<String> savedBubbleKeys, Consumer<List<BubbleEntry>> callback)289         void getShouldRestoredEntries(Set<String> savedBubbleKeys,
290                 Consumer<List<BubbleEntry>> callback);
291 
setNotificationInterruption(String key)292         void setNotificationInterruption(String key);
293 
requestNotificationShadeTopUi(boolean requestTopUi, String componentTag)294         void requestNotificationShadeTopUi(boolean requestTopUi, String componentTag);
295 
notifyRemoveNotification(String key, int reason)296         void notifyRemoveNotification(String key, int reason);
297 
notifyInvalidateNotifications(String reason)298         void notifyInvalidateNotifications(String reason);
299 
updateNotificationBubbleButton(String key)300         void updateNotificationBubbleButton(String key);
301 
onStackExpandChanged(boolean shouldExpand)302         void onStackExpandChanged(boolean shouldExpand);
303 
onManageMenuExpandChanged(boolean menuExpanded)304         void onManageMenuExpandChanged(boolean menuExpanded);
305 
onUnbubbleConversation(String key)306         void onUnbubbleConversation(String key);
307     }
308 }
309