1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5  * except in compliance with the License. You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the
10  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11  * KIND, either express or implied. See the License for the specific language governing
12  * permissions and limitations under the License.
13  */
14 
15 package com.android.systemui.plugins.statusbar;
16 
17 import android.annotation.Nullable;
18 import android.content.Context;
19 import android.graphics.Point;
20 import android.service.notification.StatusBarNotification;
21 import android.view.MotionEvent;
22 import android.view.View;
23 import android.view.ViewGroup;
24 
25 import com.android.systemui.plugins.Plugin;
26 import com.android.systemui.plugins.annotations.DependsOn;
27 import com.android.systemui.plugins.annotations.ProvidesInterface;
28 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem;
29 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.OnMenuEventListener;
30 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption;
31 
32 import java.util.ArrayList;
33 
34 @ProvidesInterface(action = NotificationMenuRowPlugin.ACTION,
35         version = NotificationMenuRowPlugin.VERSION)
36 @DependsOn(target = OnMenuEventListener.class)
37 @DependsOn(target = MenuItem.class)
38 @DependsOn(target = NotificationSwipeActionHelper.class)
39 @DependsOn(target = SnoozeOption.class)
40 public interface NotificationMenuRowPlugin extends Plugin {
41 
42     public static final String ACTION = "com.android.systemui.action.PLUGIN_NOTIFICATION_MENU_ROW";
43     public static final int VERSION = 5;
44 
45     @ProvidesInterface(version = OnMenuEventListener.VERSION)
46     public interface OnMenuEventListener {
47         public static final int VERSION = 1;
48 
onMenuClicked(View row, int x, int y, MenuItem menu)49         public void onMenuClicked(View row, int x, int y, MenuItem menu);
50 
onMenuReset(View row)51         public void onMenuReset(View row);
52 
onMenuShown(View row)53         public void onMenuShown(View row);
54     }
55 
56     @ProvidesInterface(version = MenuItem.VERSION)
57     public interface MenuItem {
58         public static final int VERSION = 1;
59 
getMenuView()60         public View getMenuView();
61 
getGutsView()62         public View getGutsView();
63 
getContentDescription()64         public String getContentDescription();
65     }
66 
67     /**
68      * @return a list of items to populate the menu 'behind' a notification.
69      */
getMenuItems(Context context)70     public ArrayList<MenuItem> getMenuItems(Context context);
71 
72     /**
73      * @return the {@link MenuItem} to display when a notification is long pressed.
74      */
getLongpressMenuItem(Context context)75     public MenuItem getLongpressMenuItem(Context context);
76 
77     /**
78      * @return the {@link MenuItem} to display when app ops icons are pressed.
79      */
getAppOpsMenuItem(Context context)80     public MenuItem getAppOpsMenuItem(Context context);
81 
82     /**
83      * @return the {@link MenuItem} to display when snooze item is pressed.
84      */
getSnoozeMenuItem(Context context)85     public MenuItem getSnoozeMenuItem(Context context);
86 
setMenuItems(ArrayList<MenuItem> items)87     public void setMenuItems(ArrayList<MenuItem> items);
88 
89     /**
90      * If this returns {@code true}, then the menu row will bind and fade in the notification guts
91      * view for the menu item it holds.
92      *
93      * @see #menuItemToExposeOnSnap()
94      * @return whether or not to immediately expose the notification guts
95      */
shouldShowGutsOnSnapOpen()96     default boolean shouldShowGutsOnSnapOpen() {
97         return false;
98     }
99 
100     /**
101      * When #shouldShowGutsOnExpose is true, this method must return the menu item to expose on
102      * #onSnapOpen. Otherwise we will fall back to the default behavior of fading in the menu row
103      *
104      * @return the {@link MenuItem} containing the NotificationGuts that should be exposed
105      */
106     @Nullable
menuItemToExposeOnSnap()107     default MenuItem menuItemToExposeOnSnap() {
108         return null;
109     }
110 
111     /**
112      * Get the origin for the circular reveal animation when expanding the notification guts. Only
113      * used when #shouldShowGutsOnSnapOpen is true
114      * @return the x,y coordinates for the start of the animation
115      */
116     @Nullable
getRevealAnimationOrigin()117     default Point getRevealAnimationOrigin() {
118         return new Point(0, 0);
119     }
120 
setMenuClickListener(OnMenuEventListener listener)121     public void setMenuClickListener(OnMenuEventListener listener);
122 
setAppName(String appName)123     public void setAppName(String appName);
124 
createMenu(ViewGroup parent, StatusBarNotification sbn)125     public void createMenu(ViewGroup parent, StatusBarNotification sbn);
126 
resetMenu()127     public void resetMenu();
128 
getMenuView()129     public View getMenuView();
130 
131     /**
132      * Get the target position that a notification row should be snapped open to in order to reveal
133      * the menu. This is generally determined by the number of icons in the notification menu and the
134      * size of each icon. This method accounts for whether the menu appears on the left or ride side
135      * of the parent notification row.
136      *
137 
138      * @return an int representing the x-offset in pixels that the notification should snap open to.
139      * Positive values imply that the notification should be offset to the right to reveal the menu,
140      * and negative alues imply that the notification should be offset to the right.
141      */
getMenuSnapTarget()142     public int getMenuSnapTarget();
143 
144     /**
145      * Determines whether or not the menu should be shown in response to user input.
146      * @return true if the menu should be shown, false otherwise.
147      */
shouldShowMenu()148     public boolean shouldShowMenu();
149 
150     /**
151      * Determines whether the menu is currently visible.
152      * @return true if the menu is visible, false otherwise.
153      */
isMenuVisible()154     public boolean isMenuVisible();
155 
156     /**
157      * Determines whether a given movement is towards or away from the current location of the menu.
158      * @param movement
159      * @return true if the movement is towards the menu, false otherwise.
160      */
isTowardsMenu(float movement)161     public boolean isTowardsMenu(float movement);
162 
163     /**
164      * Determines whether the menu should snap closed instead of dismissing the
165      * parent notification, as a function of its current state.
166      *
167      * @return true if the menu should snap closed, false otherwise.
168      */
shouldSnapBack()169     public boolean shouldSnapBack();
170 
171     /**
172      * Determines whether the menu was previously snapped open to the same side that it is currently
173      * being shown on.
174      * @return true if the menu is snapped open to the same side on which it currently appears,
175      * false otherwise.
176      */
isSnappedAndOnSameSide()177     public boolean isSnappedAndOnSameSide();
178 
179     /**
180      * Determines whether the notification the menu is attached to is able to be dismissed.
181      * @return true if the menu's parent notification is dismissable, false otherwise.
182      */
canBeDismissed()183     public boolean canBeDismissed();
184 
185     /**
186      * Informs the menu whether dismiss gestures are left-to-right or right-to-left.
187      */
setDismissRtl(boolean dismissRtl)188     default void setDismissRtl(boolean dismissRtl) {
189     }
190 
191     /**
192      * Determines whether the menu should remain open given its current state, or snap closed.
193      * @return true if the menu should remain open, false otherwise.
194      */
isWithinSnapMenuThreshold()195     public boolean isWithinSnapMenuThreshold();
196 
197     /**
198      * Determines whether the menu has been swiped far enough to snap open.
199      * @return true if the menu has been swiped far enough to open, false otherwise.
200      */
isSwipedEnoughToShowMenu()201     public boolean isSwipedEnoughToShowMenu();
202 
onInterceptTouchEvent(View view, MotionEvent ev)203     public default boolean onInterceptTouchEvent(View view, MotionEvent ev) {
204         return false;
205     }
206 
shouldUseDefaultMenuItems()207     public default boolean shouldUseDefaultMenuItems() {
208         return false;
209     }
210 
211     /**
212      * Callback used to signal the menu that its parent's translation has changed.
213      * @param translation The new x-translation of the menu as a position (not an offset).
214      */
onParentTranslationUpdate(float translation)215     public void onParentTranslationUpdate(float translation);
216 
217     /**
218      * Callback used to signal the menu that its parent's height has changed.
219      */
onParentHeightUpdate()220     public void onParentHeightUpdate();
221 
222     /**
223      * Callback used to signal the menu that its parent notification has been updated.
224      * @param sbn
225      */
onNotificationUpdated(StatusBarNotification sbn)226     public void onNotificationUpdated(StatusBarNotification sbn);
227 
228     /**
229      * Callback used to signal the menu that a user is moving the parent notification.
230      * @param delta The change in the parent notification's position.
231      */
onTouchMove(float delta)232     public void onTouchMove(float delta);
233 
234     /**
235      * Callback used to signal the menu that a user has begun touching its parent notification.
236      */
onTouchStart()237     public void onTouchStart();
238 
239     /**
240      * Callback used to signal the menu that a user has finished touching its parent notification.
241      */
onTouchEnd()242     public void onTouchEnd();
243 
244     /**
245      * Callback used to signal the menu that it has been snapped closed.
246      */
onSnapClosed()247     public void onSnapClosed();
248 
249     /**
250      * Callback used to signal the menu that it has been snapped open.
251      */
onSnapOpen()252     public void onSnapOpen();
253 
254     /**
255      * Callback used to signal the menu that its parent notification has been dismissed.
256      */
onDismiss()257     public void onDismiss();
258 
onConfigurationChanged()259     public default void onConfigurationChanged() { }
260 
261 }
262