Merge "Further call handover changes."
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index 503cd91..49882b0 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -28,10 +28,10 @@
     <string name="notification_missedCall_message" msgid="3049928912736917988">"Poruka"</string>
     <string name="accessibility_call_muted" msgid="2776111226185342220">"Zvuk poziva je isključen."</string>
     <string name="accessibility_speakerphone_enabled" msgid="1988512040421036359">"Zvučnik je omogućen."</string>
-    <string name="respond_via_sms_canned_response_1" msgid="2461606462788380215">"Ne mogu sada pričati. Šta ima?"</string>
+    <string name="respond_via_sms_canned_response_1" msgid="2461606462788380215">"Ne mogu sada pričati. O čemu se radi?"</string>
     <string name="respond_via_sms_canned_response_2" msgid="4074450431532859214">"Nazvat ću te uskoro."</string>
     <string name="respond_via_sms_canned_response_3" msgid="3496079065723960450">"Nazvat ću te kasnije."</string>
-    <string name="respond_via_sms_canned_response_4" msgid="1698989243040062190">"Ne mogu pričati. Nazovi kasnije?"</string>
+    <string name="respond_via_sms_canned_response_4" msgid="1698989243040062190">"Ne mogu pričati. Nazovi me kasnije."</string>
     <string name="respond_via_sms_setting_title" msgid="3754000371039709383">"Brzi odgovori"</string>
     <string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Uredi brze odgovore"</string>
     <string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 992df6f..5497d76 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -29,7 +29,7 @@
     <string name="accessibility_call_muted" msgid="2776111226185342220">"Llamada silenciada"</string>
     <string name="accessibility_speakerphone_enabled" msgid="1988512040421036359">"Altavoz habilitado"</string>
     <string name="respond_via_sms_canned_response_1" msgid="2461606462788380215">"No puedo hablar ahora. ¿Todo bien?"</string>
-    <string name="respond_via_sms_canned_response_2" msgid="4074450431532859214">"Te llamo enseguida."</string>
+    <string name="respond_via_sms_canned_response_2" msgid="4074450431532859214">"Te llamo en seguida."</string>
     <string name="respond_via_sms_canned_response_3" msgid="3496079065723960450">"Te llamo más tarde."</string>
     <string name="respond_via_sms_canned_response_4" msgid="1698989243040062190">"No puedo hablar ahora. ¿Me llamas más tarde?"</string>
     <string name="respond_via_sms_setting_title" msgid="3754000371039709383">"Respuestas rápidas"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 358b106..eefd65f 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -33,7 +33,7 @@
     <string name="respond_via_sms_canned_response_3" msgid="3496079065723960450">"Je t\'appellerai plus tard."</string>
     <string name="respond_via_sms_canned_response_4" msgid="1698989243040062190">"Peux pas parler. On se rappelle ?"</string>
     <string name="respond_via_sms_setting_title" msgid="3754000371039709383">"Réponses rapides"</string>
-    <string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Modifier réponses rapides"</string>
+    <string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Modifier les réponses rapides"</string>
     <string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
     <string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Réponse rapide"</string>
     <string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Message envoyé à <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 9e76715..e5bcb91 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -29,9 +29,9 @@
     <string name="accessibility_call_muted" msgid="2776111226185342220">"Zvuk poziva isključen."</string>
     <string name="accessibility_speakerphone_enabled" msgid="1988512040421036359">"Zvučnik je omogućen."</string>
     <string name="respond_via_sms_canned_response_1" msgid="2461606462788380215">"Sada ne mogu razgovarati. Što ima?"</string>
-    <string name="respond_via_sms_canned_response_2" msgid="4074450431532859214">"Nazvat ću vas odmah."</string>
-    <string name="respond_via_sms_canned_response_3" msgid="3496079065723960450">"Zvat ću vas kasnije."</string>
-    <string name="respond_via_sms_canned_response_4" msgid="1698989243040062190">"Sada ne mogu razgovarati. Nazovite me kasnije."</string>
+    <string name="respond_via_sms_canned_response_2" msgid="4074450431532859214">"Zovem čim stignem."</string>
+    <string name="respond_via_sms_canned_response_3" msgid="3496079065723960450">"Nazvat ću kasnije."</string>
+    <string name="respond_via_sms_canned_response_4" msgid="1698989243040062190">"Sad ne mogu razgovarati. Čujemo se kasnije."</string>
     <string name="respond_via_sms_setting_title" msgid="3754000371039709383">"Brzi odgovori"</string>
     <string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Uređivanje brzih odgovora"</string>
     <string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index e8fe522..b56255a 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -54,7 +54,7 @@
     <string name="block_number" msgid="1101252256321306179">"Ավելացնել համար"</string>
     <string name="unblock_dialog_body" msgid="1614238499771862793">"Արգելաբացե՞լ <xliff:g id="NUMBER_TO_BLOCK">%1$s</xliff:g> համարը:"</string>
     <string name="unblock_button" msgid="3078048901972674170">"Արգելաբացել"</string>
-    <string name="add_blocked_dialog_body" msgid="9030243212265516828">"Արգելափակել այս համարից ուղարկված զանգերն ու հաղորդագրությունները՝"</string>
+    <string name="add_blocked_dialog_body" msgid="9030243212265516828">"Արգելափակել զանգերն ու հաղորդագրությունները այս համարից"</string>
     <string name="add_blocked_number_hint" msgid="6847675097085433553">"Հեռախոսահամարը"</string>
     <string name="block_button" msgid="8822290682524373357">"Արգելափակել"</string>
     <string name="non_primary_user" msgid="5180129233352533459">"Միայն սարքի սեփականատերը կարող է դիտել և կառավարել արգելափակված համարները:"</string>
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
index 36b2473..4ee9c3f 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/strings.xml
@@ -49,8 +49,8 @@
     <string name="change_default_dialer_dialog_affirmative" msgid="8606546663509166276">"မူရင်း သတ်မှတ်ရန်"</string>
     <string name="change_default_dialer_dialog_negative" msgid="9078144617060173845">"မလုပ်တော့"</string>
     <string name="change_default_dialer_warning_message" msgid="1417671460801684999">"<xliff:g id="NEW_APP">%s</xliff:g> သည် ခေါ်ဆိုမှုများကို ဘက်စုံပြုလုပ်ထိန်းချုပ်သွားနိုင်မည်ဖြစ်သည်။ သင်ယုံကြည်သော အက်ပ်များကိုသာ မူရင်း Phone အက်ပ်အဖြစ် သတ်မှတ်သင့်ပါသည်။"</string>
-    <string name="blocked_numbers" msgid="2751843139572970579">"ပိတ်ဆို့ထားသည့် နံပါတ်များ"</string>
-    <string name="blocked_numbers_msg" msgid="1045015186124965643">"သင်သည် ဘလော့ခ်လုပ်ထားသော နံပါတ်များမှ ဖုန်းခေါ်ခြင်း (သို့) စာသားပို့ခြင်းတို့ကို လက်ခံရရှိမည် မဟုတ်ပါ။"</string>
+    <string name="blocked_numbers" msgid="2751843139572970579">"ပိတ်ထားသည့် နံပါတ်များ"</string>
+    <string name="blocked_numbers_msg" msgid="1045015186124965643">"ပိတ်ထားသော နံပါတ်များမှ ဖုန်းခေါ်ခြင်း (သို့) စာသားပို့ခြင်းတို့ကို သင်လက်ခံရရှိမည် မဟုတ်ပါ။"</string>
     <string name="block_number" msgid="1101252256321306179">"နံပါတ်တစ်ခု ထည့်ပါ"</string>
     <string name="unblock_dialog_body" msgid="1614238499771862793">"<xliff:g id="NUMBER_TO_BLOCK">%1$s</xliff:g> ကို ပိတ်ဆို့မှုပြန်ဖွင့်မလား။"</string>
     <string name="unblock_button" msgid="3078048901972674170">"ပိတ်ဆို့မှုပြန်ဖွင့်ပါ"</string>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 2fd44a5..d57efdc 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -50,7 +50,7 @@
     <string name="change_default_dialer_dialog_negative" msgid="9078144617060173845">"Anuluj"</string>
     <string name="change_default_dialer_warning_message" msgid="1417671460801684999">"<xliff:g id="NEW_APP">%s</xliff:g> uzyska możliwość nawiązywania połączeń i kontrolowania wszystkich ich aspektów. Tylko zaufane aplikacje powinny być ustawiane jako domyślna aplikacja telefoniczna."</string>
     <string name="blocked_numbers" msgid="2751843139572970579">"Zablokowane numery"</string>
-    <string name="blocked_numbers_msg" msgid="1045015186124965643">"Nie będziesz otrzymywać połączeń ani SMS-ów z zablokowanych numerów."</string>
+    <string name="blocked_numbers_msg" msgid="1045015186124965643">"Nie będziesz otrzymywać połączeń ani SMS-ów z zablokowanych numerów."</string>
     <string name="block_number" msgid="1101252256321306179">"Dodaj numer"</string>
     <string name="unblock_dialog_body" msgid="1614238499771862793">"Odblokować <xliff:g id="NUMBER_TO_BLOCK">%1$s</xliff:g>?"</string>
     <string name="unblock_button" msgid="3078048901972674170">"Odblokuj"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 11d688a..3952f30 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -28,10 +28,10 @@
     <string name="notification_missedCall_message" msgid="3049928912736917988">"簡訊"</string>
     <string name="accessibility_call_muted" msgid="2776111226185342220">"通話已靜音。"</string>
     <string name="accessibility_speakerphone_enabled" msgid="1988512040421036359">"喇叭已啟用"</string>
-    <string name="respond_via_sms_canned_response_1" msgid="2461606462788380215">"我現在不方便通話,有什麼事?"</string>
+    <string name="respond_via_sms_canned_response_1" msgid="2461606462788380215">"我現在不方便講話,有什麼事?"</string>
     <string name="respond_via_sms_canned_response_2" msgid="4074450431532859214">"我待會就回電。"</string>
     <string name="respond_via_sms_canned_response_3" msgid="3496079065723960450">"我晚點回電。"</string>
-    <string name="respond_via_sms_canned_response_4" msgid="1698989243040062190">"我現在不方便通話,晚點再打來好嗎?"</string>
+    <string name="respond_via_sms_canned_response_4" msgid="1698989243040062190">"我現在不方便講話,晚點再打來好嗎?"</string>
     <string name="respond_via_sms_setting_title" msgid="3754000371039709383">"快速回應"</string>
     <string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"編輯快速回應"</string>
     <string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
diff --git a/scripts/telecom_testing.sh b/scripts/telecom_testing.sh
index e6423a3..0ece427 100644
--- a/scripts/telecom_testing.sh
+++ b/scripts/telecom_testing.sh
@@ -1,6 +1,6 @@
-lite_test_telecom() {
+_lite_test_general() {
   usage="
-  Usage: lite_test_telecom [-c CLASSNAME] [-d] [-a | -i] [-e], where
+  Usage: $0 [-c CLASSNAME] [-d] [-a | -i] [-e], where
 
   -c CLASSNAME          Run tests only for the specified class/method. CLASSNAME
                           should be of the form SomeClassTest or SomeClassTest#testMethod.
@@ -15,12 +15,13 @@
 
   local OPTIND=1
   local class=
+  local project=
   local install=false
   local installwdep=false
   local debug=false
   local coverage=false
 
-  while getopts "c:hadie" opt; do
+  while getopts "c:p:hadie" opt; do
     case "$opt" in
       h)
         echo "$usage"
@@ -39,9 +40,28 @@
         installwdep=true;;
       e)
         coverage=true;;
+      p)
+        project=$OPTARG;;
     esac
   done
 
+  local build_dir=
+  local apk_loc=
+  local package_prefix=
+  local instrumentation=
+  case "$project" in
+    "telecom")
+      build_dir="packages/services/Telecomm/tests"
+      apk_loc="data/app/TelecomUnitTests/TelecomUnitTests.apk"
+      package_prefix="com.android.server.telecom.tests"
+      instrumentation="android.test.InstrumentationTestRunner";;
+    "telephony")
+      build_dir="frameworks/opt/telephony/tests/"
+      apk_loc="data/app/FrameworksTelephonyTests/FrameworksTelephonyTests.apk"
+      package_prefix="com.android.frameworks.telephonytests"
+      instrumentation="android.support.test.runner.AndroidJUnitRunner";;
+  esac
+
   local T=$(gettop)
 
   if [ $install = true ] ; then
@@ -57,9 +77,9 @@
     fi
 
     if [ $installwdep = true ] ; then
-      (export ${emma_opt}; mmma -j40 "packages/services/Telecomm/tests")
+      (export ${emma_opt}; mmma -j40 "$build_dir")
     else
