OSDN Git Service

Disable notification effects during phone calls.
authorJohn Spurlock <jspurlock@google.com>
Thu, 2 Oct 2014 16:16:02 +0000 (12:16 -0400)
committerJohn Spurlock <jspurlock@google.com>
Fri, 3 Oct 2014 01:05:06 +0000 (21:05 -0400)
Listen for phone call state changes in NoMan, and disable
incoming non-call notification effects when non-idle.

Bug:17658454
Change-Id: I6f7d66413970fbff6822ab29a12f91cbed068261

services/core/java/com/android/server/notification/NotificationManagerService.java
services/core/java/com/android/server/notification/ZenLog.java
services/core/java/com/android/server/notification/ZenModeHelper.java

index d8e5a98..22f060f 100644 (file)
@@ -75,6 +75,7 @@ import android.service.notification.NotificationListenerService;
 import android.service.notification.NotificationRankingUpdate;
 import android.service.notification.StatusBarNotification;
 import android.service.notification.ZenModeConfig;
+import android.telephony.PhoneStateListener;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.ArrayMap;
@@ -187,6 +188,7 @@ public class NotificationManagerService extends SystemService {
     boolean mSystemReady;
 
     private boolean mDisableNotificationEffects;
+    private int mCallState;
     NotificationRecord mSoundNotification;
     NotificationRecord mVibrateNotification;
 
@@ -490,7 +492,7 @@ public class NotificationManagerService extends SystemService {
             synchronized (mNotificationList) {
                 mDisableNotificationEffects =
                         (status & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0;
-                if (disableNotificationEffects()) {
+                if (disableNotificationEffects(null) != null) {
                     // cancel whatever's going on
                     long identity = Binder.clearCallingIdentity();
                     try {
@@ -875,6 +877,7 @@ public class NotificationManagerService extends SystemService {
         mZenModeHelper.updateZenMode();
 
         mUserProfiles.updateCache(getContext());
+        listenForCallState();
 
         // register for various Intents
         IntentFilter filter = new IntentFilter();
@@ -1510,8 +1513,17 @@ public class NotificationManagerService extends SystemService {
         return keys.toArray(new String[keys.size()]);
     }
 
-    private boolean disableNotificationEffects() {
-        return mDisableNotificationEffects || (mListenerHints & HINT_HOST_DISABLE_EFFECTS) != 0;
+    private String disableNotificationEffects(NotificationRecord record) {
+        if (mDisableNotificationEffects) {
+            return "booleanState";
+        }
+        if ((mListenerHints & HINT_HOST_DISABLE_EFFECTS) != 0) {
+            return "listenerHints";
+        }
+        if (mCallState != TelephonyManager.CALL_STATE_IDLE && !mZenModeHelper.isCall(record)) {
+            return "callState";
+        }
+        return null;
     }
 
     void dumpImpl(PrintWriter pw, DumpFilter filter) {
@@ -1563,6 +1575,7 @@ public class NotificationManagerService extends SystemService {
                     pw.println("  mSoundNotification=" + mSoundNotification);
                     pw.println("  mVibrateNotification=" + mVibrateNotification);
                     pw.println("  mDisableNotificationEffects=" + mDisableNotificationEffects);
+                    pw.println("  mCallState=" + callStateToString(mCallState));
                     pw.println("  mSystemReady=" + mSystemReady);
                 }
                 pw.println("  mArchive=" + mArchive.toString());
@@ -1839,7 +1852,11 @@ public class NotificationManagerService extends SystemService {
         }
 
         // If we're not supposed to beep, vibrate, etc. then don't.
-        if (!disableNotificationEffects()
+        final String disableEffects = disableNotificationEffects(record);
+        if (disableEffects != null) {
+            ZenLog.traceDisableEffects(record, disableEffects);
+        }
+        if (disableEffects == null
                 && (!(record.isUpdate
                     && (notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0 ))
                 && (record.getUserId() == UserHandle.USER_ALL ||
@@ -2657,6 +2674,26 @@ public class NotificationManagerService extends SystemService {
         }
     }
 
+    private static String callStateToString(int state) {
+        switch (state) {
+            case TelephonyManager.CALL_STATE_IDLE: return "CALL_STATE_IDLE";
+            case TelephonyManager.CALL_STATE_RINGING: return "CALL_STATE_RINGING";
+            case TelephonyManager.CALL_STATE_OFFHOOK: return "CALL_STATE_OFFHOOK";
+            default: return "CALL_STATE_UNKNOWN_" + state;
+        }
+    }
+
+    private void listenForCallState() {
+        TelephonyManager.from(getContext()).listen(new PhoneStateListener() {
+            @Override
+            public void onCallStateChanged(int state, String incomingNumber) {
+                if (mCallState == state) return;
+                if (DBG) Slog.d(TAG, "Call state changed: " + callStateToString(state));
+                mCallState = state;
+            }
+        }, PhoneStateListener.LISTEN_CALL_STATE);
+    }
+
     /**
      * Generates a NotificationRankingUpdate from 'sbns', considering only
      * notifications visible to the given listener.
index f84409e..6cc5e0e 100644 (file)
@@ -55,6 +55,7 @@ public class ZenLog {
     private static final int TYPE_CONFIG = 10;
     private static final int TYPE_FOLLOW_RINGER_MODE = 11;
     private static final int TYPE_NOT_INTERCEPTED = 12;
+    private static final int TYPE_DISABLE_EFFECTS = 13;
 
     private static int sNext;
     private static int sSize;
@@ -106,6 +107,10 @@ public class ZenLog {
                 + zenModeToString(oldZen) + " -> " + zenModeToString(newZen));
     }
 
+    public static void traceDisableEffects(NotificationRecord record, String reason) {
+        append(TYPE_DISABLE_EFFECTS, record.getKey() + "," + reason);
+    }
+
     private static String subscribeResult(IConditionProvider provider, RemoteException e) {
         return provider == null ? "no provider" : e != null ? e.getMessage() : "ok";
     }
@@ -124,6 +129,7 @@ public class ZenLog {
             case TYPE_CONFIG: return "config";
             case TYPE_FOLLOW_RINGER_MODE: return "follow_ringer_mode";
             case TYPE_NOT_INTERCEPTED: return "not_intercepted";
+            case TYPE_DISABLE_EFFECTS: return "disable_effects";
             default: return "unknown";
         }
     }
index e6007bf..5bc1ff9 100644 (file)
@@ -350,9 +350,9 @@ public class ZenModeHelper {
         return record.isCategory(Notification.CATEGORY_EVENT);
     }
 
-    private boolean isCall(NotificationRecord record) {
-        return isDefaultPhoneApp(record.sbn.getPackageName())
-                || record.isCategory(Notification.CATEGORY_CALL);
+    public boolean isCall(NotificationRecord record) {
+        return record != null && (isDefaultPhoneApp(record.sbn.getPackageName())
+                || record.isCategory(Notification.CATEGORY_CALL));
     }
 
     private boolean isDefaultPhoneApp(String pkg) {