am 8028a5a8: am 752dc6e1: New NotificationListenerService listener flags api.
* commit '8028a5a8a3f17e54fe6a5d28c50683def1473b9c': New NotificationListenerService listener flags api.
This commit is contained in:
@@ -27226,14 +27226,19 @@ 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 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 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
|
||||
field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.NotificationListenerService";
|
||||
}
|
||||
|
||||
|
||||
@@ -59,6 +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);
|
||||
|
||||
ZenModeConfig getZenModeConfig();
|
||||
boolean setZenModeConfig(in ZenModeConfig config);
|
||||
|
||||
@@ -28,4 +28,5 @@ oneway interface INotificationListener
|
||||
void onNotificationRemoved(in StatusBarNotification notification,
|
||||
in NotificationRankingUpdate update);
|
||||
void onNotificationRankingUpdate(in NotificationRankingUpdate update);
|
||||
void onListenerFlagsChanged(int flags);
|
||||
}
|
||||
@@ -53,6 +53,12 @@ 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;
|
||||
|
||||
private INotificationListenerWrapper mWrapper = null;
|
||||
private RankingMap mRankingMap;
|
||||
|
||||
@@ -156,6 +162,16 @@ public abstract class NotificationListenerService extends Service {
|
||||
// optional
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement this method to be notified when the
|
||||
* {@link #getCurrentListenerFlags() listener flags} change.
|
||||
*
|
||||
* @param flags The current {@link #getCurrentListenerFlags() listener flags}.
|
||||
*/
|
||||
public void onListenerFlagsChanged(int flags) {
|
||||
// optional
|
||||
}
|
||||
|
||||
private final INotificationManager getNotificationInterface() {
|
||||
if (mNoMan == null) {
|
||||
mNoMan = INotificationManager.Stub.asInterface(
|
||||
@@ -278,6 +294,46 @@ public abstract class NotificationListenerService extends Service {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the set of flags representing current state.
|
||||
*
|
||||
* <p>
|
||||
* The current state may differ from the requested state if the flag 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.
|
||||
*/
|
||||
public final int getCurrentListenerFlags() {
|
||||
if (!isBound()) return FLAG_NONE;
|
||||
try {
|
||||
return getNotificationInterface().getFlagsFromListener(mWrapper);
|
||||
} catch (android.os.RemoteException ex) {
|
||||
Log.v(TAG, "Unable to contact notification manager", ex);
|
||||
return FLAG_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the desired {@link #getCurrentListenerFlags() listener flags}.
|
||||
*
|
||||
* <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)}.
|
||||
*
|
||||
* @param flags One or more of the FLAG_ constants.
|
||||
*/
|
||||
public final void requestListenerFlags(int flags) {
|
||||
if (!isBound()) return;
|
||||
try {
|
||||
getNotificationInterface().requestFlagsFromListener(mWrapper, flags);
|
||||
} catch (android.os.RemoteException ex) {
|
||||
Log.v(TAG, "Unable to contact notification manager", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns current ranking information.
|
||||
*
|
||||
@@ -402,6 +458,14 @@ public abstract class NotificationListenerService extends Service {
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onListenerFlagsChanged(int flags) throws RemoteException {
|
||||
try {
|
||||
NotificationListenerService.this.onListenerFlagsChanged(flags);
|
||||
} catch (Throwable t) {
|
||||
Log.w(TAG, "Error running onListenerFlagsChanged", t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void applyUpdate(NotificationRankingUpdate update) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.server.notification;
|
||||
|
||||
import static android.service.notification.NotificationListenerService.FLAG_DISABLE_HOST_ALERTS;
|
||||
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
|
||||
import static org.xmlpull.v1.XmlPullParser.END_TAG;
|
||||
import static org.xmlpull.v1.XmlPullParser.START_TAG;
|
||||
@@ -71,6 +72,7 @@ import android.service.notification.ZenModeConfig;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.AtomicFile;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
@@ -121,6 +123,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 LONG_DELAY = 3500; // 3.5 seconds
|
||||
static final int SHORT_DELAY = 2000; // 2 seconds
|
||||
@@ -169,6 +172,9 @@ public class NotificationManagerService extends SystemService {
|
||||
NotificationRecord mSoundNotification;
|
||||
NotificationRecord mVibrateNotification;
|
||||
|
||||
private final ArraySet<ManagedServiceInfo> mListenersDisablingAlerts = new ArraySet<>();
|
||||
private int mListenerFlags; // right now, all flags are global
|
||||
|
||||
// for enabling and disabling notification pulse behavior
|
||||
private boolean mScreenOn = true;
|
||||
private boolean mInCall = false;
|
||||
@@ -463,7 +469,7 @@ public class NotificationManagerService extends SystemService {
|
||||
public void onSetDisabled(int status) {
|
||||
synchronized (mNotificationList) {
|
||||
mDisableNotificationAlerts = (status & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0;
|
||||
if (mDisableNotificationAlerts) {
|
||||
if (disableNotificationAlerts()) {
|
||||
// cancel whatever's going on
|
||||
long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
@@ -904,6 +910,13 @@ 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 final IBinder mService = new INotificationManager.Stub() {
|
||||
// Toasts
|
||||
// ============================================================================
|
||||
@@ -1248,6 +1261,27 @@ 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);
|
||||
}
|
||||
updateListenerFlagsLocked();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFlagsFromListener(INotificationListener token) {
|
||||
synchronized (mNotificationList) {
|
||||
return mListenerFlags;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ZenModeConfig getZenModeConfig() {
|
||||
enforceSystemOrSystemUI("INotificationManager.getZenModeConfig");
|
||||
@@ -1339,6 +1373,10 @@ public class NotificationManagerService extends SystemService {
|
||||
return keys.toArray(new String[keys.size()]);
|
||||
}
|
||||
|
||||
private boolean disableNotificationAlerts() {
|
||||
return mDisableNotificationAlerts || (mListenerFlags & FLAG_DISABLE_HOST_ALERTS) != 0;
|
||||
}
|
||||
|
||||
void dumpImpl(PrintWriter pw, DumpFilter filter) {
|
||||
pw.print("Current Notification Manager state");
|
||||
if (filter != null) {
|
||||
@@ -1422,6 +1460,15 @@ 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();
|
||||
for (int i = 0; i < N; i++) {
|
||||
final ManagedServiceInfo listener = mListenersDisablingAlerts.valueAt(i);
|
||||
if (i > 0) pw.print(',');
|
||||
pw.print(listener.component);
|
||||
}
|
||||
pw.println(')');
|
||||
}
|
||||
|
||||
pw.println("\n Condition providers:");
|
||||
@@ -1618,7 +1665,7 @@ public class NotificationManagerService extends SystemService {
|
||||
}
|
||||
|
||||
// If we're not supposed to beep, vibrate, etc. then don't.
|
||||
if (!mDisableNotificationAlerts
|
||||
if (!disableNotificationAlerts()
|
||||
&& (!(record.isUpdate
|
||||
&& (notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0 ))
|
||||
&& (record.getUserId() == UserHandle.USER_ALL ||
|
||||
@@ -1920,6 +1967,17 @@ 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 handleListenerFlagsChanged(int state) {
|
||||
synchronized (mNotificationList) {
|
||||
mListeners.notifyListenerFlagsChangedLocked(state);
|
||||
}
|
||||
}
|
||||
|
||||
private final class WorkerHandler extends Handler
|
||||
{
|
||||
@Override
|
||||
@@ -1936,6 +1994,9 @@ public class NotificationManagerService extends SystemService {
|
||||
case MESSAGE_SEND_RANKING_UPDATE:
|
||||
handleSendRankingUpdate();
|
||||
break;
|
||||
case MESSAGE_LISTENER_FLAGS_CHANGED:
|
||||
handleListenerFlagsChanged(msg.arg1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2445,6 +2506,13 @@ public class NotificationManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onServiceRemovedLocked(ManagedServiceInfo removed) {
|
||||
if (mListenersDisablingAlerts.remove(removed)) {
|
||||
updateListenerFlagsLocked();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* asynchronously notify all listeners about a new notification
|
||||
*/
|
||||
@@ -2509,6 +2577,20 @@ public class NotificationManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
public void notifyListenerFlagsChangedLocked(final int flags) {
|
||||
for (final ManagedServiceInfo serviceInfo : mServices) {
|
||||
if (!serviceInfo.isEnabledForCurrentProfiles()) {
|
||||
continue;
|
||||
}
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
notifyListenerFlagsChanged(serviceInfo, flags);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyPostedIfUserMatch(final ManagedServiceInfo info,
|
||||
final StatusBarNotification sbn, NotificationRankingUpdate rankingUpdate) {
|
||||
if (!info.enabledAndUserMatches(sbn.getUserId())) {
|
||||
@@ -2544,6 +2626,15 @@ public class NotificationManagerService extends SystemService {
|
||||
Log.e(TAG, "unable to notify listener (ranking update): " + listener, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyListenerFlagsChanged(ManagedServiceInfo info, int state) {
|
||||
final INotificationListener listener = (INotificationListener) info.service;
|
||||
try {
|
||||
listener.onListenerFlagsChanged(state);
|
||||
} catch (RemoteException ex) {
|
||||
Log.e(TAG, "unable to notify listener (listener flags): " + listener, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static final class DumpFilter {
|
||||
|
||||
Reference in New Issue
Block a user