-      (export ${emma_opt}; mmm "packages/services/Telecomm/tests")
+      (export ${emma_opt}; mmm "$build_dir")
     fi
     if [ $? -ne 0 ] ; then
       echo "Make failed! try using -a instead of -i if building with coverage"
@@ -69,7 +89,7 @@
     # Strip off any possible aosp_ prefix from the target product
     local canonical_product=$(sed 's/^aosp_//' <<< "$TARGET_PRODUCT")
 
-    adb install -r -t "out/target/product/$canonical_product/data/app/TelecomUnitTests/TelecomUnitTests.apk"
+    adb install -r -t "out/target/product/$canonical_product/$apk_loc"
     if [ $? -ne 0 ] ; then
       cd "$olddir"
       return $?
@@ -79,17 +99,22 @@
 
   local e_options=""
   if [ -n "$class" ] ; then
-    e_options="${e_options} -e class com.android.server.telecom.tests.${class}"
+    if [[ "$class" =~ "\." ]] ; then
+      e_options="${e_options} -e class ${class}"
+    else
+      e_options="${e_options} -e class ${package_prefix}.${class}"
+    fi
   fi
   if [ $debug = true ] ; then
     e_options="${e_options} -e debug 'true'"
   fi
-  if [ $coverage = true ] ; then
+  if [ $coverage = true ] && [ $project =~ "telecom" ] ; then
     e_options="${e_options} -e coverage 'true'"
   fi
-  adb shell am instrument ${e_options} -w com.android.server.telecom.tests/android.test.InstrumentationTestRunner
+  adb shell am instrument ${e_options} -w "$package_prefix/$instrumentation"
 
-  if [ $coverage = true ] ; then
+  # Code coverage only enabled for Telecom.
+  if [ $coverage = true ] && [ $project =~ "telecom" ] ; then
     adb root
     adb wait-for-device
     adb pull /data/user/0/com.android.server.telecom.tests/files/coverage.ec /tmp/
@@ -103,3 +128,11 @@
       --source-dir "$T/packages/services/Telecomm/src/"
   fi
 }
+
+lite_test_telecom() {
+  _lite_test_general -p telecom $@
+}
+
+lite_test_telephony() {
+  _lite_test_general -p telephony $@
+}
diff --git a/src/com/android/server/telecom/CallAudioManager.java b/src/com/android/server/telecom/CallAudioManager.java
index 02bd05b..f778e30 100644
--- a/src/com/android/server/telecom/CallAudioManager.java
+++ b/src/com/android/server/telecom/CallAudioManager.java
@@ -424,7 +424,8 @@
 
     @VisibleForTesting
     public boolean startRinging() {
-        return mRinger.startRinging(mForegroundCall);
+        return mRinger.startRinging(mForegroundCall,
+                mCallAudioRouteStateMachine.isHfpDeviceAvailable());
     }
 
     @VisibleForTesting
diff --git a/src/com/android/server/telecom/CallAudioRouteStateMachine.java b/src/com/android/server/telecom/CallAudioRouteStateMachine.java
index 2e4c6e5..8ab0bf8 100644
--- a/src/com/android/server/telecom/CallAudioRouteStateMachine.java
+++ b/src/com/android/server/telecom/CallAudioRouteStateMachine.java
@@ -18,11 +18,7 @@
 
 
 import android.app.ActivityManager;
-import android.app.NotificationManager;
-import android.content.BroadcastReceiver;
 import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.pm.UserInfo;
 import android.media.AudioManager;
 import android.media.IAudioService;
@@ -158,49 +154,6 @@
         put(RUN_RUNNABLE, "RUN_RUNNABLE");
     }};
 
-    /**
-     * BroadcastReceiver used to track changes in the notification interruption filter.  This
-     * ensures changes to the notification interruption filter made by the user during a call are
-     * respected when restoring the notification interruption filter state.
-     */
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            Log.startSession("CARSM.oR");
-            try {
-                String action = intent.getAction();
-
-                if (action.equals(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED)) {
-                    // We get an this broadcast any time the notification filter is changed, even if
-                    // we are the initiator of the change.
-                    // So, we'll look at who the initiator of the manual zen rule is in the
-                    // notification manager.  If its us, then we can just exit now.
-                    String initiator =
-                            mInterruptionFilterProxy.getInterruptionModeInitiator();
-
-                    if (TELECOM_PACKAGE.equals(initiator)) {
-                        // We are the initiator of this change, so ignore it.
-                        Log.i(this, "interruptionFilterChanged - ignoring own change");
-                        return;
-                    }
-
-                    if (mAreNotificationSuppressed) {
-                        // If we've already set the interruption filter, and the user changes it to
-                        // something other than INTERRUPTION_FILTER_ALARMS, assume we will no longer
-                        // try to change it back if the audio route changes.
-                        mAreNotificationSuppressed =
-                                mInterruptionFilterProxy.getCurrentInterruptionFilter()
-                                        == NotificationManager.INTERRUPTION_FILTER_ALARMS;
-                        Log.i(this, "interruptionFilterChanged - changing to %b",
-                                mAreNotificationSuppressed);
-                    }
-                }
-            } finally {
-                Log.endSession();
-            }
-        }
-    };
-
     private static final String ACTIVE_EARPIECE_ROUTE_NAME = "ActiveEarpieceRoute";
     private static final String ACTIVE_BLUETOOTH_ROUTE_NAME = "ActiveBluetoothRoute";
     private static final String ACTIVE_SPEAKER_ROUTE_NAME = "ActiveSpeakerRoute";
@@ -315,9 +268,6 @@
             super.enter();
             setSpeakerphoneOn(false);
             setBluetoothOn(false);
-            if (mAudioFocusType == ACTIVE_FOCUS) {
-                setNotificationsSuppressed(true);
-            }
             CallAudioState newState = new CallAudioState(mIsMuted, ROUTE_EARPIECE,
                     mAvailableRoutes);
             setSystemAudioState(newState, true);
@@ -325,12 +275,6 @@
         }
 
         @Override
-        public void exit() {
-            super.exit();
-            setNotificationsSuppressed(false);
-        }
-
-        @Override
         public void updateSystemAudioState() {
             updateInternalCallAudioState();
             setSystemAudioState(mCurrentCallAudioState);
@@ -368,10 +312,6 @@
                     transitionTo(mActiveSpeakerRoute);
                     return HANDLED;
                 case SWITCH_FOCUS:
-                    if (msg.arg1 == ACTIVE_FOCUS) {
-                        setNotificationsSuppressed(true);
-                    }
-
                     if (msg.arg1 == NO_FOCUS) {
                         reinitialize();
                     }
@@ -1151,7 +1091,6 @@
     private int mAudioFocusType;
     private boolean mWasOnSpeaker;
     private boolean mIsMuted;
-    private boolean mAreNotificationSuppressed = false;
 
     private final Context mContext;
     private final CallsManager mCallsManager;
@@ -1160,7 +1099,6 @@
     private final WiredHeadsetManager mWiredHeadsetManager;
     private final StatusBarNotifier mStatusBarNotifier;
     private final CallAudioManager.AudioServiceFactory mAudioServiceFactory;
-    private final InterruptionFilterProxy mInterruptionFilterProxy;
     private final boolean mDoesDeviceSupportEarpieceRoute;
     private final TelecomSystem.SyncRoot mLock;
     private boolean mHasUserExplicitlyLeftBluetooth = false;
@@ -1180,7 +1118,6 @@
             WiredHeadsetManager wiredHeadsetManager,
             StatusBarNotifier statusBarNotifier,
             CallAudioManager.AudioServiceFactory audioServiceFactory,
-            InterruptionFilterProxy interruptionFilterProxy,
             boolean doesDeviceSupportEarpieceRoute) {
         super(NAME);
         addState(mActiveEarpieceRoute);
@@ -1200,11 +1137,6 @@
         mWiredHeadsetManager = wiredHeadsetManager;
         mStatusBarNotifier = statusBarNotifier;
         mAudioServiceFactory = audioServiceFactory;
-        mInterruptionFilterProxy = interruptionFilterProxy;
-        // Register for misc other intent broadcasts.
-        IntentFilter intentFilter =
-                new IntentFilter(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED);
-        context.registerReceiver(mReceiver, intentFilter);
         mDoesDeviceSupportEarpieceRoute = doesDeviceSupportEarpieceRoute;
         mLock = callsManager.getLock();
 
@@ -1323,47 +1255,8 @@
         getHandler().getLooper().dump(pw::println, "");
     }
 
-    /**
-     * Sets whether notifications should be suppressed or not.  Used when in a call to ensure the
-     * device will not vibrate due to notifications.
-     * Alarm-only filtering is activated when
-     *
-     * @param on {@code true} when notification suppression should be activated, {@code false} when
-     *                       it should be deactivated.
-     */
-    private void setNotificationsSuppressed(boolean on) {
-        if (mInterruptionFilterProxy == null) {
-            return;
-        }
-
-        Log.i(this, "setNotificationsSuppressed: on=%s; suppressed=%s", (on ? "yes" : "no"),
-                (mAreNotificationSuppressed ? "yes" : "no"));
-        if (on) {
-            if (!mAreNotificationSuppressed) {
-                // Enabling suppression of notifications.
-                int interruptionFilter = mInterruptionFilterProxy.getCurrentInterruptionFilter();
-                if (interruptionFilter == NotificationManager.INTERRUPTION_FILTER_ALL) {
-                    // No interruption filter is specified, so suppress notifications by setting the
-                    // current filter to alarms-only.
-                    mAreNotificationSuppressed = true;
-                    mInterruptionFilterProxy.setInterruptionFilter(
-                            NotificationManager.INTERRUPTION_FILTER_ALARMS);
-                } else {
-                    // Interruption filter is already chosen by the user, so do not attempt to change
-                    // it.
-                    mAreNotificationSuppressed = false;
-                }
-            }
-        } else {
-            // Disabling suppression of notifications.
-            if (mAreNotificationSuppressed) {
-                // We have implemented the alarms-only policy and the user has not changed it since
-                // we originally set it, so reset the notification filter.
-                mInterruptionFilterProxy.setInterruptionFilter(
-                        NotificationManager.INTERRUPTION_FILTER_ALL);
-            }
-            mAreNotificationSuppressed = false;
-        }
+    public boolean isHfpDeviceAvailable() {
+        return mBluetoothRouteManager.isBluetoothAvailable();
     }
 
     private void setSpeakerphoneOn(boolean on) {
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index 5e11d37..8f97b1b 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -17,7 +17,6 @@
 package com.android.server.telecom;
 
 import android.app.ActivityManager;
-import android.app.NotificationManager;
 import android.content.Context;
 import android.content.pm.UserInfo;
 import android.content.Intent;
@@ -143,6 +142,9 @@
      */
     private static final int CALL_FILTER_ALL = 3;
 
+    private static final String PERMISSION_PROCESS_PHONE_ACCOUNT_REGISTRATION =
+            "android.permission.PROCESS_PHONE_ACCOUNT_REGISTRATION";
+
     private static final int HANDLER_WAIT_TIMEOUT = 10000;
     private static final int MAXIMUM_LIVE_CALLS = 1;
     private static final int MAXIMUM_HOLD_CALLS = 1;
@@ -248,7 +250,6 @@
     private final DefaultDialerCache mDefaultDialerCache;
     private final Timeouts.Adapter mTimeoutsAdapter;
     private final PhoneNumberUtilsAdapter mPhoneNumberUtilsAdapter;
-    private final NotificationManager mNotificationManager;
     private final Set<Call> mLocallyDisconnectingCalls = new HashSet<>();
     private final Set<Call> mPendingCallsToDisconnect = new HashSet<>();
     /* Handler tied to thread in which CallManager was initialized. */
@@ -262,6 +263,21 @@
     private Runnable mStopTone;
 
     /**
+     * Listener to PhoneAccountRegistrar events.
+     */
+    private PhoneAccountRegistrar.Listener mPhoneAccountListener =
+            new PhoneAccountRegistrar.Listener() {
+        public void onPhoneAccountRegistered(PhoneAccountRegistrar registrar,
+                                             PhoneAccountHandle handle) {
+            broadcastRegisterIntent(handle);
+        }
+        public void onPhoneAccountUnRegistered(PhoneAccountRegistrar registrar,
+                                               PhoneAccountHandle handle) {
+            broadcastUnregisterIntent(handle);
+        }
+    };
+
+    /**
      * Initializes the required Telecom components.
      */
     CallsManager(
@@ -282,7 +298,6 @@
             Timeouts.Adapter timeoutsAdapter,
             AsyncRingtonePlayer asyncRingtonePlayer,
             PhoneNumberUtilsAdapter phoneNumberUtilsAdapter,
-            InterruptionFilterProxy interruptionFilterProxy,
             EmergencyCallHelper emergencyCallHelper) {
         mContext = context;
         mLock = lock;
@@ -290,6 +305,7 @@
         mContactsAsyncHelper = contactsAsyncHelper;
         mCallerInfoAsyncQueryFactory = callerInfoAsyncQueryFactory;
         mPhoneAccountRegistrar = phoneAccountRegistrar;
+        mPhoneAccountRegistrar.addListener(mPhoneAccountListener);
         mMissedCallNotifier = missedCallNotifier;
         StatusBarNotifier statusBarNotifier = new StatusBarNotifier(context, this);
         mWiredHeadsetManager = wiredHeadsetManager;
@@ -303,8 +319,6 @@
 
         mDtmfLocalTonePlayer =
                 new DtmfLocalTonePlayer(new DtmfLocalTonePlayer.ToneGeneratorProxy());
-        mNotificationManager = (NotificationManager) context.getSystemService(
-                Context.NOTIFICATION_SERVICE);
         CallAudioRouteStateMachine callAudioRouteStateMachine = new CallAudioRouteStateMachine(
                 context,
                 this,
@@ -312,7 +326,6 @@
                 wiredHeadsetManager,
                 statusBarNotifier,
                 audioServiceFactory,
-                interruptionFilterProxy,
                 CallAudioRouteStateMachine.doesDeviceSupportEarpieceRoute()
         );
         callAudioRouteStateMachine.initialize();
@@ -2949,4 +2962,50 @@
         return mCalls.stream().filter(c -> c.getHandoverFromCall() != null ||
                 c.getHandoverToCall() != null).count() > 0;
     }
+
+    private void broadcastUnregisterIntent(PhoneAccountHandle accountHandle) {
+        Intent intent =
+                new Intent(TelecomManager.ACTION_PHONE_ACCOUNT_UNREGISTERED);
+        intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+        intent.putExtra(
+                TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, accountHandle);
+        Log.i(this, "Sending phone-account %s unregistered intent as user", accountHandle);
+        mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
+                PERMISSION_PROCESS_PHONE_ACCOUNT_REGISTRATION);
+
+        String dialerPackage = mDefaultDialerCache.getDefaultDialerApplication(
+                getCurrentUserHandle().getIdentifier());
+        if (!TextUtils.isEmpty(dialerPackage)) {
+            Intent directedIntent = new Intent(TelecomManager.ACTION_PHONE_ACCOUNT_UNREGISTERED)
+                    .setPackage(dialerPackage);
+            directedIntent.putExtra(
+                    TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, accountHandle);
+            Log.i(this, "Sending phone-account unregistered intent to default dialer");
+            mContext.sendBroadcastAsUser(directedIntent, UserHandle.ALL, null);
+        }
+        return ;
+    }
+
+    private void broadcastRegisterIntent(PhoneAccountHandle accountHandle) {
+        Intent intent = new Intent(
+                TelecomManager.ACTION_PHONE_ACCOUNT_REGISTERED);
+        intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+        intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
+                accountHandle);
+        Log.i(this, "Sending phone-account %s registered intent as user", accountHandle);
+        mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
+                PERMISSION_PROCESS_PHONE_ACCOUNT_REGISTRATION);
+
+        String dialerPackage = mDefaultDialerCache.getDefaultDialerApplication(
+                getCurrentUserHandle().getIdentifier());
+        if (!TextUtils.isEmpty(dialerPackage)) {
+            Intent directedIntent = new Intent(TelecomManager.ACTION_PHONE_ACCOUNT_REGISTERED)
+                    .setPackage(dialerPackage);
+            directedIntent.putExtra(
+                    TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, accountHandle);
+            Log.i(this, "Sending phone-account registered intent to default dialer");
+            mContext.sendBroadcastAsUser(directedIntent, UserHandle.ALL, null);
+        }
+        return ;
+    }
 }
