summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt14
-rw-r--r--core/java/android/app/INotificationManager.aidl4
-rw-r--r--core/java/android/service/notification/INotificationListener.aidl2
-rw-r--r--core/java/android/service/notification/NotificationListenerService.java61
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java107
-rw-r--r--services/core/java/com/android/server/notification/ZenModeHelper.java35
6 files changed, 146 insertions, 77 deletions
diff --git a/api/current.txt b/api/current.txt
index da1ebae..8514584 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -27450,19 +27450,23 @@ package android.service.notification {
method public final void cancelNotification(java.lang.String);
method public final void cancelNotifications(java.lang.String[]);
method public android.service.notification.StatusBarNotification[] getActiveNotifications();
- method public final int getCurrentListenerFlags();
+ 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 onListenerConnected();
- method public void onListenerFlagsChanged(int);
+ method public void onListenerHintsChanged(int);
method public void onNotificationPosted(android.service.notification.StatusBarNotification);
method public void onNotificationPosted(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap);
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 requestListenerFlags(int);
- field public static final int FLAG_DISABLE_HOST_ALERTS = 1; // 0x1
- field public static final int FLAG_NONE = 0; // 0x0
+ 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 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 113c533..4b65934 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -59,8 +59,8 @@ interface INotificationManager
void cancelNotificationsFromListener(in INotificationListener token, in String[] keys);
ParceledListSlice getActiveNotificationsFromListener(in INotificationListener token);
- void requestFlagsFromListener(in INotificationListener token, int flags);
- int getFlagsFromListener(in INotificationListener token);
+ void requestHintsFromListener(in INotificationListener token, int hints);
+ int getHintsFromListener(in INotificationListener token);
ZenModeConfig getZenModeConfig();
boolean setZenModeConfig(in ZenModeConfig config);
diff --git a/core/java/android/service/notification/INotificationListener.aidl b/core/java/android/service/notification/INotificationListener.aidl
index 19a8ef5..93b2d3b 100644
--- a/core/java/android/service/notification/INotificationListener.aidl
+++ b/core/java/android/service/notification/INotificationListener.aidl
@@ -28,5 +28,5 @@ oneway interface INotificationListener
void onNotificationRemoved(in StatusBarNotification notification,
in NotificationRankingUpdate update);
void onNotificationRankingUpdate(in NotificationRankingUpdate update);
- void onListenerFlagsChanged(int flags);
+ void onListenerHintsChanged(int hints);
} \ No newline at end of file
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index f807ad6..119f7f6 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -58,11 +58,26 @@ public abstract class NotificationListenerService extends Service {
private final String TAG = NotificationListenerService.class.getSimpleName()
+ "[" + getClass().getSimpleName() + "]";
- /** {@link #getCurrentListenerFlags() Listener flags} constant - default state. **/
- public static final int FLAG_NONE = 0;
- /** {@link #getCurrentListenerFlags() Listener flags} constant - the primary device UI
- * should disable notification sound, vibrating and other visual or aural effects. **/
- public static final int FLAG_DISABLE_HOST_ALERTS = 1;
+ /** {@link #getCurrentListenerHints() Listener hints} constant - default state. */
+ public static final int HINTS_NONE = 0;
+
+ /** Bitmask range for {@link #getCurrentListenerHints() Listener hints} host interruption level
+ * constants. */
+ public static final int HOST_INTERRUPTION_LEVEL_MASK = 0x3;
+
+ /** {@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 #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;
private INotificationListenerWrapper mWrapper = null;
private RankingMap mRankingMap;
@@ -174,11 +189,11 @@ public abstract class NotificationListenerService extends Service {
/**
* Implement this method to be notified when the
- * {@link #getCurrentListenerFlags() listener flags} change.
+ * {@link #getCurrentListenerHints() Listener hints} change.
*
- * @param flags The current {@link #getCurrentListenerFlags() listener flags}.
+ * @param hints The current {@link #getCurrentListenerHints() listener hints}.
*/
- public void onListenerFlagsChanged(int flags) {
+ public void onListenerHintsChanged(int hints) {
// optional
}
@@ -311,40 +326,40 @@ public abstract class NotificationListenerService extends Service {
}
/**
- * Gets the set of flags representing current state.
+ * Gets the set of hints representing current state.
*
* <p>
- * The current state may differ from the requested state if the flag represents state
+ * The current state may differ from the requested state if the hint represents state
* shared across all listeners or a feature the notification host does not support or refuses
* to grant.
*
- * @return One or more of the FLAG_ constants.
+ * @return One or more of the HINT_ constants.
*/
- public final int getCurrentListenerFlags() {
- if (!isBound()) return FLAG_NONE;
+ public final int getCurrentListenerHints() {
+ if (!isBound()) return HINTS_NONE;
try {
- return getNotificationInterface().getFlagsFromListener(mWrapper);
+ return getNotificationInterface().getHintsFromListener(mWrapper);
} catch (android.os.RemoteException ex) {
Log.v(TAG, "Unable to contact notification manager", ex);
- return FLAG_NONE;
+ return HINTS_NONE;
}
}
/**
- * Sets the desired {@link #getCurrentListenerFlags() listener flags}.
+ * Sets the desired {@link #getCurrentListenerHints() listener hints}.
*
* <p>
* This is merely a request, the host may or not choose to take action depending
* on other listener requests or other global state.
* <p>
- * Listen for updates using {@link #onListenerFlagsChanged(int)}.
+ * Listen for updates using {@link #onListenerHintsChanged(int)}.
*
- * @param flags One or more of the FLAG_ constants.
+ * @param hints One or more of the HINT_ constants.
*/
- public final void requestListenerFlags(int flags) {
+ public final void requestListenerHints(int hints) {
if (!isBound()) return;
try {
- getNotificationInterface().requestFlagsFromListener(mWrapper, flags);
+ getNotificationInterface().requestHintsFromListener(mWrapper, hints);
} catch (android.os.RemoteException ex) {
Log.v(TAG, "Unable to contact notification manager", ex);
}
@@ -480,11 +495,11 @@ public abstract class NotificationListenerService extends Service {
}
}
@Override
- public void onListenerFlagsChanged(int flags) throws RemoteException {
+ public void onListenerHintsChanged(int hints) throws RemoteException {
try {
- NotificationListenerService.this.onListenerFlagsChanged(flags);
+ NotificationListenerService.this.onListenerHintsChanged(hints);
} catch (Throwable t) {
- Log.w(TAG, "Error running onListenerFlagsChanged", t);
+ Log.w(TAG, "Error running onListenerHintsChanged", t);
}
}
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 743abc8..3eb2b7e 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -16,7 +16,7 @@
package com.android.server.notification;
-import static android.service.notification.NotificationListenerService.FLAG_DISABLE_HOST_ALERTS;
+import static android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_EFFECTS;
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import static org.xmlpull.v1.XmlPullParser.END_TAG;
import static org.xmlpull.v1.XmlPullParser.START_TAG;
@@ -125,7 +125,7 @@ public class NotificationManagerService extends SystemService {
static final int MESSAGE_RECONSIDER_RANKING = 4;
static final int MESSAGE_RANKING_CONFIG_CHANGE = 5;
static final int MESSAGE_SEND_RANKING_UPDATE = 6;
- static final int MESSAGE_LISTENER_FLAGS_CHANGED = 7;
+ static final int MESSAGE_LISTENER_HINTS_CHANGED = 7;
static final int LONG_DELAY = 3500; // 3.5 seconds
static final int SHORT_DELAY = 2000; // 2 seconds
@@ -170,12 +170,12 @@ public class NotificationManagerService extends SystemService {
private boolean mUseAttentionLight;
boolean mSystemReady;
- private boolean mDisableNotificationAlerts;
+ private boolean mDisableNotificationEffects;
NotificationRecord mSoundNotification;
NotificationRecord mVibrateNotification;
- private final ArraySet<ManagedServiceInfo> mListenersDisablingAlerts = new ArraySet<>();
- private int mListenerFlags; // right now, all flags are global
+ private final ArraySet<ManagedServiceInfo> mListenersDisablingEffects = new ArraySet<>();
+ private int mListenerHints; // right now, all hints are global
// for enabling and disabling notification pulse behavior
private boolean mScreenOn = true;
@@ -470,8 +470,9 @@ public class NotificationManagerService extends SystemService {
@Override
public void onSetDisabled(int status) {
synchronized (mNotificationList) {
- mDisableNotificationAlerts = (status & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0;
- if (disableNotificationAlerts()) {
+ mDisableNotificationEffects =
+ (status & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0;
+ if (disableNotificationEffects()) {
// cancel whatever's going on
long identity = Binder.clearCallingIdentity();
try {
@@ -804,6 +805,13 @@ public class NotificationManagerService extends SystemService {
public void onConfigChanged() {
savePolicyFile();
}
+
+ @Override
+ void onZenModeChanged() {
+ synchronized(mNotificationList) {
+ updateListenerHintsLocked();
+ }
+ }
});
final File systemDir = new File(Environment.getDataDirectory(), "system");
mPolicyFile = new AtomicFile(new File(systemDir, "notification_policy.xml"));
@@ -846,7 +854,7 @@ public class NotificationManagerService extends SystemService {
// flag at least once and we'll go back to 0 after that.
if (0 == Settings.Global.getInt(getContext().getContentResolver(),
Settings.Global.DEVICE_PROVISIONED, 0)) {
- mDisableNotificationAlerts = true;
+ mDisableNotificationEffects = true;
}
mZenModeHelper.updateZenMode();
@@ -932,11 +940,12 @@ public class NotificationManagerService extends SystemService {
}
}
- private void updateListenerFlagsLocked() {
- final int flags = mListenersDisablingAlerts.isEmpty() ? 0 : FLAG_DISABLE_HOST_ALERTS;
- if (flags == mListenerFlags) return;
- mListenerFlags = flags;
- scheduleListenerFlagsChanged(flags);
+ private void updateListenerHintsLocked() {
+ final int hints = (mListenersDisablingEffects.isEmpty() ? 0 : HINT_HOST_DISABLE_EFFECTS) |
+ mZenModeHelper.getZenModeListenerHint();
+ if (hints == mListenerHints) return;
+ mListenerHints = hints;
+ scheduleListenerHintsChanged(hints);
}
private final IBinder mService = new INotificationManager.Stub() {
@@ -1284,23 +1293,29 @@ public class NotificationManagerService extends SystemService {
}
@Override
- public void requestFlagsFromListener(INotificationListener token, int flags) {
- synchronized (mNotificationList) {
- final ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token);
- final boolean disableAlerts = (flags & FLAG_DISABLE_HOST_ALERTS) != 0;
- if (disableAlerts) {
- mListenersDisablingAlerts.add(info);
- } else {
- mListenersDisablingAlerts.remove(info);
+ public void requestHintsFromListener(INotificationListener token, int hints) {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ synchronized (mNotificationList) {
+ final ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token);
+ final boolean disableEffects = (hints & HINT_HOST_DISABLE_EFFECTS) != 0;
+ if (disableEffects) {
+ mListenersDisablingEffects.add(info);
+ } else {
+ mListenersDisablingEffects.remove(info);
+ }
+ mZenModeHelper.requestFromListener(hints);
+ updateListenerHintsLocked();
}
- updateListenerFlagsLocked();
+ } finally {
+ Binder.restoreCallingIdentity(identity);
}
}
@Override
- public int getFlagsFromListener(INotificationListener token) {
+ public int getHintsFromListener(INotificationListener token) {
synchronized (mNotificationList) {
- return mListenerFlags;
+ return mListenerHints;
}
}
@@ -1395,8 +1410,8 @@ public class NotificationManagerService extends SystemService {
return keys.toArray(new String[keys.size()]);
}
- private boolean disableNotificationAlerts() {
- return mDisableNotificationAlerts || (mListenerFlags & FLAG_DISABLE_HOST_ALERTS) != 0;
+ private boolean disableNotificationEffects() {
+ return mDisableNotificationEffects || (mListenerHints & HINT_HOST_DISABLE_EFFECTS) != 0;
}
void dumpImpl(PrintWriter pw, DumpFilter filter) {
@@ -1447,7 +1462,7 @@ public class NotificationManagerService extends SystemService {
pw.println(" mNotificationPulseEnabled=" + mNotificationPulseEnabled);
pw.println(" mSoundNotification=" + mSoundNotification);
pw.println(" mVibrateNotification=" + mVibrateNotification);
- pw.println(" mDisableNotificationAlerts=" + mDisableNotificationAlerts);
+ pw.println(" mDisableNotificationEffects=" + mDisableNotificationEffects);
pw.println(" mSystemReady=" + mSystemReady);
}
pw.println(" mArchive=" + mArchive.toString());
@@ -1483,11 +1498,11 @@ public class NotificationManagerService extends SystemService {
pw.println("\n Notification listeners:");
mListeners.dump(pw, filter);
- pw.print(" mListenerFlags: "); pw.println(mListenerFlags);
- pw.print(" mListenersDisablingAlerts: (");
- N = mListenersDisablingAlerts.size();
+ pw.print(" mListenerHints: "); pw.println(mListenerHints);
+ pw.print(" mListenersDisablingEffects: (");
+ N = mListenersDisablingEffects.size();
for (int i = 0; i < N; i++) {
- final ManagedServiceInfo listener = mListenersDisablingAlerts.valueAt(i);
+ final ManagedServiceInfo listener = mListenersDisablingEffects.valueAt(i);
if (i > 0) pw.print(',');
pw.print(listener.component);
}
@@ -1705,7 +1720,7 @@ public class NotificationManagerService extends SystemService {
}
// If we're not supposed to beep, vibrate, etc. then don't.
- if (!disableNotificationAlerts()
+ if (!disableNotificationEffects()
&& (!(record.isUpdate
&& (notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0 ))
&& (record.getUserId() == UserHandle.USER_ALL ||
@@ -2021,14 +2036,14 @@ public class NotificationManagerService extends SystemService {
}
}
- private void scheduleListenerFlagsChanged(int state) {
- mHandler.removeMessages(MESSAGE_LISTENER_FLAGS_CHANGED);
- mHandler.obtainMessage(MESSAGE_LISTENER_FLAGS_CHANGED, state, 0).sendToTarget();
+ private void scheduleListenerHintsChanged(int state) {
+ mHandler.removeMessages(MESSAGE_LISTENER_HINTS_CHANGED);
+ mHandler.obtainMessage(MESSAGE_LISTENER_HINTS_CHANGED, state, 0).sendToTarget();
}
- private void handleListenerFlagsChanged(int state) {
+ private void handleListenerHintsChanged(int hints) {
synchronized (mNotificationList) {
- mListeners.notifyListenerFlagsChangedLocked(state);
+ mListeners.notifyListenerHintsChangedLocked(hints);
}
}
@@ -2048,8 +2063,8 @@ public class NotificationManagerService extends SystemService {
case MESSAGE_SEND_RANKING_UPDATE:
handleSendRankingUpdate();
break;
- case MESSAGE_LISTENER_FLAGS_CHANGED:
- handleListenerFlagsChanged(msg.arg1);
+ case MESSAGE_LISTENER_HINTS_CHANGED:
+ handleListenerHintsChanged(msg.arg1);
break;
}
}
@@ -2570,8 +2585,8 @@ public class NotificationManagerService extends SystemService {
@Override
protected void onServiceRemovedLocked(ManagedServiceInfo removed) {
- if (mListenersDisablingAlerts.remove(removed)) {
- updateListenerFlagsLocked();
+ if (mListenersDisablingEffects.remove(removed)) {
+ updateListenerHintsLocked();
}
}
@@ -2655,7 +2670,7 @@ public class NotificationManagerService extends SystemService {
}
}
- public void notifyListenerFlagsChangedLocked(final int flags) {
+ public void notifyListenerHintsChangedLocked(final int hints) {
for (final ManagedServiceInfo serviceInfo : mServices) {
if (!serviceInfo.isEnabledForCurrentProfiles()) {
continue;
@@ -2663,7 +2678,7 @@ public class NotificationManagerService extends SystemService {
mHandler.post(new Runnable() {
@Override
public void run() {
- notifyListenerFlagsChanged(serviceInfo, flags);
+ notifyListenerHintsChanged(serviceInfo, hints);
}
});
}
@@ -2702,12 +2717,12 @@ public class NotificationManagerService extends SystemService {
}
}
- private void notifyListenerFlagsChanged(ManagedServiceInfo info, int state) {
+ private void notifyListenerHintsChanged(ManagedServiceInfo info, int hints) {
final INotificationListener listener = (INotificationListener) info.service;
try {
- listener.onListenerFlagsChanged(state);
+ listener.onListenerHintsChanged(hints);
} catch (RemoteException ex) {
- Log.e(TAG, "unable to notify listener (listener flags): " + listener, ex);
+ Log.e(TAG, "unable to notify listener (listener hints): " + listener, ex);
}
}
}
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 9f97583..9282283 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -41,6 +41,7 @@ import android.os.IBinder;
import android.os.UserHandle;
import android.provider.Settings.Global;
import android.provider.Settings.Secure;
+import android.service.notification.NotificationListenerService;
import android.service.notification.ZenModeConfig;
import android.telecomm.TelecommManager;
import android.util.Slog;
@@ -125,6 +126,40 @@ public class ZenModeHelper {
mAudioManager = audioManager;
}
+ public int getZenModeListenerHint() {
+ switch(mZenMode) {
+ case Global.ZEN_MODE_OFF:
+ return NotificationListenerService.HINT_HOST_INTERRUPTION_LEVEL_ALL;
+ case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
+ return NotificationListenerService.HINT_HOST_INTERRUPTION_LEVEL_PRIORITY;
+ case Global.ZEN_MODE_NO_INTERRUPTIONS:
+ return NotificationListenerService.HINT_HOST_INTERRUPTION_LEVEL_NONE;
+ default:
+ return 0;
+ }
+ }
+
+ private static int zenFromListenerHint(int hints, int defValue) {
+ final int level = hints & NotificationListenerService.HOST_INTERRUPTION_LEVEL_MASK;
+ switch(level) {
+ case NotificationListenerService.HINT_HOST_INTERRUPTION_LEVEL_ALL:
+ return Global.ZEN_MODE_OFF;
+ case NotificationListenerService.HINT_HOST_INTERRUPTION_LEVEL_PRIORITY:
+ return Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ case NotificationListenerService.HINT_HOST_INTERRUPTION_LEVEL_NONE:
+ return Global.ZEN_MODE_NO_INTERRUPTIONS;
+ default:
+ return defValue;
+ }
+ }
+
+ public void requestFromListener(int hints) {
+ final int newZen = zenFromListenerHint(hints, -1);
+ if (newZen != -1) {
+ setZenMode(newZen);
+ }
+ }
+
public boolean shouldIntercept(NotificationRecord record) {
if (mZenMode != Global.ZEN_MODE_OFF) {
if (isSystem(record)) {