diff --git a/api/current.txt b/api/current.txt index ec00363112126..480ab9ba85bdb 100644 --- a/api/current.txt +++ b/api/current.txt @@ -27104,9 +27104,11 @@ package android.service.notification { method public final void cancelNotifications(java.lang.String[]); method public android.service.notification.StatusBarNotification[] getActiveNotifications(); method public android.service.notification.StatusBarNotification[] getActiveNotifications(java.lang.String[]); + method public final int getCurrentInterruptionFilter(); method public final int getCurrentListenerHints(); method public android.service.notification.NotificationListenerService.RankingMap getCurrentRanking(); method public android.os.IBinder onBind(android.content.Intent); + method public void onInterruptionFilterChanged(int); method public void onListenerConnected(); method public void onListenerHintsChanged(int); method public void onNotificationPosted(android.service.notification.StatusBarNotification); @@ -27114,13 +27116,12 @@ package android.service.notification { method public void onNotificationRankingUpdate(android.service.notification.NotificationListenerService.RankingMap); method public void onNotificationRemoved(android.service.notification.StatusBarNotification); method public void onNotificationRemoved(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap); + method public final void requestInterruptionFilter(int); method public final void requestListenerHints(int); - field public static final int HINTS_NONE = 0; // 0x0 - field public static final int HINT_HOST_DISABLE_EFFECTS = 4; // 0x4 - field public static final int HINT_HOST_INTERRUPTION_LEVEL_ALL = 1; // 0x1 - field public static final int HINT_HOST_INTERRUPTION_LEVEL_NONE = 3; // 0x3 - field public static final int HINT_HOST_INTERRUPTION_LEVEL_PRIORITY = 2; // 0x2 - field public static final int HOST_INTERRUPTION_LEVEL_MASK = 3; // 0x3 + field public static final int HINT_HOST_DISABLE_EFFECTS = 1; // 0x1 + field public static final int INTERRUPTION_FILTER_ALL = 1; // 0x1 + field public static final int INTERRUPTION_FILTER_NONE = 3; // 0x3 + field public static final int INTERRUPTION_FILTER_PRIORITY = 2; // 0x2 field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.NotificationListenerService"; } diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl index 07e9a94f307c8..214f50cbb3d9a 100644 --- a/core/java/android/app/INotificationManager.aidl +++ b/core/java/android/app/INotificationManager.aidl @@ -61,6 +61,8 @@ interface INotificationManager ParceledListSlice getActiveNotificationsFromListener(in INotificationListener token, in String[] keys); void requestHintsFromListener(in INotificationListener token, int hints); int getHintsFromListener(in INotificationListener token); + void requestInterruptionFilterFromListener(in INotificationListener token, int interruptionFilter); + int getInterruptionFilterFromListener(in INotificationListener token); ComponentName getEffectsSuppressor(); diff --git a/core/java/android/service/notification/INotificationListener.aidl b/core/java/android/service/notification/INotificationListener.aidl index 93b2d3bfadf80..8ca9b6cbd2a10 100644 --- a/core/java/android/service/notification/INotificationListener.aidl +++ b/core/java/android/service/notification/INotificationListener.aidl @@ -29,4 +29,5 @@ oneway interface INotificationListener in NotificationRankingUpdate update); void onNotificationRankingUpdate(in NotificationRankingUpdate update); void onListenerHintsChanged(int hints); -} \ No newline at end of file + void onInterruptionFilterChanged(int interruptionFilter); +} diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java index 450b9a797e6ce..a544b2dbe2534 100644 --- a/core/java/android/service/notification/NotificationListenerService.java +++ b/core/java/android/service/notification/NotificationListenerService.java @@ -58,26 +58,28 @@ public abstract class NotificationListenerService extends Service { private final String TAG = NotificationListenerService.class.getSimpleName() + "[" + getClass().getSimpleName() + "]"; - /** {@link #getCurrentListenerHints() Listener hints} constant - default state. */ - public static final int HINTS_NONE = 0; + /** + * {@link #getCurrentInterruptionFilter() Interruption filter} constant - + * Normal interruption filter. + */ + public static final int INTERRUPTION_FILTER_ALL = 1; - /** Bitmask range for {@link #getCurrentListenerHints() Listener hints} host interruption level - * constants. */ - public static final int HOST_INTERRUPTION_LEVEL_MASK = 0x3; + /** + * {@link #getCurrentInterruptionFilter() Interruption filter} constant - + * Priority interruption filter. + */ + public static final int INTERRUPTION_FILTER_PRIORITY = 2; - /** {@link #getCurrentListenerHints() Listener hints} constant - Normal interruption level. */ - public static final int HINT_HOST_INTERRUPTION_LEVEL_ALL = 1; - - /** {@link #getCurrentListenerHints() Listener hints} constant - Priority interruption level. */ - public static final int HINT_HOST_INTERRUPTION_LEVEL_PRIORITY = 2; - - /** {@link #getCurrentListenerHints() Listener hints} constant - No interruptions level. */ - public static final int HINT_HOST_INTERRUPTION_LEVEL_NONE = 3; + /** + * {@link #getCurrentInterruptionFilter() Interruption filter} constant - + * No interruptions filter. + */ + public static final int INTERRUPTION_FILTER_NONE = 3; /** {@link #getCurrentListenerHints() Listener hints} constant - the primary device UI * should disable notification sound, vibrating and other visual or aural effects. - * This does not change the interruption level, only the effects. **/ - public static final int HINT_HOST_DISABLE_EFFECTS = 1 << 2; + * This does not change the interruption filter, only the effects. **/ + public static final int HINT_HOST_DISABLE_EFFECTS = 1; private INotificationListenerWrapper mWrapper = null; private RankingMap mRankingMap; @@ -197,6 +199,17 @@ public abstract class NotificationListenerService extends Service { // optional } + /** + * Implement this method to be notified when the + * {@link #getCurrentInterruptionFilter() interruption filter} changed. + * + * @param interruptionFilter The current + * {@link #getCurrentInterruptionFilter() interruption filter}. + */ + public void onInterruptionFilterChanged(int interruptionFilter) { + // optional + } + private final INotificationManager getNotificationInterface() { if (mNoMan == null) { mNoMan = INotificationManager.Stub.asInterface( @@ -345,15 +358,42 @@ public abstract class NotificationListenerService extends Service { * shared across all listeners or a feature the notification host does not support or refuses * to grant. * - * @return One or more of the HINT_ constants. + * @return Zero or more of the HINT_ constants. */ public final int getCurrentListenerHints() { - if (!isBound()) return HINTS_NONE; + if (!isBound()) return 0; try { return getNotificationInterface().getHintsFromListener(mWrapper); } catch (android.os.RemoteException ex) { Log.v(TAG, "Unable to contact notification manager", ex); - return HINTS_NONE; + return 0; + } + } + + /** + * Gets the current notification interruption filter active on the host. + * + *
+ * The interruption filter defines which notifications are allowed to interrupt the user + * (e.g. via sound & vibration) and is applied globally. Listeners can find out whether + * a specific notification matched the interruption filter via + * {@link Ranking#matchesInterruptionFilter()}. + *
+ * The current filter may differ from the previously requested filter if the notification host + * does not support or refuses to apply the requested filter, or if another component changed + * the filter in the meantime. + *
+ * Listen for updates using {@link #onInterruptionFilterChanged(int)}. + * + * @return One of the INTERRUPTION_FILTER_ constants, or 0 on errors. + */ + public final int getCurrentInterruptionFilter() { + if (!isBound()) return 0; + try { + return getNotificationInterface().getHintsFromListener(mWrapper); + } catch (android.os.RemoteException ex) { + Log.v(TAG, "Unable to contact notification manager", ex); + return 0; } } @@ -361,7 +401,7 @@ public abstract class NotificationListenerService extends Service { * Sets the desired {@link #getCurrentListenerHints() listener hints}. * *
- * This is merely a request, the host may or not choose to take action depending + * This is merely a request, the host may or may not choose to take action depending * on other listener requests or other global state. *
* Listen for updates using {@link #onListenerHintsChanged(int)}. @@ -377,6 +417,27 @@ public abstract class NotificationListenerService extends Service { } } + /** + * Sets the desired {@link #getCurrentInterruptionFilter() interruption filter}. + * + *
+ * This is merely a request, the host may or may not choose to apply the requested + * interruption filter depending on other listener requests or other global state. + *
+ * Listen for updates using {@link #onInterruptionFilterChanged(int)}.
+ *
+ * @param interruptionFilter One of the INTERRUPTION_FILTER_ constants.
+ */
+ public final void requestInterruptionFilter(int interruptionFilter) {
+ if (!isBound()) return;
+ try {
+ getNotificationInterface()
+ .requestInterruptionFilterFromListener(mWrapper, interruptionFilter);
+ } catch (android.os.RemoteException ex) {
+ Log.v(TAG, "Unable to contact notification manager", ex);
+ }
+ }
+
/**
* Returns current ranking information.
*
@@ -514,6 +575,15 @@ public abstract class NotificationListenerService extends Service {
Log.w(TAG, "Error running onListenerHintsChanged", t);
}
}
+
+ @Override
+ public void onInterruptionFilterChanged(int interruptionFilter) throws RemoteException {
+ try {
+ NotificationListenerService.this.onInterruptionFilterChanged(interruptionFilter);
+ } catch (Throwable t) {
+ Log.w(TAG, "Error running onInterruptionFilterChanged", t);
+ }
+ }
}
private void applyUpdate(NotificationRankingUpdate update) {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 8c0d2c91cd20d..fc1b74690be2f 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -57,7 +57,6 @@ import android.os.IBinder;
import android.os.IInterface;
import android.os.Looper;
import android.os.Message;
-import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -127,6 +126,7 @@ public class NotificationManagerService extends SystemService {
static final int MESSAGE_RANKING_CONFIG_CHANGE = 5;
static final int MESSAGE_SEND_RANKING_UPDATE = 6;
static final int MESSAGE_LISTENER_HINTS_CHANGED = 7;
+ static final int MESSAGE_LISTENER_NOTIFICATION_FILTER_CHANGED = 8;
static final int LONG_DELAY = 3500; // 3.5 seconds
static final int SHORT_DELAY = 2000; // 2 seconds
@@ -178,6 +178,7 @@ public class NotificationManagerService extends SystemService {
private final ArraySet