diff --git a/src/com/android/server/telecom/InCallController.java b/src/com/android/server/telecom/InCallController.java
index 4696649..fde2910 100644
--- a/src/com/android/server/telecom/InCallController.java
+++ b/src/com/android/server/telecom/InCallController.java
@@ -61,7 +61,7 @@
  * can send updates to the in-call app. This class is created and owned by CallsManager and retains
  * a binding to the {@link IInCallService} (implemented by the in-call app).
  */
-public final class InCallController extends CallsManagerListenerBase {
+public class InCallController extends CallsManagerListenerBase {
 
     public class InCallServiceConnection {
         /**
diff --git a/src/com/android/server/telecom/PhoneAccountRegistrar.java b/src/com/android/server/telecom/PhoneAccountRegistrar.java
index af633fb..8cdec30 100644
--- a/src/com/android/server/telecom/PhoneAccountRegistrar.java
+++ b/src/com/android/server/telecom/PhoneAccountRegistrar.java
@@ -120,6 +120,10 @@
         public void onAccountsChanged(PhoneAccountRegistrar registrar) {}
         public void onDefaultOutgoingChanged(PhoneAccountRegistrar registrar) {}
         public void onSimCallManagerChanged(PhoneAccountRegistrar registrar) {}
+        public void onPhoneAccountRegistered(PhoneAccountRegistrar registrar,
+                                             PhoneAccountHandle handle) {}
+        public void onPhoneAccountUnRegistered(PhoneAccountRegistrar registrar,
+                                             PhoneAccountHandle handle) {}
     }
 
     /**
@@ -652,14 +656,17 @@
         // !!! IMPORTANT !!! It is important that we do not read the enabled state that the
         // source app provides or else an third party app could enable itself.
         boolean isEnabled = false;
+        boolean isNewAccount;
 
         PhoneAccount oldAccount = getPhoneAccountUnchecked(account.getAccountHandle());
         if (oldAccount != null) {
             mState.accounts.remove(oldAccount);
             isEnabled = oldAccount.isEnabled();
-            Log.i(this, getAccountDiffString(account, oldAccount));
+            Log.i(this, "Modify account: %s", getAccountDiffString(account, oldAccount));
+            isNewAccount = false;
         } else {
             Log.i(this, "New phone account registered: " + account);
+            isNewAccount = true;
         }
 
         // When registering a self-managed PhoneAccount we enforce the rule that the label that the
@@ -695,6 +702,9 @@
 
         write();
         fireAccountsChanged();
+        if (isNewAccount) {
+            fireAccountRegistered(account.getAccountHandle());
+        }
     }
 
     public void unregisterPhoneAccount(PhoneAccountHandle accountHandle) {
@@ -703,6 +713,7 @@
             if (mState.accounts.remove(account)) {
                 write();
                 fireAccountsChanged();
+                fireAccountUnRegistered(accountHandle);
             }
         }
     }
@@ -748,6 +759,18 @@
         }
     }
 
+    private void fireAccountRegistered(PhoneAccountHandle handle) {
+        for (Listener l : mListeners) {
+            l.onPhoneAccountRegistered(this, handle);
+        }
+    }
+
+    private void fireAccountUnRegistered(PhoneAccountHandle handle) {
+        for (Listener l : mListeners) {
+            l.onPhoneAccountUnRegistered(this, handle);
+        }
+    }
+
     private void fireAccountsChanged() {
         for (Listener l : mListeners) {
             l.onAccountsChanged(this);
@@ -771,7 +794,6 @@
                 Log.piiHandle(account2.getAddress()));
         appendDiff(sb, "cap", account1.getCapabilities(), account2.getCapabilities());
         appendDiff(sb, "hl", account1.getHighlightColor(), account2.getHighlightColor());
-        appendDiff(sb, "icon", account1.getIcon(), account2.getIcon());
         appendDiff(sb, "lbl", account1.getLabel(), account2.getLabel());
         appendDiff(sb, "desc", account1.getShortDescription(), account2.getShortDescription());
         appendDiff(sb, "subAddr", Log.piiHandle(account1.getSubscriptionAddress()),
diff --git a/src/com/android/server/telecom/Ringer.java b/src/com/android/server/telecom/Ringer.java
index c5817e7..d955227 100644
--- a/src/com/android/server/telecom/Ringer.java
+++ b/src/com/android/server/telecom/Ringer.java
@@ -97,41 +97,44 @@
         mInCallController = inCallController;
     }
 
-    public boolean startRinging(Call foregroundCall) {
-        AudioManager audioManager =
-                (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
-        boolean isRingerAudible = audioManager.getStreamVolume(AudioManager.STREAM_RING) > 0;
-
-        if (mSystemSettingsUtil.isTheaterModeOn(mContext)) {
-            return false;
-        }
-
+    public boolean startRinging(Call foregroundCall, boolean isHfpDeviceAttached) {
         if (foregroundCall == null) {
             Log.wtf(this, "startRinging called with null foreground call.");
             return false;
         }
 
-        if (mInCallController.doesConnectedDialerSupportRinging()) {
-            Log.addEvent(foregroundCall, LogUtils.Events.SKIP_RINGING);
-            return isRingerAudible;
-        }
+        AudioManager audioManager =
+                (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+        boolean isVolumeOverZero = audioManager.getStreamVolume(AudioManager.STREAM_RING) > 0;
+        boolean shouldRingForContact = shouldRingForContact(foregroundCall.getContactUri());
+        boolean isRingtonePresent = !(mRingtoneFactory.getRingtone(foregroundCall) == null);
+        boolean isSelfManaged = foregroundCall.isSelfManaged();
 
-        if (foregroundCall.isSelfManaged()) {
-            Log.addEvent(foregroundCall, LogUtils.Events.SKIP_RINGING, "Self-managed");
-            return false;
+        boolean isRingerAudible = isVolumeOverZero && shouldRingForContact && isRingtonePresent;
+        // Acquire audio focus under any of the following conditions:
+        // 1. Should ring for contact and there's an HFP device attached
+        // 2. Volume is over zero, we should ring for the contact, and there's a audible ringtone
+        //    present.
+        // 3. The call is self-managed.
+        boolean shouldAcquireAudioFocus =
+                isRingerAudible || (isHfpDeviceAttached && shouldRingForContact) || isSelfManaged;
+
+        // Don't do call waiting operations or vibration unless these are false.
+        boolean isTheaterModeOn = mSystemSettingsUtil.isTheaterModeOn(mContext);
+        boolean letDialerHandleRinging = mInCallController.doesConnectedDialerSupportRinging();
+        boolean endEarly = isTheaterModeOn || letDialerHandleRinging || isSelfManaged;
+
+        if (endEarly) {
+            if (letDialerHandleRinging) {
+                Log.addEvent(foregroundCall, LogUtils.Events.SKIP_RINGING);
+            }
+            Log.i(this, "Ending early -- isTheaterModeOn=%s, letDialerHandleRinging=%s, " +
+                    "isSelfManaged=%s", isTheaterModeOn, letDialerHandleRinging, isSelfManaged);
+            return shouldAcquireAudioFocus;
         }
 
         stopCallWaiting();
 
-        if (!shouldRingForContact(foregroundCall.getContactUri())) {
-            return false;
-        }
-
-        // Don't ring/acquire focus if there is no ringtone
-        if (mRingtoneFactory.getRingtone(foregroundCall) == null) {
-            isRingerAudible = false;
-        }
-
         if (isRingerAudible) {
             mRingingCall = foregroundCall;
             Log.addEvent(foregroundCall, LogUtils.Events.START_RINGER);
@@ -141,10 +144,12 @@
             // request the custom ringtone from the call and expect it to be current.
             mRingtonePlayer.play(mRingtoneFactory, foregroundCall);
         } else {
-            Log.i(this, "startRingingOrCallWaiting, skipping because volume is 0");
+            Log.i(this, "startRinging: skipping because ringer would not be audible. " +
+                    "isVolumeOverZero=%s, shouldRingForContact=%s, isRingtonePresent=%s",
+                    isVolumeOverZero, shouldRingForContact, isRingtonePresent);
         }
 
-        if (shouldVibrate(mContext, foregroundCall) && !mIsVibrating) {
+        if (shouldVibrate(mContext, foregroundCall) && !mIsVibrating && shouldRingForContact) {
             mVibratingCall = foregroundCall;
             mVibrator.vibrate(VIBRATION_PATTERN, VIBRATION_PATTERN_REPEAT,
                     VIBRATION_ATTRIBUTES);
@@ -153,7 +158,7 @@
             Log.addEvent(foregroundCall, LogUtils.Events.SKIP_VIBRATION, "already vibrating");
         }
 
-        return isRingerAudible;
+        return shouldAcquireAudioFocus;
     }
 
     public void startCallWaiting(Call call) {
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
index d9b9536..b1ba744 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -46,6 +46,7 @@
 import android.telecom.VideoProfile;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.text.TextUtils;
 import android.util.EventLog;
 
 import com.android.internal.telecom.ITelecomService;
@@ -76,8 +77,6 @@
         }
     }
 
-    private static final String PERMISSION_PROCESS_PHONE_ACCOUNT_REGISTRATION =
-            "android.permission.PROCESS_PHONE_ACCOUNT_REGISTRATION";
     private static final int DEFAULT_VIDEO_STATE = -1;
 
     private final ITelecomService.Stub mBinderImpl = new ITelecomService.Stub() {
@@ -398,18 +397,9 @@
                             enforceRegisterMultiUser();
                         }
                         enforceUserHandleMatchesCaller(account.getAccountHandle());
-                        mPhoneAccountRegistrar.registerPhoneAccount(account);
-                        // Broadcast an intent indicating the phone account which was registered.
-                        long token = Binder.clearCallingIdentity();
+                        final long token = Binder.clearCallingIdentity();
                         try {
-                            Intent intent = new Intent(
-                                    TelecomManager.ACTION_PHONE_ACCOUNT_REGISTERED);
-                            intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
-                            intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,
-                                    account.getAccountHandle());
-                            Log.i(this, "Sending phone-account registered intent as user");
-                            mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
-                                    PERMISSION_PROCESS_PHONE_ACCOUNT_REGISTRATION);
+                            mPhoneAccountRegistrar.registerPhoneAccount(account);
                         } finally {
                             Binder.restoreCallingIdentity(token);
                         }
@@ -431,19 +421,9 @@
                     enforcePhoneAccountModificationForPackage(
                             accountHandle.getComponentName().getPackageName());
                     enforceUserHandleMatchesCaller(accountHandle);
-                    mPhoneAccountRegistrar.unregisterPhoneAccount(accountHandle);
-
-                    // Broadcast an intent indicating the phone account which was unregistered.
-                    long token = Binder.clearCallingIdentity();
+                    final long token = Binder.clearCallingIdentity();
                     try {
-                        Intent intent =
-                                new Intent(TelecomManager.ACTION_PHONE_ACCOUNT_UNREGISTERED);
-                        intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
-                        intent.putExtra(
-                                TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, accountHandle);
-                        Log.i(this, "Sending phone-account unregistered intent as user");
-                        mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
-                                PERMISSION_PROCESS_PHONE_ACCOUNT_REGISTRATION);
+                        mPhoneAccountRegistrar.unregisterPhoneAccount(accountHandle);
                     } finally {
                         Binder.restoreCallingIdentity(token);
                     }
diff --git a/src/com/android/server/telecom/TelecomSystem.java b/src/com/android/server/telecom/TelecomSystem.java
index 9c34ef5..d2a1959 100644
--- a/src/com/android/server/telecom/TelecomSystem.java
+++ b/src/com/android/server/telecom/TelecomSystem.java
@@ -189,7 +189,6 @@
             Timeouts.Adapter timeoutsAdapter,
             AsyncRingtonePlayer asyncRingtonePlayer,
             PhoneNumberUtilsAdapter phoneNumberUtilsAdapter,
-            InterruptionFilterProxy interruptionFilterProxy,
             IncomingCallNotifier incomingCallNotifier) {
         mContext = context.getApplicationContext();
         LogUtils.initLogging(mContext);
@@ -254,7 +253,6 @@
                 timeoutsAdapter,
                 asyncRingtonePlayer,
                 phoneNumberUtilsAdapter,
-                interruptionFilterProxy,
                 emergencyCallHelper);
 
         mIncomingCallNotifier = incomingCallNotifier;
diff --git a/src/com/android/server/telecom/components/TelecomService.java b/src/com/android/server/telecom/components/TelecomService.java
index a2ca9cb..56c1e08 100644
--- a/src/com/android/server/telecom/components/TelecomService.java
+++ b/src/com/android/server/telecom/components/TelecomService.java
@@ -16,7 +16,6 @@
 
 package com.android.server.telecom.components;
 
-import android.app.NotificationManager;
 import android.app.Service;
 import android.bluetooth.BluetoothAdapter;
 import android.content.Context;
@@ -25,9 +24,7 @@
 import android.os.IBinder;
 import android.os.PowerManager;
 import android.os.ServiceManager;
-import android.service.notification.ZenModeConfig;
 import android.telecom.Log;
-import android.telecom.PhoneAccountHandle;
 
 import com.android.internal.telephony.CallerInfoAsyncQuery;
 import com.android.server.telecom.AsyncRingtonePlayer;
@@ -40,7 +37,6 @@
 import com.android.server.telecom.HeadsetMediaButtonFactory;
 import com.android.server.telecom.InCallWakeLockControllerFactory;
 import com.android.server.telecom.CallAudioManager;
-import com.android.server.telecom.InterruptionFilterProxy;
 import com.android.server.telecom.PhoneAccountRegistrar;
 import com.android.server.telecom.PhoneNumberUtilsAdapterImpl;
 import com.android.server.telecom.ProximitySensorManagerFactory;
@@ -79,9 +75,6 @@
      */
     static void initializeTelecomSystem(Context context) {
         if (TelecomSystem.getInstance() == null) {
-            final NotificationManager notificationManager =
-                    (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
-
             NotificationChannelManager notificationChannelManager =
                     new NotificationChannelManager();
             notificationChannelManager.createChannels(context);
@@ -165,26 +158,6 @@
                             new Timeouts.Adapter(),
                             new AsyncRingtonePlayer(),
                             new PhoneNumberUtilsAdapterImpl(),
-                            new InterruptionFilterProxy() {
-                                @Override
-                                public void setInterruptionFilter(int interruptionFilter) {
-                                    notificationManager.setInterruptionFilter(interruptionFilter);
-                                }
-
-                                @Override
-                                public int getCurrentInterruptionFilter() {
-                                    return notificationManager.getCurrentInterruptionFilter();
-                                }
-
-                                @Override
-                                public String getInterruptionModeInitiator() {
-                                    ZenModeConfig config = notificationManager.getZenModeConfig();
-                                    if (config.manualRule != null) {
-                                        return config.manualRule.enabler;
-                                    }
-                                    return null;
-                                }
-                            },
                             new IncomingCallNotifier(context)
                     ));
         }
diff --git a/src/com/android/server/telecom/ui/IncomingCallNotifier.java b/src/com/android/server/telecom/ui/IncomingCallNotifier.java
index d7a2477..ea3105d 100644
--- a/src/com/android/server/telecom/ui/IncomingCallNotifier.java
+++ b/src/com/android/server/telecom/ui/IncomingCallNotifier.java
@@ -263,7 +263,7 @@
         builder.setContentTitle(incomingCallText);
         builder.setContentText(disconnectText);
         builder.setSmallIcon(R.drawable.ic_phone);
-        builder.setChannel(NotificationChannelManager.CHANNEL_ID_INCOMING_CALLS);
+        builder.setChannelId(NotificationChannelManager.CHANNEL_ID_INCOMING_CALLS);
         // Ensures this is a heads up notification.  A heads-up notification is typically only shown
         // if there is a fullscreen intent.  However since this notification doesn't have that we
         // will use this trick to get it to show as one anyways.
diff --git a/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java b/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java
index 1081c98..bbacd36 100644
--- a/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java
+++ b/src/com/android/server/telecom/ui/MissedCallNotifierImpl.java
@@ -332,7 +332,7 @@
                 // notification is shown on the user's lock screen and they have chosen to hide
                 // sensitive notification information.
                 .setPublicVersion(publicBuilder.build())
-                .setChannel(NotificationChannelManager.CHANNEL_ID_MISSED_CALLS);
+                .setChannelId(NotificationChannelManager.CHANNEL_ID_MISSED_CALLS);
 
         Uri handleUri = callInfo.getHandle();
         String handle = callInfo.getHandleSchemeSpecificPart();
diff --git a/testapps/AndroidManifest.xml b/testapps/AndroidManifest.xml
index 6980a12..592145b 100644
--- a/testapps/AndroidManifest.xml
+++ b/testapps/AndroidManifest.xml
@@ -66,7 +66,8 @@
             <intent-filter>
                 <action android:name="android.server.telecom.testapps.ACTION_SEND_UPDATE_REQUEST_FROM_TEST_INCALL_SERVICE"/>
                 <action android:name="android.server.telecom.testapps.ACTION_SEND_UPGRADE_RESPONSE"/>
-                <data android:scheme="int" />
+                <action android:name="android.telecom.action.PHONE_ACCOUNT_REGISTERED"/>
+                <action android:name="android.telecom.action.PHONE_ACCOUNT_UNREGISTERED"/>
             </intent-filter>
         </receiver>
 
diff --git a/testapps/src/com/android/server/telecom/testapps/TestInCallServiceBroadcastReceiver.java b/testapps/src/com/android/server/telecom/testapps/TestInCallServiceBroadcastReceiver.java
index b6902bf..3371060 100644
--- a/testapps/src/com/android/server/telecom/testapps/TestInCallServiceBroadcastReceiver.java
+++ b/testapps/src/com/android/server/telecom/testapps/TestInCallServiceBroadcastReceiver.java
@@ -19,6 +19,7 @@
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.telecom.TelecomManager;
 import android.util.Log;
 
 /**
@@ -56,6 +57,12 @@
         } else if (ACTION_SEND_UPGRADE_RESPONSE.equals(action)) {
             final int videoState = Integer.parseInt(intent.getData().getSchemeSpecificPart());
             TestCallList.getInstance().sendUpgradeToVideoResponse(videoState);
+        } else if (TelecomManager.ACTION_PHONE_ACCOUNT_REGISTERED.equals(action)) {
+            Log.i(TAG, "onReceive: registered " + intent.getExtras().get(
+                    TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE));
+        } else if (TelecomManager.ACTION_PHONE_ACCOUNT_UNREGISTERED.equals(action)) {
+            Log.i(TAG, "onReceive: unregistered " + intent.getExtras().get(
+                    TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE));
         }
     }
 }
diff --git a/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java b/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java
index 14fdf05..d0d7c8e 100644
--- a/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.media.AudioManager;
 import android.media.IAudioService;
+import android.os.Handler;
 import android.telecom.CallAudioState;
 import android.test.suitebuilder.annotation.LargeTest;
 import android.test.suitebuilder.annotation.MediumTest;
@@ -32,7 +33,6 @@
 import com.android.server.telecom.CallsManager;
 import com.android.server.telecom.ConnectionServiceWrapper;
 import com.android.server.telecom.CallAudioManager;
-import com.android.server.telecom.InterruptionFilterProxy;
 import com.android.server.telecom.StatusBarNotifier;
 import com.android.server.telecom.TelecomSystem;
 import com.android.server.telecom.WiredHeadsetManager;
@@ -72,39 +72,30 @@
     static class RoutingTestParameters extends TestParameters {
         public String name;
         public int initialRoute;
-        public int initialNotificationFilter;
         public int availableRoutes; // may excl. speakerphone, because that's always available
         public int speakerInteraction; // one of NONE, ON, or OFF
         public int bluetoothInteraction; // one of NONE, ON, or OFF
         public int action;
         public int expectedRoute;
         public int expectedAvailableRoutes; // also may exclude the speakerphone.
-        public int expectedNotificationFilter; // expected end notification filter.
-        public boolean isNotificationChangeExpected; // indicates whether we expect the notification
-                                                     // filter to change during the process of the
-                                                     // test.
         public boolean doesDeviceSupportEarpiece; // set to false in the case of Wear devices
         public boolean shouldRunWithFocus;
 
         public int callSupportedRoutes = CallAudioState.ROUTE_ALL;
 
         public RoutingTestParameters(String name, int initialRoute,
-                int initialNotificationFilter, int availableRoutes, int speakerInteraction,
+                int availableRoutes, int speakerInteraction,
                 int bluetoothInteraction, int action, int expectedRoute,
-                int expectedAvailableRoutes, int expectedNotificationFilter,
-                boolean isNotificationChangeExpected, boolean doesDeviceSupportEarpiece,
+                int expectedAvailableRoutes, boolean doesDeviceSupportEarpiece,
                 boolean shouldRunWithFocus) {
             this.name = name;
             this.initialRoute = initialRoute;
-            this.initialNotificationFilter = initialNotificationFilter;
             this.availableRoutes = availableRoutes;
             this.speakerInteraction = speakerInteraction;
             this.bluetoothInteraction = bluetoothInteraction;
             this.action = action;
             this.expectedRoute = expectedRoute;
             this.expectedAvailableRoutes = expectedAvailableRoutes;
-            this.expectedNotificationFilter = expectedNotificationFilter;
-            this.isNotificationChangeExpected = isNotificationChangeExpected;
             this.doesDeviceSupportEarpiece = doesDeviceSupportEarpiece;
             this.shouldRunWithFocus = shouldRunWithFocus;
         }
@@ -119,15 +110,12 @@
             return "RoutingTestParameters{" +
                     "name='" + name + '\'' +
                     ", initialRoute=" + initialRoute +
-                    ", initialNotificationFilter=" + initialNotificationFilter +
                     ", availableRoutes=" + availableRoutes +
                     ", speakerInteraction=" + speakerInteraction +
                     ", bluetoothInteraction=" + bluetoothInteraction +
                     ", action=" + action +
                     ", expectedRoute=" + expectedRoute +
                     ", expectedAvailableRoutes=" + expectedAvailableRoutes +
-                    ", expectedNotificationFilter= " + expectedNotificationFilter +
-                    ", isNotificationChangeExpected=" + isNotificationChangeExpected +
                     ", doesDeviceSupportEarpiece=" + doesDeviceSupportEarpiece +
                     ", shouldRunWithFocus=" + shouldRunWithFocus +
                     '}';
@@ -141,7 +129,6 @@
     @Mock WiredHeadsetManager mockWiredHeadsetManager;
     @Mock StatusBarNotifier mockStatusBarNotifier;
     @Mock Call fakeCall;
-    @Mock InterruptionFilterProxy mMockInterruptionFilterProxy;
 
     private CallAudioManager.AudioServiceFactory mAudioServiceFactory;
     private static final int TEST_TIMEOUT = 500;
@@ -168,29 +155,11 @@
         when(fakeCall.getConnectionService()).thenReturn(mockConnectionServiceWrapper);
         when(fakeCall.isAlive()).thenReturn(true);
         when(fakeCall.getSupportedAudioRoutes()).thenReturn(CallAudioState.ROUTE_ALL);
-        setupInterruptionFilterMocks();
 
         doNothing().when(mockConnectionServiceWrapper).onCallAudioStateChanged(any(Call.class),
                 any(CallAudioState.class));
     }
 
-    private void setupInterruptionFilterMocks() {
-        // These mock implementations keep track of when the caller sets the current notification
-        // filter, and ensures the same value is returned via getCurrentInterruptionFilter.
-        final int objId = Objects.hashCode(mMockInterruptionFilterProxy);
-        when(mMockInterruptionFilterProxy.getCurrentInterruptionFilter()).thenReturn(
-                NotificationManager.INTERRUPTION_FILTER_ALL);
-        doAnswer(new Answer<Void>() {
-            @Override
-            public Void answer(InvocationOnMock i) {
-                int requestedFilter = (int) i.getArguments()[0];
-                when(mMockInterruptionFilterProxy.getCurrentInterruptionFilter()).thenReturn(
-                        requestedFilter);
-                return null;
-            }
-        }).when(mMockInterruptionFilterProxy).setInterruptionFilter(anyInt());
-    }
-
     @LargeTest
     public void testStateMachineTransitionsWithFocus() throws Throwable {
         List<RoutingTestParameters> paramList = generateTransitionTests(true);
@@ -212,7 +181,6 @@
                 mockWiredHeadsetManager,
                 mockStatusBarNotifier,
                 mAudioServiceFactory,
-                mMockInterruptionFilterProxy,
                 true);
 
         when(mockBluetoothRouteManager.isBluetoothAudioConnectedOrPending()).thenReturn(false);
@@ -255,7 +223,6 @@
                 mockWiredHeadsetManager,
                 mockStatusBarNotifier,
                 mAudioServiceFactory,
-                mMockInterruptionFilterProxy,
                 true);
 
         when(mockBluetoothRouteManager.isBluetoothAudioConnectedOrPending()).thenReturn(false);
@@ -276,9 +243,6 @@
 
         waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE);
         verifyNewSystemCallAudioState(initState, expectedEndState);
-        // Expecting to end up in earpiece, so we expect notifications to be filtered.
-        assertEquals(NotificationManager.INTERRUPTION_FILTER_ALARMS,
-                mMockInterruptionFilterProxy.getCurrentInterruptionFilter());
         resetMocks(false);
         stateMachine.sendMessageWithSessionInfo(
                 CallAudioRouteStateMachine.DISCONNECT_BLUETOOTH);
@@ -298,7 +262,6 @@
                 mockWiredHeadsetManager,
                 mockStatusBarNotifier,
                 mAudioServiceFactory,
-                mMockInterruptionFilterProxy,
                 true);
 
         when(mockBluetoothRouteManager.isBluetoothAudioConnectedOrPending()).thenReturn(false);
@@ -314,9 +277,6 @@
         waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE);
 
         verify(mockBluetoothRouteManager, never()).connectBluetoothAudio(null);
-        // Shouldn't change interruption filter when in bluetooth route.
-        assertEquals(NotificationManager.INTERRUPTION_FILTER_ALL,
-                mMockInterruptionFilterProxy.getCurrentInterruptionFilter());
 
         stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.SWITCH_FOCUS,
                 CallAudioRouteStateMachine.ACTIVE_FOCUS);
@@ -333,7 +293,6 @@
                 mockWiredHeadsetManager,
                 mockStatusBarNotifier,
                 mAudioServiceFactory,
-                mMockInterruptionFilterProxy,
                 true);
 
         when(mockBluetoothRouteManager.isBluetoothAudioConnectedOrPending()).thenReturn(false);
@@ -435,7 +394,6 @@
                 mockWiredHeadsetManager,
                 mockStatusBarNotifier,
                 mAudioServiceFactory,
-                mMockInterruptionFilterProxy,
                 doesDeviceSupportEarpiece);
         stateMachine.initialize();
         assertEquals(expectedState, stateMachine.getCurrentCallAudioState());
@@ -446,15 +404,12 @@
         params.add(new RoutingTestParameters(
                 "Connect headset during earpiece", // name
                 CallAudioState.ROUTE_EARPIECE, // initialRoute
-                NotificationManager.INTERRUPTION_FILTER_ALL, // initialNotificationFilter
                 CallAudioState.ROUTE_EARPIECE, // availableRoutes
                 NONE, // speakerInteraction
                 NONE, // bluetoothInteraction
                 CallAudioRouteStateMachine.CONNECT_WIRED_HEADSET, // action
                 CallAudioState.ROUTE_WIRED_HEADSET, // expectedRoute
                 CallAudioState.ROUTE_WIRED_HEADSET, // expectedAvailableRoutes
-                NotificationManager.INTERRUPTION_FILTER_ALL, // expectedNotificationFilter
-                true, // isNotificationChangeExpected
                 true, // doesDeviceSupportEarpiece
                 shouldRunWithFocus
         ));
@@ -462,15 +417,12 @@
         params.add(new RoutingTestParameters(
                 "Connect headset during bluetooth", // name
                 CallAudioState.ROUTE_BLUETOOTH, // initialRoute
-                NotificationManager.INTERRUPTION_FILTER_ALL, // initialNotificationFilter
                 CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, // availableRoutes
                 NONE, // speakerInteraction
                 OFF, // bluetoothInteraction
                 CallAudioRouteStateMachine.CONNECT_WIRED_HEADSET, // action
                 CallAudioState.ROUTE_WIRED_HEADSET, // expectedRoute
                 CallAudioState.ROUTE_WIRED_HEADSET | CallAudioState.ROUTE_BLUETOOTH, // expectedAvai
-                NotificationManager.INTERRUPTION_FILTER_ALL, // expectedNotificationFilter
-                false, // isNotificationChangeExpected
                 true, // doesDeviceSupportEarpiece
                 shouldRunWithFocus
         ));
@@ -478,15 +430,12 @@
         params.add(new RoutingTestParameters(
                 "Connect headset during speakerphone", // name
                 CallAudioState.ROUTE_SPEAKER, // initialRoute
-                NotificationManager.INTERRUPTION_FILTER_ALL, // initialNotificationFilter
                 CallAudioState.ROUTE_EARPIECE, // availableRoutes
                 OFF, // speakerInteraction
                 NONE, // bluetoothInteraction
                 CallAudioRouteStateMachine.CONNECT_WIRED_HEADSET, // action
                 CallAudioState.ROUTE_WIRED_HEADSET, // expectedRoute
                 CallAudioState.ROUTE_WIRED_HEADSET, // expectedAvailableRoutes
-                NotificationManager.INTERRUPTION_FILTER_ALL, // expectedNotificationFilter
-                false, // isNotificationChangeExpected
                 true, // doesDeviceSupportEarpiece
                 shouldRunWithFocus
         ));
@@ -494,15 +443,12 @@
         params.add(new RoutingTestParameters(
                 "Disconnect headset during headset", // name
                 CallAudioState.ROUTE_WIRED_HEADSET, // initialRoute
-                NotificationManager.INTERRUPTION_FILTER_ALL, // initialNotificationFilter
                 CallAudioState.ROUTE_WIRED_HEADSET, // availableRoutes
                 NONE, // speakerInteraction
                 NONE, // bluetoothInteraction
                 CallAudioRouteStateMachine.DISCONNECT_WIRED_HEADSET, // action
                 CallAudioState.ROUTE_EARPIECE, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE, // expectedAvailableRoutes
-                NotificationManager.INTERRUPTION_FILTER_ALARMS, // expectedNotificationFilter
-                true, // isNotificationChangeExpected
                 true, // doesDeviceSupportEarpiece
                 shouldRunWithFocus
         ));
@@ -510,15 +456,12 @@
         params.add(new RoutingTestParameters(
                 "Disconnect headset during headset with bluetooth available", // name
                 CallAudioState.ROUTE_WIRED_HEADSET, // initialRoute
-                NotificationManager.INTERRUPTION_FILTER_ALL, // initialNotificationFilter
                 CallAudioState.ROUTE_WIRED_HEADSET | CallAudioState.ROUTE_BLUETOOTH, // availableRou
                 NONE, // speakerInteraction
                 NONE, // bluetoothInteraction
                 CallAudioRouteStateMachine.DISCONNECT_WIRED_HEADSET, // action
                 CallAudioState.ROUTE_EARPIECE, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, // expectedAvailable
-                NotificationManager.INTERRUPTION_FILTER_ALARMS, // expectedNotificationFilter
-                true, // isNotificationChangeExpected
                 true, // doesDeviceSupportEarpiece
                 shouldRunWithFocus
         ));
@@ -526,15 +469,12 @@
         params.add(new RoutingTestParameters(
                 "Disconnect headset during bluetooth", // name
                 CallAudioState.ROUTE_BLUETOOTH, // initialRoute
-                NotificationManager.INTERRUPTION_FILTER_ALL, // initialNotificationFilter
                 CallAudioState.ROUTE_WIRED_HEADSET | CallAudioState.ROUTE_BLUETOOTH, // availableRou
                 NONE, // speakerInteraction
                 NONE, // bluetoothInteraction
                 CallAudioRouteStateMachine.DISCONNECT_WIRED_HEADSET, // action
                 CallAudioState.ROUTE_BLUETOOTH, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, // expectedAvailable
-                NotificationManager.INTERRUPTION_FILTER_ALL, // expectedNotificationFilter
-                false, // isNotificationChangeExpected
                 true, // doesDeviceSupportEarpiece
                 shouldRunWithFocus
         ));
@@ -542,15 +482,12 @@
         params.add(new RoutingTestParameters(
                 "Disconnect headset during speakerphone", // name
                 CallAudioState.ROUTE_SPEAKER, // initialRoute
-                NotificationManager.INTERRUPTION_FILTER_ALL, // initialNotificationFilter
                 CallAudioState.ROUTE_WIRED_HEADSET, // availableRoutes
                 NONE, // speakerInteraction
                 NONE, // bluetoothInteraction
                 CallAudioRouteStateMachine.DISCONNECT_WIRED_HEADSET, // action
                 CallAudioState.ROUTE_SPEAKER, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE, // expectedAvailableRoutes
-                NotificationManager.INTERRUPTION_FILTER_ALL, // expectedNotificationFilter
-                false, // isNotificationChangeExpected
                 true, // doesDeviceSupportEarpiece
                 shouldRunWithFocus
         ));
@@ -558,15 +495,12 @@
         params.add(new RoutingTestParameters(
                 "Disconnect headset during speakerphone with bluetooth available", // name
                 CallAudioState.ROUTE_SPEAKER, // initialRoute
-                NotificationManager.INTERRUPTION_FILTER_ALL, // initialNotificationFilter
                 CallAudioState.ROUTE_WIRED_HEADSET | CallAudioState.ROUTE_BLUETOOTH, // availableRou
                 NONE, // speakerInteraction
                 NONE, // bluetoothInteraction
                 CallAudioRouteStateMachine.DISCONNECT_WIRED_HEADSET, // action
                 CallAudioState.ROUTE_SPEAKER, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, // expectedAvailable
-                NotificationManager.INTERRUPTION_FILTER_ALL, // expectedNotificationFilter
-                false, // isNotificationChangeExpected
                 true, // doesDeviceSupportEarpiece
                 shouldRunWithFocus
         ));
@@ -574,15 +508,12 @@
         params.add(new RoutingTestParameters(
                 "Connect bluetooth during earpiece", // name
                 CallAudioState.ROUTE_EARPIECE, // initialRoute
-                NotificationManager.INTERRUPTION_FILTER_ALL, // initialNotificationFilter
                 CallAudioState.ROUTE_EARPIECE, // availableRoutes
                 NONE, // speakerInteraction
                 ON, // bluetoothInteraction
                 CallAudioRouteStateMachine.CONNECT_BLUETOOTH, // action
                 CallAudioState.ROUTE_BLUETOOTH, // expectedRoute
                 CallAudioState.ROUTE_BLUETOOTH | CallAudioState.ROUTE_EARPIECE, // expectedAvailable
-                NotificationManager.INTERRUPTION_FILTER_ALL, // expectedNotificationFilter
-                true, // isNotificationChangeExpected
                 true, // doesDeviceSupportEarpiece
                 shouldRunWithFocus
         ));
@@ -590,15 +521,12 @@
         params.add(new RoutingTestParameters(
                 "Connect bluetooth during wired headset", // name
                 CallAudioState.ROUTE_WIRED_HEADSET, // initialRoute
-                NotificationManager.INTERRUPTION_FILTER_ALL, // initialNotificationFilter
                 CallAudioState.ROUTE_WIRED_HEADSET, // availableRoutes
                 NONE, // speakerInteraction
                 ON, // bluetoothInteraction
                 CallAudioRouteStateMachine.CONNECT_BLUETOOTH, // action
                 CallAudioState.ROUTE_BLUETOOTH, // expectedRoute
                 CallAudioState.ROUTE_BLUETOOTH | CallAudioState.ROUTE_WIRED_HEADSET, // expectedAvai
-                NotificationManager.INTERRUPTION_FILTER_ALL, // expectedNotificationFilter
-                false, // isNotificationChangeExpected
                 true, // doesDeviceSupportEarpiece
                 shouldRunWithFocus
         ));
@@ -606,15 +534,12 @@
         params.add(new RoutingTestParameters(
                 "Connect bluetooth during speakerphone", // name
                 CallAudioState.ROUTE_SPEAKER, // initialRoute
-                NotificationManager.INTERRUPTION_FILTER_ALL, // initialNotificationFilter
                 CallAudioState.ROUTE_EARPIECE, // availableRoutes
                 OFF, // speakerInteraction
                 ON, // bluetoothInteraction
                 CallAudioRouteStateMachine.CONNECT_BLUETOOTH, // action
                 CallAudioState.ROUTE_BLUETOOTH, // expectedRoute
                 CallAudioState.ROUTE_BLUETOOTH | CallAudioState.ROUTE_EARPIECE, // expectedAvailable
-                NotificationManager.INTERRUPTION_FILTER_ALL, // expectedNotificationFilter
-                false, // isNotificationChangeExpected
                 true, // doesDeviceSupportEarpiece
                 shouldRunWithFocus
         ));
@@ -622,15 +547,12 @@
         params.add(new RoutingTestParameters(
                 "Disconnect bluetooth during bluetooth without headset in", // name
                 CallAudioState.ROUTE_BLUETOOTH, // initialRoute
-                NotificationManager.INTERRUPTION_FILTER_ALL, // initialNotificationFilter
                 CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, // availableRoutes
                 NONE, // speakerInteraction
                 OFF, // bluetoothInteraction
                 CallAudioRouteStateMachine.DISCONNECT_BLUETOOTH, // action
                 CallAudioState.ROUTE_EARPIECE, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE, // expectedAvailableRoutes
-                NotificationManager.INTERRUPTION_FILTER_ALARMS, // expectedNotificationFilter
-                true, // isNotificationChangeExpected
                 true, // doesDeviceSupportEarpiece
                 shouldRunWithFocus
         ));
@@ -638,15 +560,12 @@
         params.add(new RoutingTestParameters(
                 "Disconnect bluetooth during bluetooth without headset in, priority mode ", // name
                 CallAudioState.ROUTE_BLUETOOTH, // initialRoute
-                NotificationManager.INTERRUPTION_FILTER_PRIORITY, // initialNotificationFilter
                 CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, // availableRoutes
                 NONE, // speakerInteraction
                 OFF, // bluetoothInteraction
                 CallAudioRouteStateMachine.DISCONNECT_BLUETOOTH, // action
                 CallAudioState.ROUTE_EARPIECE, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE, // expectedAvailableRoutes
-                NotificationManager.INTERRUPTION_FILTER_PRIORITY, // expectedNotificationFilter
-                false, // isNotificationChangeExpected
                 true, // doesDeviceSupportEarpiece
                 shouldRunWithFocus
         ));
@@ -654,15 +573,12 @@
         params.add(new RoutingTestParameters(
                 "Disconnect bluetooth during bluetooth with headset in", // name
                 CallAudioState.ROUTE_BLUETOOTH, // initialRoute
-                NotificationManager.INTERRUPTION_FILTER_ALL, // initialNotificationFilter
                 CallAudioState.ROUTE_WIRED_HEADSET | CallAudioState.ROUTE_BLUETOOTH, // availableRou
                 NONE, // speakerInteraction
                 OFF, // bluetoothInteraction
                 CallAudioRouteStateMachine.DISCONNECT_BLUETOOTH, // action
                 CallAudioState.ROUTE_WIRED_HEADSET, // expectedRoute
                 CallAudioState.ROUTE_WIRED_HEADSET, // expectedAvailableRoutes
-                NotificationManager.INTERRUPTION_FILTER_ALL, // expectedNotificationFilter
-                false, // isNotificationChangeExpected
                 true, // doesDeviceSupportEarpiece
                 shouldRunWithFocus
         ));
@@ -670,15 +586,12 @@
         params.add(new RoutingTestParameters(
                 "Disconnect bluetooth during speakerphone", // name
                 CallAudioState.ROUTE_SPEAKER, // initialRoute
-                NotificationManager.INTERRUPTION_FILTER_ALL, // initialNotificationFilter
                 CallAudioState.ROUTE_WIRED_HEADSET | CallAudioState.ROUTE_BLUETOOTH, // availableRou
                 NONE, // speakerInteraction
                 NONE, // bluetoothInteraction
                 CallAudioRouteStateMachine.DISCONNECT_BLUETOOTH, // action
                 CallAudioState.ROUTE_SPEAKER, // expectedRoute
                 CallAudioState.ROUTE_WIRED_HEADSET, // expectedAvailableRoutes
-                NotificationManager.INTERRUPTION_FILTER_ALL, // expectedNotificationFilter
-                false, // isNotificationChangeExpected
                 true, // doesDeviceSupportEarpiece
                 shouldRunWithFocus
         ));
@@ -686,15 +599,12 @@
         params.add(new RoutingTestParameters(
                 "Disconnect bluetooth during earpiece", // name
                 CallAudioState.ROUTE_EARPIECE, // initialRoute
-                NotificationManager.INTERRUPTION_FILTER_ALL, // initialNotificationFilter
                 CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, // availableRoutes
                 NONE, // speakerInteraction
                 NONE, // bluetoothInteraction
                 CallAudioRouteStateMachine.DISCONNECT_BLUETOOTH, // action
                 CallAudioState.ROUTE_EARPIECE, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE, // expectedAvailableRoutes
-                NotificationManager.INTERRUPTION_FILTER_ALARMS, // expectedNotificationFilter
-                true, // isNotificationChangeExpected
                 true, // doesDeviceSupportEarpiece
                 shouldRunWithFocus
         ));
@@ -702,15 +612,12 @@
         params.add(new RoutingTestParameters(
                 "Switch to speakerphone from earpiece", // name
                 CallAudioState.ROUTE_EARPIECE, // initialRoute
-                NotificationManager.INTERRUPTION_FILTER_ALL, // initialNotificationFilter
                 CallAudioState.ROUTE_EARPIECE, // availableRoutes
                 ON, // speakerInteraction
                 NONE, // bluetoothInteraction
                 CallAudioRouteStateMachine.SWITCH_SPEAKER, // action
                 CallAudioState.ROUTE_SPEAKER, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE, // expectedAvailableRoutes
-                NotificationManager.INTERRUPTION_FILTER_ALL, // expectedNotificationFilter
-                true, // isNotificationChangeExpected
                 true, // doesDeviceSupportEarpiece
                 shouldRunWithFocus
         ));
@@ -718,15 +625,12 @@
         params.add(new RoutingTestParameters(
                 "Switch to speakerphone from headset", // name
                 CallAudioState.ROUTE_WIRED_HEADSET, // initialRoute
-                NotificationManager.INTERRUPTION_FILTER_ALL, // initialNotificationFilter
                 CallAudioState.ROUTE_WIRED_HEADSET, // availableRoutes
                 ON, // speakerInteraction
                 NONE, // bluetoothInteraction
                 CallAudioRouteStateMachine.SWITCH_SPEAKER, // action
                 CallAudioState.ROUTE_SPEAKER, // expectedRoute
                 CallAudioState.ROUTE_WIRED_HEADSET, // expectedAvailableRoutes
-                NotificationManager.INTERRUPTION_FILTER_ALL, // expectedNotificationFilter
-                false, // isNotificationChangeExpected
                 true, // doesDeviceSupportEarpiece
                 shouldRunWithFocus
         ));
@@ -734,15 +638,12 @@
         params.add(new RoutingTestParameters(
                 "Switch to speakerphone from bluetooth", // name
                 CallAudioState.ROUTE_BLUETOOTH, // initialRoute
-                NotificationManager.INTERRUPTION_FILTER_ALL, // initialNotificationFilter
                 CallAudioState.ROUTE_WIRED_HEADSET | CallAudioState.ROUTE_BLUETOOTH, // availableRou
                 ON, // speakerInteraction
                 OFF, // bluetoothInteraction
                 CallAudioRouteStateMachine.SWITCH_SPEAKER, // action
                 CallAudioState.ROUTE_SPEAKER, // expectedRoute
                 CallAudioState.ROUTE_WIRED_HEADSET | CallAudioState.ROUTE_BLUETOOTH, // expectedAvai
-                NotificationManager.INTERRUPTION_FILTER_ALL, // expectedNotificationFilter
-                false, // isNotificationChangeExpected
                 true, // doesDeviceSupportEarpiece
                 shouldRunWithFocus
         ));
@@ -750,15 +651,12 @@
         params.add(new RoutingTestParameters(
                 "Switch to earpiece from bluetooth", // name
                 CallAudioState.ROUTE_BLUETOOTH, // initialRoute
-                NotificationManager.INTERRUPTION_FILTER_ALL, // initialNotificationFilter
                 CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, // availableRoutes
                 NONE, // speakerInteraction
                 OFF, // bluetoothInteraction
                 CallAudioRouteStateMachine.SWITCH_EARPIECE, // action
                 CallAudioState.ROUTE_EARPIECE, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, // expectedAvailable
-                NotificationManager.INTERRUPTION_FILTER_ALARMS, // expectedNotificationFilter
-                true, // isNotificationChangeExpected
                 true, // doesDeviceSupportEarpiece
                 shouldRunWithFocus
         ));
@@ -766,15 +664,12 @@
         params.add(new RoutingTestParameters(
                 "Switch to earpiece from speakerphone", // name
                 CallAudioState.ROUTE_SPEAKER, // initialRoute
-                NotificationManager.INTERRUPTION_FILTER_ALL, // initialNotificationFilter
                 CallAudioState.ROUTE_EARPIECE, // availableRoutes
                 OFF, // speakerInteraction
                 NONE, // bluetoothInteraction
                 CallAudioRouteStateMachine.SWITCH_EARPIECE, // action
                 CallAudioState.ROUTE_EARPIECE, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE, // expectedAvailableRoutes
-                NotificationManager.INTERRUPTION_FILTER_ALARMS, // expectedNotificationFilter
-                true, // isNotificationChangeExpected
                 true, // doesDeviceSupportEarpiece
                 shouldRunWithFocus
         ));
@@ -782,15 +677,12 @@
         params.add(new RoutingTestParameters(
                 "Switch to earpiece from speakerphone, priority notifications", // name
                 CallAudioState.ROUTE_SPEAKER, // initialRoute
-                NotificationManager.INTERRUPTION_FILTER_PRIORITY, // initialNotificationFilter
                 CallAudioState.ROUTE_EARPIECE, // availableRoutes
                 OFF, // speakerInteraction
                 NONE, // bluetoothInteraction
                 CallAudioRouteStateMachine.SWITCH_EARPIECE, // action
                 CallAudioState.ROUTE_EARPIECE, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE, // expectedAvailableRoutes
-                NotificationManager.INTERRUPTION_FILTER_PRIORITY, // expectedNotificationFilter
-                false, // isNotificationChangeExpected
                 true, // doesDeviceSupportEarpiece
                 shouldRunWithFocus
         ));
@@ -798,15 +690,12 @@
         params.add(new RoutingTestParameters(
                 "Switch to earpiece from speakerphone, silent mode", // name
                 CallAudioState.ROUTE_SPEAKER, // initialRoute
-                NotificationManager.INTERRUPTION_FILTER_NONE, // initialNotificationFilter
                 CallAudioState.ROUTE_EARPIECE, // availableRoutes
                 OFF, // speakerInteraction
                 NONE, // bluetoothInteraction
                 CallAudioRouteStateMachine.SWITCH_EARPIECE, // action
                 CallAudioState.ROUTE_EARPIECE, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE, // expectedAvailableRoutes
-                NotificationManager.INTERRUPTION_FILTER_NONE, // expectedNotificationFilter
-                false, // isNotificationChangeExpected
                 true, // doesDeviceSupportEarpiece
                 shouldRunWithFocus
         ));
@@ -814,15 +703,12 @@
         params.add(new RoutingTestParameters(
                 "Switch to bluetooth from speakerphone", // name
                 CallAudioState.ROUTE_SPEAKER, // initialRoute
-                NotificationManager.INTERRUPTION_FILTER_ALL, // initialNotificationFilter
                 CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, // availableRoutes
                 OFF, // speakerInteraction
                 ON, // bluetoothInteraction
                 CallAudioRouteStateMachine.SWITCH_BLUETOOTH, // action
                 CallAudioState.ROUTE_BLUETOOTH, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, // expectedAvailable
-                NotificationManager.INTERRUPTION_FILTER_ALL, // expectedNotificationFilter
-                false, // isNotificationChangeExpected
                 true, // doesDeviceSupportEarpiece
                 shouldRunWithFocus
         ));
@@ -830,15 +716,12 @@
         params.add(new RoutingTestParameters(
                 "Switch to bluetooth from earpiece", // name
                 CallAudioState.ROUTE_EARPIECE, // initialRoute
-                NotificationManager.INTERRUPTION_FILTER_ALL, // initialNotificationFilter
                 CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, // availableRoutes
                 NONE, // speakerInteraction
                 ON, // bluetoothInteraction
                 CallAudioRouteStateMachine.SWITCH_BLUETOOTH, // action
                 CallAudioState.ROUTE_BLUETOOTH, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, // expectedAvailable
-                NotificationManager.INTERRUPTION_FILTER_ALL, // expectedNotificationFilter
-                true, // isNotificationChangeExpected
                 true, // doesDeviceSupportEarpiece
                 shouldRunWithFocus
         ));
@@ -846,15 +729,12 @@
         params.add(new RoutingTestParameters(
                 "Switch to bluetooth from wired headset", // name
                 CallAudioState.ROUTE_WIRED_HEADSET, // initialRoute
-                NotificationManager.INTERRUPTION_FILTER_ALL, // initialNotificationFilter
                 CallAudioState.ROUTE_WIRED_HEADSET | CallAudioState.ROUTE_BLUETOOTH, // availableRou
                 NONE, // speakerInteraction
                 ON, // bluetoothInteraction
                 CallAudioRouteStateMachine.SWITCH_BLUETOOTH, // action
                 CallAudioState.ROUTE_BLUETOOTH, // expectedRoute
                 CallAudioState.ROUTE_WIRED_HEADSET | CallAudioState.ROUTE_BLUETOOTH, // expectedAvai
-                NotificationManager.INTERRUPTION_FILTER_ALL, // expectedNotificationFilter
-                false, // isNotificationChangeExpected
                 true, // doesDeviceSupportEarpiece
                 shouldRunWithFocus
         ));
@@ -862,15 +742,12 @@
         params.add(new RoutingTestParameters(
                 "Switch from bluetooth to wired/earpiece when neither are available", // name
                 CallAudioState.ROUTE_BLUETOOTH, // initialRoute
-                NotificationManager.INTERRUPTION_FILTER_ALL, // initialNotificationFilter
                 CallAudioState.ROUTE_BLUETOOTH, // availableRoutes
                 ON, // speakerInteraction
                 OFF, // bluetoothInteraction
                 CallAudioRouteStateMachine.SWITCH_BASELINE_ROUTE, // action
                 CallAudioState.ROUTE_SPEAKER, // expectedRoute
                 CallAudioState.ROUTE_BLUETOOTH, // expectedAvailableRoutes
-                NotificationManager.INTERRUPTION_FILTER_ALL, // expectedNotificationFilter
-                false, // isNotificationChangeExpected
                 false, // doesDeviceSupportEarpiece
                 shouldRunWithFocus
         ));
@@ -878,15 +755,12 @@
         params.add(new RoutingTestParameters(
                 "Disconnect wired headset when device does not support earpiece", // name
                 CallAudioState.ROUTE_WIRED_HEADSET, // initialRoute
-                NotificationManager.INTERRUPTION_FILTER_ALL, // initialNotificationFilter
                 CallAudioState.ROUTE_WIRED_HEADSET, // availableRoutes
                 ON, // speakerInteraction
                 NONE, // bluetoothInteraction
                 CallAudioRouteStateMachine.DISCONNECT_WIRED_HEADSET, // action
                 CallAudioState.ROUTE_SPEAKER, // expectedRoute
                 CallAudioState.ROUTE_SPEAKER, // expectedAvailableRoutes
-                NotificationManager.INTERRUPTION_FILTER_ALL, // expectedNotificationFilter
-                false, // isNotificationChangeExpected
                 false, // doesDeviceSupportEarpiece
                 shouldRunWithFocus
         ));
@@ -894,15 +768,12 @@
         params.add(new RoutingTestParameters(
                 "Disconnect wired headset when call doesn't support earpiece", // name
                 CallAudioState.ROUTE_WIRED_HEADSET, // initialRoute
-                NotificationManager.INTERRUPTION_FILTER_ALL, // initialNotificationFilter
                 CallAudioState.ROUTE_WIRED_HEADSET, // availableRoutes
                 ON, // speakerInteraction
                 NONE, // bluetoothInteraction
                 CallAudioRouteStateMachine.DISCONNECT_WIRED_HEADSET, // action
                 CallAudioState.ROUTE_SPEAKER, // expectedRoute
                 CallAudioState.ROUTE_SPEAKER, // expectedAvailableRoutes
-                NotificationManager.INTERRUPTION_FILTER_ALL, // expectedNotificationFilter
-                false, // isNotificationChangeExpected
                 true, // doesDeviceSupportEarpiece
                 shouldRunWithFocus
         ).setCallSupportedRoutes(CallAudioState.ROUTE_ALL & ~CallAudioState.ROUTE_EARPIECE));
@@ -910,15 +781,12 @@
         params.add(new RoutingTestParameters(
                 "Disconnect bluetooth when call does not support earpiece", // name
                 CallAudioState.ROUTE_BLUETOOTH, // initialRoute
-                NotificationManager.INTERRUPTION_FILTER_ALL, // initialNotificationFilter
                 CallAudioState.ROUTE_BLUETOOTH,  // availableRoutes
                 ON, // speakerInteraction
                 OFF, // bluetoothInteraction
                 CallAudioRouteStateMachine.DISCONNECT_BLUETOOTH, // action
                 CallAudioState.ROUTE_SPEAKER, // expectedRoute
                 CallAudioState.ROUTE_SPEAKER, // expectedAvailableRoutes
-                NotificationManager.INTERRUPTION_FILTER_ALL, // expectedNotificationFilter
-                false, // isNotificationChangeExpected
                 true, // doesDeviceSupportEarpiece
                 shouldRunWithFocus
         ).setCallSupportedRoutes(CallAudioState.ROUTE_ALL & ~CallAudioState.ROUTE_EARPIECE));
@@ -939,8 +807,6 @@
     private void runParametrizedTestCaseWithFocus(final RoutingTestParameters params)
             throws Throwable {
         resetMocks(true);
-        when(mMockInterruptionFilterProxy.getCurrentInterruptionFilter()).thenReturn(
-                params.initialNotificationFilter);
 
         // Construct a fresh state machine on every case
         final CallAudioRouteStateMachine stateMachine = new CallAudioRouteStateMachine(
@@ -950,7 +816,6 @@
                 mockWiredHeadsetManager,
                 mockStatusBarNotifier,
                 mAudioServiceFactory,
-                mMockInterruptionFilterProxy,
                 params.doesDeviceSupportEarpiece);
 
         setupMocksForParams(params);
@@ -972,22 +837,8 @@
 
         waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE);
 
-        // Capture the changes made to the interruption filter and verify that the last change
-        // made to it matches the expected interruption filter.
-        if (params.isNotificationChangeExpected) {
-            ArgumentCaptor<Integer> interruptionCaptor = ArgumentCaptor.forClass(Integer.class);
-            verify(mMockInterruptionFilterProxy, timeout(TEST_TIMEOUT).atLeastOnce())
-                    .setInterruptionFilter(interruptionCaptor.capture());
-            List<Integer> interruptionFilterValues = interruptionCaptor.getAllValues();
-
-            int lastChange = interruptionFilterValues.get(interruptionFilterValues.size() - 1)
-                    .intValue();
-            assertEquals(params.expectedNotificationFilter, lastChange);
-        } else {
-            Thread.sleep(TEST_TIMEOUT);
-            verify(mMockInterruptionFilterProxy, never()).setInterruptionFilter(anyInt());
-        }
-
+        Handler h = stateMachine.getHandler();
+        waitForHandlerAction(h, TEST_TIMEOUT);
         stateMachine.quitStateMachine();
 
         // Verify interactions with the speakerphone and bluetooth systems
@@ -1045,7 +896,6 @@
                 mockWiredHeadsetManager,
                 mockStatusBarNotifier,
                 mAudioServiceFactory,
-                mMockInterruptionFilterProxy,
                 params.doesDeviceSupportEarpiece);
 
         // Set up bluetooth and speakerphone state
@@ -1108,11 +958,6 @@
     private void resetMocks(boolean resetNotificationFilter) {
         reset(mockAudioManager, mockBluetoothRouteManager, mockCallsManager,
                 mockConnectionServiceWrapper, fakeCall);
-        if (resetNotificationFilter) {
-            reset(mMockInterruptionFilterProxy);
-            mMockInterruptionFilterProxy = mock(InterruptionFilterProxy.class);
-            setupInterruptionFilterMocks();
-        }
         when(mockCallsManager.getForegroundCall()).thenReturn(fakeCall);
         when(fakeCall.getConnectionService()).thenReturn(mockConnectionServiceWrapper);
         when(fakeCall.isAlive()).thenReturn(true);
diff --git a/tests/src/com/android/server/telecom/tests/RingerTest.java b/tests/src/com/android/server/telecom/tests/RingerTest.java
new file mode 100644
index 0000000..8b269a9
--- /dev/null
+++ b/tests/src/com/android/server/telecom/tests/RingerTest.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.telecom.tests;
+
+import android.app.NotificationManager;
+import android.content.Context;
+import android.media.AudioAttributes;
+import android.media.AudioManager;
+import android.media.Ringtone;
+import android.os.Bundle;
+import android.os.Vibrator;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.server.telecom.AsyncRingtonePlayer;
+import com.android.server.telecom.Call;
+import com.android.server.telecom.InCallController;
+import com.android.server.telecom.InCallTonePlayer;
+import com.android.server.telecom.Ringer;
+import com.android.server.telecom.RingtoneFactory;
+import com.android.server.telecom.SystemSettingsUtil;
+
+import org.mockito.Mock;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class RingerTest extends TelecomTestCase {
+    @Mock InCallTonePlayer.Factory mockPlayerFactory;
+    @Mock SystemSettingsUtil mockSystemSettingsUtil;
+    @Mock AsyncRingtonePlayer mockRingtonePlayer;
+    @Mock RingtoneFactory mockRingtoneFactory;
+    @Mock Vibrator mockVibrator;
+    @Mock InCallController mockInCallController;
+
+    @Mock InCallTonePlayer mockTonePlayer;
+    @Mock Call mockCall1;
+    @Mock Call mockCall2;
+
+    Ringer mRingerUnderTest;
+    AudioManager mockAudioManager;
+    public void setUp() throws Exception {
+        super.setUp();
+        mContext = mComponentContextFixture.getTestDouble().getApplicationContext();
+        mRingerUnderTest = new Ringer(mockPlayerFactory, mContext, mockSystemSettingsUtil,
+                mockRingtonePlayer, mockRingtoneFactory, mockVibrator, mockInCallController);
+        when(mockPlayerFactory.createPlayer(anyInt())).thenReturn(mockTonePlayer);
+        mockAudioManager =
+                (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+        when(mockAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
+        NotificationManager notificationManager =
+                (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+        when(notificationManager.matchesCallFilter(any(Bundle.class))).thenReturn(true);
+    }
+
+    @SmallTest
+    public void testNoActionInTheaterMode() {
+        // Start call waiting to make sure that it doesn't stop when we start ringing
+        mRingerUnderTest.startCallWaiting(mockCall1);
+        when(mockSystemSettingsUtil.isTheaterModeOn(any(Context.class))).thenReturn(true);
+        assertFalse(mRingerUnderTest.startRinging(mockCall2, false));
+        verify(mockTonePlayer, never()).stopTone();
+        verify(mockRingtonePlayer, never()).play(any(RingtoneFactory.class), any(Call.class));
+        verify(mockVibrator, never()).vibrate(
+                any(long[].class), anyInt(), any(AudioAttributes.class));
+    }
+
+    @SmallTest
+    public void testNoActionWhenDialerRings() {
+        // Start call waiting to make sure that it doesn't stop when we start ringing
+        mRingerUnderTest.startCallWaiting(mockCall1);
+        when(mockInCallController.doesConnectedDialerSupportRinging()).thenReturn(true);
+        assertFalse(mRingerUnderTest.startRinging(mockCall2, false));
+        verify(mockTonePlayer, never()).stopTone();
+        verify(mockRingtonePlayer, never()).play(any(RingtoneFactory.class), any(Call.class));
+        verify(mockVibrator, never()).vibrate(
+                any(long[].class), anyInt(), any(AudioAttributes.class));
+    }
+
+    @SmallTest
+    public void testAudioFocusStillAcquiredWhenDialerRings() {
+        // Start call waiting to make sure that it doesn't stop when we start ringing
+        mRingerUnderTest.startCallWaiting(mockCall1);
+        when(mockInCallController.doesConnectedDialerSupportRinging()).thenReturn(true);
+        ensureRingerIsAudible();
+        assertTrue(mRingerUnderTest.startRinging(mockCall2, false));
+        verify(mockTonePlayer, never()).stopTone();
+        verify(mockRingtonePlayer, never()).play(any(RingtoneFactory.class), any(Call.class));
+        verify(mockVibrator, never()).vibrate(
+                any(long[].class), anyInt(), any(AudioAttributes.class));
+    }
+
+    @SmallTest
+    public void testNoActionWhenCallIsSelfManaged() {
+        // Start call waiting to make sure that it doesn't stop when we start ringing
+        mRingerUnderTest.startCallWaiting(mockCall1);
+        when(mockCall2.isSelfManaged()).thenReturn(true);
+        // We do want to acquire audio focus when self-managed
+        assertTrue(mRingerUnderTest.startRinging(mockCall2, true));
+        verify(mockTonePlayer, never()).stopTone();
+        verify(mockRingtonePlayer, never()).play(any(RingtoneFactory.class), any(Call.class));
+        verify(mockVibrator, never()).vibrate(
+                any(long[].class), anyInt(), any(AudioAttributes.class));
+    }
+
+    @SmallTest
+    public void testCallWaitingButNoRingForSpecificContacts() {
+        NotificationManager notificationManager =
+                (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+        when(notificationManager.matchesCallFilter(any(Bundle.class))).thenReturn(false);
+        // Start call waiting to make sure that it does stop when we start ringing
+        mRingerUnderTest.startCallWaiting(mockCall1);
+        verify(mockTonePlayer).startTone();
+
+        assertFalse(mRingerUnderTest.startRinging(mockCall2, false));
+        verify(mockTonePlayer).stopTone();
+        verify(mockRingtonePlayer, never()).play(any(RingtoneFactory.class), any(Call.class));
+        verify(mockVibrator, never()).vibrate(
+                any(long[].class), anyInt(), any(AudioAttributes.class));
+    }
+
+    @SmallTest
+    public void testVibrateButNoRingForNullRingtone() {
+        mRingerUnderTest.startCallWaiting(mockCall1);
+        when(mockRingtoneFactory.getRingtone(any(Call.class))).thenReturn(null);
+        when(mockAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
+        enableVibrationWhenRinging();
+        assertFalse(mRingerUnderTest.startRinging(mockCall2, false));
+        verify(mockTonePlayer).stopTone();
+        verify(mockRingtonePlayer, never()).play(any(RingtoneFactory.class), any(Call.class));
+        verify(mockVibrator).vibrate(
+                any(long[].class), anyInt(), any(AudioAttributes.class));
+    }
+
+    @SmallTest
+    public void testVibrateButNoRingForSilentRingtone() {
+        mRingerUnderTest.startCallWaiting(mockCall1);
+        Ringtone mockRingtone = mock(Ringtone.class);
+        when(mockRingtoneFactory.getRingtone(any(Call.class))).thenReturn(mockRingtone);
+        when(mockAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
+        when(mockAudioManager.getStreamVolume(AudioManager.STREAM_RING)).thenReturn(0);
+        enableVibrationWhenRinging();
+        assertFalse(mRingerUnderTest.startRinging(mockCall2, false));
+        verify(mockTonePlayer).stopTone();
+        verify(mockRingtonePlayer, never()).play(any(RingtoneFactory.class), any(Call.class));
+        verify(mockVibrator).vibrate(
+                any(long[].class), anyInt(), any(AudioAttributes.class));
+    }
+
+    @SmallTest
+    public void testRingAndNoVibrate() {
+        mRingerUnderTest.startCallWaiting(mockCall1);
+        ensureRingerIsAudible();
+        enableVibrationOnlyWhenNotRinging();
+        assertTrue(mRingerUnderTest.startRinging(mockCall2, false));
+        verify(mockTonePlayer).stopTone();
+        verify(mockRingtonePlayer).play(any(RingtoneFactory.class), any(Call.class));
+        verify(mockVibrator, never()).vibrate(
+                any(long[].class), anyInt(), any(AudioAttributes.class));
+    }
+
+    @SmallTest
+    public void testSilentRingWithHfpStillAcquiresFocus1() {
+        mRingerUnderTest.startCallWaiting(mockCall1);
+        Ringtone mockRingtone = mock(Ringtone.class);
+        when(mockRingtoneFactory.getRingtone(any(Call.class))).thenReturn(mockRingtone);
+        when(mockAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
+        when(mockAudioManager.getStreamVolume(AudioManager.STREAM_RING)).thenReturn(0);
+        enableVibrationOnlyWhenNotRinging();
+        assertTrue(mRingerUnderTest.startRinging(mockCall2, true));
+        verify(mockTonePlayer).stopTone();
+        verify(mockRingtonePlayer, never()).play(any(RingtoneFactory.class), any(Call.class));
+        verify(mockVibrator, never()).vibrate(
+                any(long[].class), anyInt(), any(AudioAttributes.class));
+    }
+
+    @SmallTest
+    public void testSilentRingWithHfpStillAcquiresFocus2() {
+        mRingerUnderTest.startCallWaiting(mockCall1);
+        when(mockRingtoneFactory.getRingtone(any(Call.class))).thenReturn(null);
+        when(mockAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
+        when(mockAudioManager.getStreamVolume(AudioManager.STREAM_RING)).thenReturn(0);
+        enableVibrationOnlyWhenNotRinging();
+        assertTrue(mRingerUnderTest.startRinging(mockCall2, true));
+        verify(mockTonePlayer).stopTone();
+        verify(mockRingtonePlayer, never()).play(any(RingtoneFactory.class), any(Call.class));
+        verify(mockVibrator, never()).vibrate(
+                any(long[].class), anyInt(), any(AudioAttributes.class));
+    }
+
+    private void ensureRingerIsAudible() {
+        Ringtone mockRingtone = mock(Ringtone.class);
+        when(mockRingtoneFactory.getRingtone(any(Call.class))).thenReturn(mockRingtone);
+        when(mockAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
+        when(mockAudioManager.getStreamVolume(AudioManager.STREAM_RING)).thenReturn(100);
+    }
+
+    private void enableVibrationWhenRinging() {
+        when(mockVibrator.hasVibrator()).thenReturn(true);
+        when(mockSystemSettingsUtil.canVibrateWhenRinging(any(Context.class))).thenReturn(true);
+    }
+
+    private void enableVibrationOnlyWhenNotRinging() {
+        when(mockVibrator.hasVibrator()).thenReturn(true);
+        when(mockSystemSettingsUtil.canVibrateWhenRinging(any(Context.class))).thenReturn(false);
+    }
+}
diff --git a/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java b/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
index 2ee5b5b..305475d 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomServiceImplTest.java
@@ -466,22 +466,10 @@
         if (shouldSucceed) {
             assertFalse(didExceptionOccur);
             verify(mFakePhoneAccountRegistrar).registerPhoneAccount(testPhoneAccount);
-            verify(mContext).sendBroadcastAsUser(intentCaptor.capture(), eq(UserHandle.ALL),
-                    anyString());
-
-            Intent capturedIntent = intentCaptor.getValue();
-            assertEquals(TelecomManager.ACTION_PHONE_ACCOUNT_REGISTERED,
-                    capturedIntent.getAction());
-            Bundle intentExtras = capturedIntent.getExtras();
-            assertEquals(1, intentExtras.size());
-            assertEquals(testPhoneAccount.getAccountHandle(),
-                    intentExtras.get(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE));
         } else {
             assertTrue(didExceptionOccur);
             verify(mFakePhoneAccountRegistrar, never())
                     .registerPhoneAccount(any(PhoneAccount.class));
-            verify(mContext, never())
-                    .sendBroadcastAsUser(any(Intent.class), any(UserHandle.class), anyString());
         }
     }
 
@@ -497,14 +485,6 @@
 
         mTSIBinder.unregisterPhoneAccount(phHandle);
         verify(mFakePhoneAccountRegistrar).unregisterPhoneAccount(phHandle);
-        verify(mContext).sendBroadcastAsUser(intentCaptor.capture(), eq(UserHandle.ALL),
-                anyString());
-        Intent capturedIntent = intentCaptor.getValue();
-        assertEquals(TelecomManager.ACTION_PHONE_ACCOUNT_UNREGISTERED,
-                capturedIntent.getAction());
-        Bundle intentExtras = capturedIntent.getExtras();
-        assertEquals(1, intentExtras.size());
-        assertEquals(phHandle, intentExtras.get(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE));
     }
 
     @SmallTest
diff --git a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
index b90ca97..33315a1 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
@@ -25,6 +25,7 @@
 import static org.mockito.Matchers.eq;
 import static org.mockito.Matchers.isNull;
 import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.reset;
@@ -73,7 +74,6 @@
 import com.android.server.telecom.HeadsetMediaButtonFactory;
 import com.android.server.telecom.InCallWakeLockController;
 import com.android.server.telecom.InCallWakeLockControllerFactory;
-import com.android.server.telecom.InterruptionFilterProxy;
 import com.android.server.telecom.MissedCallNotifier;
 import com.android.server.telecom.PhoneAccountRegistrar;
 import com.android.server.telecom.PhoneNumberUtilsAdapter;
@@ -172,29 +172,11 @@
     }
     PhoneNumberUtilsAdapter mPhoneNumberUtilsAdapter = new EmergencyNumberUtilsAdapter();
 
-    public static class MockInterruptionFilterProxy implements InterruptionFilterProxy {
-        private int mInterruptionFilter = NotificationManager.INTERRUPTION_FILTER_ALL;
-        @Override
-        public void setInterruptionFilter(int interruptionFilter) {
-            mInterruptionFilter = interruptionFilter;
-        }
-
-        @Override
-        public int getCurrentInterruptionFilter() {
-            return mInterruptionFilter;
-        }
-
-        @Override
-        public String getInterruptionModeInitiator() {
-            return "com.android.server.telecom";
-        }
-    }
     @Mock HeadsetMediaButton mHeadsetMediaButton;
     @Mock ProximitySensorManager mProximitySensorManager;
     @Mock InCallWakeLockController mInCallWakeLockController;
     @Mock BluetoothPhoneServiceImpl mBluetoothPhoneServiceImpl;
     @Mock AsyncRingtonePlayer mAsyncRingtonePlayer;
-    @Mock InterruptionFilterProxy mInterruptionFilterProxy;
     @Mock IncomingCallNotifier mIncomingCallNotifier;
 
     final ComponentName mInCallServiceComponentNameX =
@@ -322,6 +304,7 @@
         super.setUp();
         mSpyContext = mComponentContextFixture.getTestDouble().getApplicationContext();
         doReturn(mSpyContext).when(mSpyContext).getApplicationContext();
+        doNothing().when(mSpyContext).sendBroadcastAsUser(any(), any(), any());
 
         mNumOutgoingCallsMade = 0;
 
@@ -424,7 +407,6 @@
                 mTimeoutsAdapter,
                 mAsyncRingtonePlayer,
                 mPhoneNumberUtilsAdapter,
-                mInterruptionFilterProxy,
                 mIncomingCallNotifier);
 
         mComponentContextFixture.setTelecomManager(new TelecomManager(