Merge "Fix issue that the disconnect tone doesn't sound from BTHS" am: 0a17b57d1c am: fef8b02b63
am: 99ba29fd35

Change-Id: I6376c69016d82af6dfd558b73192ea0270bb9b8f
diff --git a/Android.mk b/Android.mk
index 79ef194..234b111 100644
--- a/Android.mk
+++ b/Android.mk
@@ -7,6 +7,7 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-proto-files-under, proto)
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_USE_AAPT2 := true
 
 LOCAL_PROTOC_OPTIMIZE_TYPE := nano
 LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/proto/
diff --git a/proguard.flags b/proguard.flags
index 4e0c310..d7f443e 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -6,3 +6,21 @@
 -keep class android.telecom.Log {
   *;
 }
+
+# Keep classes, annotations and members used by Lifecycle. Remove this once aapt2 is enabled
+-keepattributes *Annotation*
+
+-keepclassmembers enum android.arch.lifecycle.Lifecycle$Event {
+    <fields>;
+}
+
+-keep class * implements android.arch.lifecycle.LifecycleObserver {
+}
+
+-keep class * implements android.arch.lifecycle.GeneratedAdapter {
+    <init>(...);
+}
+
+-keepclassmembers class ** {
+    @android.arch.lifecycle.OnLifecycleEvent *;
+}
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 286b73e..ab49bfb 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -57,7 +57,7 @@
     <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>
+    <string name="non_primary_user" msgid="5180129233352533459">"يمكن لمالك الجهاز فقط الاطّلاع على الأرقام المحظورة وإدارتها."</string>
     <string name="delete_icon_description" msgid="8903995728252556724">"إلغاء الحظر"</string>
     <string name="blocked_numbers_butter_bar_title" msgid="438170866438793182">"تم إيقاف الحظر مؤقتًا"</string>
     <string name="blocked_numbers_butter_bar_body" msgid="2223244484319442431">"بعد الاتصال الهاتفي أو إرسال رسالة نصية إلى رقم طوارئ، يتم إيقاف تشغيل الحظر لضمان تمكن خدمات الطوارئ من الاتصال بك."</string>
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index 63bccaa..18cf839 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -39,7 +39,7 @@
     <string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Poruka poslana na <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
     <string name="enable_account_preference_title" msgid="2021848090086481720">"Računi za pozivanje"</string>
     <string name="outgoing_call_not_allowed_user_restriction" msgid="6872406278300131364">"Dozvoljeni su samo hitni pozivi."</string>
-    <string name="outgoing_call_not_allowed_no_permission" msgid="1996571596464271228">"Ova aplikacija ne može upućivati odlazne pozive bez dozvole za Telefon."</string>
+    <string name="outgoing_call_not_allowed_no_permission" msgid="1996571596464271228">"Ova aplikacija ne može upućivati odlazne pozive bez odobrenja za Telefon."</string>
     <string name="outgoing_call_error_no_phone_number_supplied" msgid="1940125199802007505">"Da uputite poziv, upišite važeći broj."</string>
     <string name="duplicate_video_call_not_allowed" msgid="3749211605014548386">"Trenutno nije moguće dodati poziv."</string>
     <string name="no_vm_number" msgid="4164780423805688336">"Nedostaje broj govorne pošte"</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index ca762e0..2e0ed39 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -52,13 +52,13 @@
     <string name="blocked_numbers" msgid="2751843139572970579">"Blokerede telefonnumre"</string>
     <string name="blocked_numbers_msg" msgid="1045015186124965643">"Du modtager ikke opkald og sms-beskeder fra blokerede numre."</string>
     <string name="block_number" msgid="1101252256321306179">"Tilføj et nummer"</string>
-    <string name="unblock_dialog_body" msgid="1614238499771862793">"Vil du ophæve blokeringen af <xliff:g id="NUMBER_TO_BLOCK">%1$s</xliff:g>?"</string>
-    <string name="unblock_button" msgid="3078048901972674170">"Ophæv blokeringen"</string>
+    <string name="unblock_dialog_body" msgid="1614238499771862793">"Vil du fjerne blokeringen af <xliff:g id="NUMBER_TO_BLOCK">%1$s</xliff:g>?"</string>
+    <string name="unblock_button" msgid="3078048901972674170">"Fjern blokeringen"</string>
     <string name="add_blocked_dialog_body" msgid="9030243212265516828">"Bloker opkald og sms-beskeder fra"</string>
     <string name="add_blocked_number_hint" msgid="6847675097085433553">"Telefonnummer"</string>
     <string name="block_button" msgid="8822290682524373357">"Bloker"</string>
     <string name="non_primary_user" msgid="5180129233352533459">"Det er kun ejeren af en enhed, der kan se og administrere blokerede numre."</string>
-    <string name="delete_icon_description" msgid="8903995728252556724">"Ophæv blokering"</string>
+    <string name="delete_icon_description" msgid="8903995728252556724">"Fjern blokering"</string>
     <string name="blocked_numbers_butter_bar_title" msgid="438170866438793182">"Blokering er midlertidigt slået fra"</string>
     <string name="blocked_numbers_butter_bar_body" msgid="2223244484319442431">"Når du har ringet eller sendt en sms-besked til alarmcentralen, bliver blokering slået fra for at sikre, at alarmcentralen kan komme i kontakt med dig."</string>
     <string name="blocked_numbers_butter_bar_button" msgid="2197943354922010696">"Genaktiver nu"</string>
diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml
new file mode 100644
index 0000000..7d344f1
--- /dev/null
+++ b/res/values-en-rCA/strings.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="telecommAppLabel" product="default" msgid="382363169988504520">"Call Management"</string>
+    <string name="userCallActivityLabel" product="default" msgid="5415173590855187131">"Phone"</string>
+    <string name="unknown" msgid="6878797917991465859">"Unknown"</string>
+    <string name="notification_missedCallTitle" msgid="7554385905572364535">"Missed call"</string>
+    <string name="notification_missedWorkCallTitle" msgid="6242489980390803090">"Missed work call"</string>
+    <string name="notification_missedCallsTitle" msgid="1361677948941502522">"Missed calls"</string>
+    <string name="notification_missedCallsMsg" msgid="4575787816055205600">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> missed calls"</string>
+    <string name="notification_missedCallTicker" msgid="504686252427747209">"Missed call from <xliff:g id="MISSED_CALL_FROM">%s</xliff:g>"</string>
+    <string name="notification_missedCall_call_back" msgid="2684890353590890187">"Call back"</string>
+    <string name="notification_missedCall_message" msgid="3049928912736917988">"Message"</string>
+    <string name="accessibility_call_muted" msgid="2776111226185342220">"Call muted."</string>
+    <string name="accessibility_speakerphone_enabled" msgid="1988512040421036359">"Speakerphone enabled."</string>
+    <string name="respond_via_sms_canned_response_1" msgid="2461606462788380215">"Can\'t talk now. What\'s up?"</string>
+    <string name="respond_via_sms_canned_response_2" msgid="4074450431532859214">"I\'ll call you right back."</string>
+    <string name="respond_via_sms_canned_response_3" msgid="3496079065723960450">"I\'ll call you later."</string>
+    <string name="respond_via_sms_canned_response_4" msgid="1698989243040062190">"Can\'t talk now. Call me later?"</string>
+    <string name="respond_via_sms_setting_title" msgid="3754000371039709383">"Quick responses"</string>
+    <string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"Edit quick responses"</string>
+    <string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
+    <string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Quick response"</string>
+    <string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Message sent to <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
+    <string name="enable_account_preference_title" msgid="2021848090086481720">"Calling accounts"</string>
+    <string name="outgoing_call_not_allowed_user_restriction" msgid="6872406278300131364">"Only emergency calls are allowed."</string>
+    <string name="outgoing_call_not_allowed_no_permission" msgid="1996571596464271228">"This application cannot make outgoing calls without Phone permission."</string>
+    <string name="outgoing_call_error_no_phone_number_supplied" msgid="1940125199802007505">"To place a call, enter a valid number."</string>
+    <string name="duplicate_video_call_not_allowed" msgid="3749211605014548386">"Call cannot be added at this time."</string>
+    <string name="no_vm_number" msgid="4164780423805688336">"Missing voicemail number"</string>
+    <string name="no_vm_number_msg" msgid="1300729501030053828">"No voicemail number is stored on the SIM card."</string>
+    <string name="add_vm_number_str" msgid="4676479471644687453">"Add number"</string>
+    <string name="change_default_dialer_dialog_title" msgid="9101655962941740507">"Make <xliff:g id="NEW_APP">%s</xliff:g> your default Phone app?"</string>
+    <string name="change_default_dialer_dialog_affirmative" msgid="8606546663509166276">"Set Default"</string>
+    <string name="change_default_dialer_dialog_negative" msgid="9078144617060173845">"Cancel"</string>
+    <string name="change_default_dialer_warning_message" msgid="1417671460801684999">"<xliff:g id="NEW_APP">%s</xliff:g> will be able to place and control all aspects of calls. Only apps that you trust should be set as the default Phone app."</string>
+    <string name="blocked_numbers" msgid="2751843139572970579">"Blocked numbers"</string>
+    <string name="blocked_numbers_msg" msgid="1045015186124965643">"You won\'t receive calls or texts from blocked numbers."</string>
+    <string name="block_number" msgid="1101252256321306179">"Add a number"</string>
+    <string name="unblock_dialog_body" msgid="1614238499771862793">"Unblock <xliff:g id="NUMBER_TO_BLOCK">%1$s</xliff:g>?"</string>
+    <string name="unblock_button" msgid="3078048901972674170">"Unblock"</string>
+    <string name="add_blocked_dialog_body" msgid="9030243212265516828">"Block calls and texts from"</string>
+    <string name="add_blocked_number_hint" msgid="6847675097085433553">"Phone number"</string>
+    <string name="block_button" msgid="8822290682524373357">"Block"</string>
+    <string name="non_primary_user" msgid="5180129233352533459">"Only the device owner can view and manage blocked numbers."</string>
+    <string name="delete_icon_description" msgid="8903995728252556724">"Unblock"</string>
+    <string name="blocked_numbers_butter_bar_title" msgid="438170866438793182">"Blocking temporarily off"</string>
+    <string name="blocked_numbers_butter_bar_body" msgid="2223244484319442431">"When you dial or text an emergency number, blocking is turned off to ensure that emergency services can contact you."</string>
+    <string name="blocked_numbers_butter_bar_button" msgid="2197943354922010696">"Re-enable now"</string>
+    <string name="blocked_numbers_number_blocked_message" msgid="7678509606805029540">"<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g> blocked"</string>
+    <string name="blocked_numbers_number_unblocked_message" msgid="977894647366750418">"<xliff:g id="UNBLOCKED_NUMBER">%1$s</xliff:g> unblocked"</string>
+    <string name="blocked_numbers_block_emergency_number_message" msgid="917851876780698387">"Unable to block emergency number."</string>
+    <string name="blocked_numbers_number_already_blocked_message" msgid="4392247814500811798">"<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g> is already blocked."</string>
+    <string name="toast_personal_call_msg" msgid="5115361633476779723">"Using the personal dialler to make the call"</string>
+    <string name="notification_incoming_call" msgid="7713197997773986670">"<xliff:g id="CALL_VIA">%1$s</xliff:g> call from <xliff:g id="CALL_FROM">%2$s</xliff:g>"</string>
+    <string name="notification_incoming_video_call" msgid="6638486071698373893">"<xliff:g id="CALL_VIA">%1$s</xliff:g> video call from <xliff:g id="CALL_FROM">%2$s</xliff:g>"</string>
+    <string name="answering_ends_other_call" msgid="8282145910153766401">"Answering will end your <xliff:g id="CALL_VIA">%1$s</xliff:g> call"</string>
+    <string name="answering_ends_other_calls" msgid="1198589551399049197">"Answering will end your <xliff:g id="CALL_VIA">%1$s</xliff:g> calls"</string>
+    <string name="answering_ends_other_video_call" msgid="8510410917384186360">"Answering will end your <xliff:g id="CALL_VIA">%1$s</xliff:g> video call"</string>
+    <string name="answering_ends_other_managed_call" msgid="5186137550267947785">"Answering will end your ongoing call"</string>
+    <string name="answering_ends_other_managed_calls" msgid="6429838309560397988">"Answering will end your ongoing calls"</string>
+    <string name="answering_ends_other_managed_video_call" msgid="1585423762458248435">"Answering will end your ongoing video call"</string>
+    <string name="answer_incoming_call" msgid="4140530013111794587">"Answer"</string>
+    <string name="decline_incoming_call" msgid="806026168661598368">"Decline"</string>
+    <string name="cant_call_due_to_ongoing_call" msgid="4952615196237854748">"Call cannot be placed due to your <xliff:g id="OTHER_CALL">%1$s</xliff:g> call."</string>
+    <string name="cant_call_due_to_ongoing_calls" msgid="1380804892363503856">"Call cannot be placed due to your <xliff:g id="OTHER_CALL">%1$s</xliff:g> calls."</string>
+    <string name="cant_call_due_to_ongoing_unknown_call" msgid="149091978697302211">"Call cannot be placed due to a call in another app."</string>
+    <string name="notification_channel_incoming_call" msgid="3513761697082968084">"Incoming calls"</string>
+    <string name="notification_channel_missed_call" msgid="8727062678632713146">"Missed calls"</string>
+    <string name="alert_outgoing_call" msgid="982908156825958001">"Placing this call will end your <xliff:g id="OTHER_APP">%1$s</xliff:g> call."</string>
+</resources>
diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..26daa02
--- /dev/null
+++ b/res/values-en-rXC/strings.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2013 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.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="telecommAppLabel" product="default" msgid="382363169988504520">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‎‏‎‏‎‎‏‏‏‎‎‏‏‎‏‏‎‏‎‏‎‎‎‏‏‎‏‏‏‏‏‎‏‎‎‏‎‏‏‎‏‏‎‏‏‎‏‎‏‏‏‏‎‎‏‎‎‎‎Call Management‎‏‎‎‏‎"</string>
+    <string name="userCallActivityLabel" product="default" msgid="5415173590855187131">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‏‎‎‏‏‎‏‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‏‏‎Phone‎‏‎‎‏‎"</string>
+    <string name="unknown" msgid="6878797917991465859">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‎‏‏‎‎‏‏‎‎‏‏‎‎‏‎‎‎‎‏‎‏‏‎‎‏‏‏‏‏‎‎‏‎‎‏‏‏‏‏‏‎‎‏‏‏‎‎‎‎‎‏‏‎Unknown‎‏‎‎‏‎"</string>
+    <string name="notification_missedCallTitle" msgid="7554385905572364535">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‎‏‏‎‏‎‎‏‎‎‎‏‏‏‏‏‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎‏‏‎‏‏‏‏‎‎‎‎‎‎‏‏‏‏‎‏‏‏‎Missed call‎‏‎‎‏‎"</string>
+    <string name="notification_missedWorkCallTitle" msgid="6242489980390803090">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‎‎‎‎‏‏‏‎‎‎‏‏‏‏‎‎‏‎‎‎‎‎‎‏‎‎‎‏‏‎‎‏‎‎‎‎‏‎‎‎‎‎‏‏‎‏‎‎‏‎‎‏‎‎Missed work call‎‏‎‎‏‎"</string>
+    <string name="notification_missedCallsTitle" msgid="1361677948941502522">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‏‏‎‎‏‎‏‏‏‎‎‏‎‏‏‎‏‎‎‏‏‎‏‏‏‎‎‎‎‏‎‏‎‎‏‏‎‏‎‎‏‎‎‏‎‎‎‎‎‎‏‎‎‎‎‎‏‏‏‎‏‎‎Missed calls‎‏‎‎‏‎"</string>
+    <string name="notification_missedCallsMsg" msgid="4575787816055205600">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‎‎‎‏‏‎‎‏‏‎‏‏‏‏‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‎‎‎‎‎‎‏‎‎‏‏‎<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g>‎‏‎‎‏‏‏‎ missed calls‎‏‎‎‏‎"</string>
+    <string name="notification_missedCallTicker" msgid="504686252427747209">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‎‎‎‎‎‎‎‏‎‎‎‎‎‎‎‏‎‏‏‏‏‎‎‎‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‏‎‎‏‏‏‏‏‏‎‎‎‏‎‎‏‎Missed call from ‎‏‎‎‏‏‎<xliff:g id="MISSED_CALL_FROM">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="notification_missedCall_call_back" msgid="2684890353590890187">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‎‎‏‎‏‎‏‎‎‎‎‏‎‏‎‏‎‎‏‎‏‏‎‎‎‏‏‎‏‎‎‏‎‏‎‏‎‏‎‏‎‏‎‎‎‎‏‏‎‏‏‏‎‏‏‎‎‏‎‏‏‎Call back‎‏‎‎‏‎"</string>
+    <string name="notification_missedCall_message" msgid="3049928912736917988">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‎‏‎‏‎‎‏‎‏‎‎‏‏‏‎‎‎‎‏‏‎‎‎‏‎‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‎‎‎‎‎‏‎‎‏‏‎‎‏‏‏‏‎‎‏‎‎‎Message‎‏‎‎‏‎"</string>
+    <string name="accessibility_call_muted" msgid="2776111226185342220">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‎‎‏‏‎‏‎‎‎‎‏‏‎‏‎‏‏‏‎‏‎‎‏‏‏‎‎‏‏‏‎‏‎‎‏‎‏‏‏‎‎‎‎‎‎‎‏‎‏‏‏‎‏‎‎‎‎‏‏‎‎‎Call muted.‎‏‎‎‏‎"</string>
+    <string name="accessibility_speakerphone_enabled" msgid="1988512040421036359">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‏‏‏‎‏‏‏‎‎‏‏‎‎‎‏‎‎‏‏‏‎‏‎‎‏‎‏‎‏‎‎‏‎‎‏‎‎‎‏‏‏‎‎‎‏‎‎‎‎‏‎‎‎‏‎‏‎‎‎‏‏‏‎Speakerphone enabled.‎‏‎‎‏‎"</string>
+    <string name="respond_via_sms_canned_response_1" msgid="2461606462788380215">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‎‎‎‏‎‎‎‏‎‏‎‎‏‎‏‏‎‎‎‏‎‎‎‎‎‏‎‎‏‎‎‏‎‎‏‏‏‎‏‎‎‏‏‏‎‏‎‏‎‎‏‏‎‎‎‏‏‎‏‏‏‎Can\'t talk now. What\'s up?‎‏‎‎‏‎"</string>
+    <string name="respond_via_sms_canned_response_2" msgid="4074450431532859214">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‎‎‎‏‎‏‏‎‏‎‏‏‎‏‏‎‎‎‏‎‏‎‎‏‎‎‎‎‎‏‎‎‏‏‏‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎I\'ll call you right back.‎‏‎‎‏‎"</string>
+    <string name="respond_via_sms_canned_response_3" msgid="3496079065723960450">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‎‎‎‎‏‎‎‏‎‎‏‎‎‎‏‎‏‏‎‎‎‏‏‎‎‏‎‎‎‏‏‎‎‏‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‏‎‎I\'ll call you later.‎‏‎‎‏‎"</string>
+    <string name="respond_via_sms_canned_response_4" msgid="1698989243040062190">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‏‏‎‏‏‏‏‎‎‏‎‏‎‎‎‎‎‎‎‏‎‏‏‎‏‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‏‏‏‎‎‏‏‎‏‏‎‏‎‏‏‏‎‏‏‏‎‎Can\'t talk now. Call me later?‎‏‎‎‏‎"</string>
+    <string name="respond_via_sms_setting_title" msgid="3754000371039709383">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‎‎‏‏‎‎‎‏‏‏‎‎‎‏‏‎‏‏‏‎‎‏‎‏‎‏‎‏‎‏‎‏‎‎‎‎‎‎‏‏‎‏‎‏‎‎‎‏‏‎‎‎‏‏‏‎Quick responses‎‏‎‎‏‎"</string>
+    <string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‏‏‏‎‎‎‎‎‎‏‏‏‎‏‏‏‏‏‎‎‏‏‏‎‏‎‏‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‎‎‎‎‎‏‎‎‏‎‎Edit quick responses‎‏‎‎‏‎"</string>
+    <string name="respond_via_sms_setting_summary" msgid="9150281183930613065"></string>
+    <string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‎‏‏‏‏‎‎‏‎‎‎‎‏‏‎‎‏‏‏‎‏‏‎‎‏‏‏‎‎‎‎‎‎‎‎‏‏‏‏‎‎‎‏‏‎‎‎‏‏‎‎‎‏‏‏‎‎‏‎‎Quick response‎‏‎‎‏‎"</string>
+    <string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‏‎‎‏‏‎‎‎‏‏‎‎‏‏‎‎‏‏‎‏‎‎‏‎‏‎‏‎‏‏‏‎‏‏‎‎‏‏‏‏‏‏‎‎‎‎‏‎‎‏‏‎‏‎Message sent to ‎‏‎‎‏‏‎<xliff:g id="PHONE_NUMBER">%s</xliff:g>‎‏‎‎‏‏‏‎.‎‏‎‎‏‎"</string>
+    <string name="enable_account_preference_title" msgid="2021848090086481720">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‎‎‎‎‏‏‏‏‎‎‎‎‏‏‎‎‎‎‏‎‎‎‎‎‎‎‏‎‏‏‏‏‎‏‏‎‏‎‎‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‎Calling accounts‎‏‎‎‏‎"</string>
+    <string name="outgoing_call_not_allowed_user_restriction" msgid="6872406278300131364">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‎‏‏‏‏‏‏‎‏‏‎‎‎‏‎‎‎‏‏‎‎‏‎‎‏‏‏‎‏‎‎‎‏‏‏‏‏‎‎‏‏‎‎‎‎‎‎‎‏‎‎‏‎‎‎Only emergency calls are allowed.‎‏‎‎‏‎"</string>
+    <string name="outgoing_call_not_allowed_no_permission" msgid="1996571596464271228">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‏‏‏‎‏‏‏‎‏‏‎‏‎‏‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‏‏‎‎‏‏‏‏‏‏‎‎‎‏‏‎‎‏‎‏‏‏‏‎‏‏‏‏‏‎‎‎This application cannot make outgoing calls without the Phone permission.‎‏‎‎‏‎"</string>
+    <string name="outgoing_call_error_no_phone_number_supplied" msgid="1940125199802007505">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‏‏‏‎‏‎‏‏‏‎‏‏‎‎‏‎‏‏‎‏‎‏‏‎‎‏‎‏‏‏‎‎‎‎‏‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎To place a call, enter a valid number.‎‏‎‎‏‎"</string>
+    <string name="duplicate_video_call_not_allowed" msgid="3749211605014548386">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‎‎‎‎‏‏‏‏‏‏‎‎‎‎‎‎‎‎‏‎‏‏‏‎‎‏‏‎‎‎‎‏‎‏‎‏‎‏‎‎‎‎‎‏‏‏‏‏‎‏‎‎‎‏‎‎Call cannot be added at this time.‎‏‎‎‏‎"</string>
+    <string name="no_vm_number" msgid="4164780423805688336">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‎‏‏‎‎‎‏‎‎‎‏‎‏‏‎‏‏‏‎‏‎‏‏‎‎‎‎‎‎‎‏‏‏‎‎‎‎‎‏‎‏‏‎‏‎‎‎‎‏‎‎‎‎‎Missing voicemail number‎‏‎‎‏‎"</string>
+    <string name="no_vm_number_msg" msgid="1300729501030053828">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‏‏‎‎‏‎‎‎‎‎‏‏‎‏‎‎‎‏‏‏‏‎‏‎‎‏‎‏‏‎‏‏‏‏‎‎‎‏‏‏‎‎‎‏‎‎‎‏‏‏‎‏‏‏‏‏‎‎‎‏‎‎‎No voicemail number is stored on the SIM card.‎‏‎‎‏‎"</string>
+    <string name="add_vm_number_str" msgid="4676479471644687453">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‎‎‏‏‎‎‎‏‏‎‎‎‏‎‏‎‎‏‏‎‏‎‏‏‎‏‎‏‎‏‏‎‎‏‎‎‏‏‎‏‏‏‏‎‎‎‏‎‏‏‏‎‏‎Add number‎‏‎‎‏‎"</string>
+    <string name="change_default_dialer_dialog_title" msgid="9101655962941740507">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‏‏‎‎‏‎‎‏‏‏‏‏‎‎‎‎‎‎‎‏‎‏‎‏‎‏‏‏‏‎‏‎‏‎‏‎‏‎‏‎‏‏‏‎‏‏‎‏‏‎Make ‎‏‎‎‏‏‎<xliff:g id="NEW_APP">%s</xliff:g>‎‏‎‎‏‏‏‎ your default Phone app?‎‏‎‎‏‎"</string>
+    <string name="change_default_dialer_dialog_affirmative" msgid="8606546663509166276">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‎‎‎‏‎‎‏‏‎‎‎‏‎‎‏‎‏‏‏‎‏‎‎‏‏‎‏‎‏‎‎‏‎‎‏‏‎‎‎‏‎‎‎‏‏‎‎‎‏‎‎‎Set Default‎‏‎‎‏‎"</string>
+    <string name="change_default_dialer_dialog_negative" msgid="9078144617060173845">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‎‎‎‏‏‎‏‏‏‎‎‏‎‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‎‎‏‎‎‎‎‎‎‏‎‏‎‏‎Cancel‎‏‎‎‏‎"</string>
+    <string name="change_default_dialer_warning_message" msgid="1417671460801684999">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‏‏‎‎‏‏‏‎‏‎‏‏‎‎‏‎‎‏‎‏‎‎‏‎‏‎‏‏‏‎‏‎‏‏‎‏‎‏‎‏‎‎‏‎‏‏‎‎‏‎‎‏‏‎‎‎‎‎‎‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="NEW_APP">%s</xliff:g>‎‏‎‎‏‏‏‎ will be able to place and control all aspects of calls. Only apps you trust should be set as the default Phone app.‎‏‎‎‏‎"</string>
+    <string name="blocked_numbers" msgid="2751843139572970579">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‏‎‎‎‎‏‎‎‎‎‎‏‎‏‏‎‎‎‎‎‏‎‏‏‎‏‎‏‏‏‏‎‏‎‏‏‏‏‎‏‏‎‏‎‎‎‏‎‏‎‎‏‏‎Blocked numbers‎‏‎‎‏‎"</string>
+    <string name="blocked_numbers_msg" msgid="1045015186124965643">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‎‏‏‏‎‏‎‎‎‎‎‎‎‏‎‏‎‎‎‏‏‏‏‎‎‎‏‏‎‎‏‏‎‏‎‎‏‏‏‎‏‏‏‏‎‎‎‎‎‎‏‏‏‎‎‎‎‏‎‏‏‎You won\'t receive calls or texts from blocked numbers.‎‏‎‎‏‎"</string>
+    <string name="block_number" msgid="1101252256321306179">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‎‏‏‏‏‎‏‎‎‏‎‎‎‎‏‏‎‏‏‏‏‎‎‎‏‎‏‏‏‏‎‏‎‏‎‏‎‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‏‎Add a number‎‏‎‎‏‎"</string>
+    <string name="unblock_dialog_body" msgid="1614238499771862793">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‏‏‎‏‏‎‎‏‏‎‎‏‏‎‏‏‏‎‏‏‎‏‎‏‎‏‏‏‎‎‏‏‏‎‏‎‎‏‏‎‏‎‏‎‎‏‎‏‎‎‏‏‏‏‎‎‎‎‏‎‎‏‎Unblock ‎‏‎‎‏‏‎<xliff:g id="NUMBER_TO_BLOCK">%1$s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
+    <string name="unblock_button" msgid="3078048901972674170">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‎‏‎‏‎‏‎‏‏‎‏‏‏‎‏‏‎‏‏‎‏‎‎‏‎‏‎‏‏‎‎‎‎‏‎‏‏‎‏‎‏‏‏‎‎‏‏‎‎‎‏‏‎‎‏‏‏‏‎‏‎‎Unblock‎‏‎‎‏‎"</string>
+    <string name="add_blocked_dialog_body" msgid="9030243212265516828">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‏‏‏‎‏‏‏‏‎‎‏‎‏‏‎‏‏‎‏‏‏‎‏‏‎‎‏‏‏‎‏‏‏‏‏‏‎‏‏‏‏‎‎‎‏‏‏‎‎‎Block calls and texts from‎‏‎‎‏‎"</string>
+    <string name="add_blocked_number_hint" msgid="6847675097085433553">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‏‏‏‏‎‏‎‏‎‎‎‎‏‏‏‎‎‎‎‏‏‎‎‎‏‏‎‎‎‏‎‎‎‎‏‏‎‏‎‏‏‎‏‏‎‏‎‎‎‏‎Phone number‎‏‎‎‏‎"</string>
+    <string name="block_button" msgid="8822290682524373357">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‏‏‏‎‎‎‏‎‎‏‎‏‎‏‎‎‎‏‎‎‎‎‏‏‏‎‏‎‎‎‏‏‎‏‎‏‎‎‏‎‎‎‏‎‏‏‎‏‏‎‏‎Block‎‏‎‎‏‎"</string>
+    <string name="non_primary_user" msgid="5180129233352533459">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‎‎‎‏‏‏‏‏‏‎‎‎‏‏‏‎‎‎‎‏‎‎‎‎‎‏‎‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‏‎‎‎‎‎‏‎‎‏‎‏‏‏‎‏‎‎‏‏‎Only the device owner can view and manage blocked numbers.‎‏‎‎‏‎"</string>
+    <string name="delete_icon_description" msgid="8903995728252556724">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‎‎‏‎‏‎‏‏‎‎‎‏‏‏‏‎‎‎‎‏‎‎‎‎‎‎‎‎‎‎‏‎‏‏‎‏‏‎‏‎‏‎‏‏‎‏‏‎‏‎‎‎Unblock‎‏‎‎‏‎"</string>
+    <string name="blocked_numbers_butter_bar_title" msgid="438170866438793182">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‎‎‎‎‏‎‏‎‎‏‎‏‏‎‎‏‎‎‎‎‏‎‏‎‎‏‏‎‏‏‏‎‏‎‎‎‎‎‎‏‎‎‏‏‎‎‏‏‏‏‏‎‏‏‏‏‎‎Blocking temporarily off‎‏‎‎‏‎"</string>
+    <string name="blocked_numbers_butter_bar_body" msgid="2223244484319442431">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‎‎‏‏‎‏‎‎‎‏‎‏‎‎‎‏‎‎‏‎‎‎‏‎‏‏‎‏‎‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‏‏‎After you dial or text an emergency number, blocking is turned off to ensure that emergency services can contact you.‎‏‎‎‏‎"</string>
+    <string name="blocked_numbers_butter_bar_button" msgid="2197943354922010696">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‏‎‏‎‎‏‏‏‎‏‎‏‏‎‎‎‎‎‏‎‏‎‏‎‎‎‏‏‏‎‏‎‎‎‏‎‎‎‎‏‎‎‏‎‎‎‎Re-enable now‎‏‎‎‏‎"</string>
+    <string name="blocked_numbers_number_blocked_message" msgid="7678509606805029540">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‏‏‏‏‏‎‎‎‏‎‏‏‏‏‎‎‏‏‏‎‎‎‎‎‏‏‏‎‎‎‎‎‏‎‎‏‏‏‎‎‎‎‏‎‏‎‏‎‎‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g>‎‏‎‎‏‏‏‎ blocked‎‏‎‎‏‎"</string>
+    <string name="blocked_numbers_number_unblocked_message" msgid="977894647366750418">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‎‏‏‎‏‏‎‎‏‎‎‏‎‎‎‏‎‏‏‏‎‎‎‎‎‎‎‎‎‎‎‏‎‏‏‎‎‎‎‎‎‏‏‎‏‎‎‎‏‎‎‎‎‏‏‎‏‎‎‏‎‎‎‏‎‎‏‏‎<xliff:g id="UNBLOCKED_NUMBER">%1$s</xliff:g>‎‏‎‎‏‏‏‎ unblocked‎‏‎‎‏‎"</string>
+    <string name="blocked_numbers_block_emergency_number_message" msgid="917851876780698387">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‎‏‏‎‎‏‎‏‏‏‏‎‎‏‏‎‏‏‏‎‏‎‏‏‎‏‎‏‏‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‎‏‎‏‏‎‎‎‏‎‎‏‏‎Unable to block emergency number.‎‏‎‎‏‎"</string>
+    <string name="blocked_numbers_number_already_blocked_message" msgid="4392247814500811798">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‏‏‏‎‏‎‎‎‏‏‎‎‏‏‎‎‎‎‏‏‏‎‏‏‎‏‏‏‏‎‎‏‏‎‎‏‏‏‎‏‎‎‎‎‏‎‎‎‎‎‏‎‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is already blocked.‎‏‎‎‏‎"</string>
+    <string name="toast_personal_call_msg" msgid="5115361633476779723">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‎‎‏‎‎‏‏‎‏‏‎‏‎‎‏‎‏‎‎‎‎‏‎‏‏‏‎‎‏‏‏‏‎‏‏‎‎‏‎‏‏‎Using the personal dialer to make the call‎‏‎‎‏‎"</string>
+    <string name="notification_incoming_call" msgid="7713197997773986670">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‎‏‎‏‏‎‎‏‎‎‎‏‎‏‏‎‏‏‎‎‏‏‏‎‎‏‏‏‎‎‏‎‎‏‎‏‎‎‏‏‎‏‏‎‏‏‎‏‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="CALL_VIA">%1$s</xliff:g>‎‏‎‎‏‏‏‎ call from ‎‏‎‎‏‏‎<xliff:g id="CALL_FROM">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="notification_incoming_video_call" msgid="6638486071698373893">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‏‎‎‎‎‎‏‎‏‎‎‎‏‏‏‏‏‎‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‏‎‏‎‏‏‎‏‏‏‏‎‏‎‎‎‎‎‏‎‏‎‎‏‎‎‏‏‎<xliff:g id="CALL_VIA">%1$s</xliff:g>‎‏‎‎‏‏‏‎ video call from ‎‏‎‎‏‏‎<xliff:g id="CALL_FROM">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="answering_ends_other_call" msgid="8282145910153766401">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‎‎‎‎‎‎‎‏‎‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‏‎‎‎‏‎‏‎‏‎‏‏‎‏‏‎‎‏‏‎‎‎‎‎‎‎‎‏‎Answering will end your ‎‏‎‎‏‏‎<xliff:g id="CALL_VIA">%1$s</xliff:g>‎‏‎‎‏‏‏‎ call‎‏‎‎‏‎"</string>
+    <string name="answering_ends_other_calls" msgid="1198589551399049197">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‏‏‎‎‎‎‏‎‏‎‎‎‏‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‏‏‏‎‏‎‏‎‏‎‎‎‏‎‏‎‎‏‎‏‏‏‏‏‏‎‏‏‎‏‎Answering will end your ‎‏‎‎‏‏‎<xliff:g id="CALL_VIA">%1$s</xliff:g>‎‏‎‎‏‏‏‎ calls‎‏‎‎‏‎"</string>
+    <string name="answering_ends_other_video_call" msgid="8510410917384186360">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‏‎‏‏‎‎‎‎‏‏‎‏‏‎‏‎‎‎‏‏‏‎‏‎‎‏‏‏‎‏‎‎‏‎‏‎‎‏‏‎‏‎‎‏‏‏‏‏‏‎‎‎‎Answering will end your ‎‏‎‎‏‏‎<xliff:g id="CALL_VIA">%1$s</xliff:g>‎‏‎‎‏‏‏‎ video call‎‏‎‎‏‎"</string>
+    <string name="answering_ends_other_managed_call" msgid="5186137550267947785">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‏‏‎‎‏‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‎‏‎‎‎‏‏‎‏‏‎‎‎‎‏‎‎‏‎Answering will end your ongoing call‎‏‎‎‏‎"</string>
+    <string name="answering_ends_other_managed_calls" msgid="6429838309560397988">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‏‏‏‎‏‏‎‏‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‏‎‏‎‎‏‎‎‎‏‎‏‏‏‎‏‏‎‎‎‎‏‎‏‎‎‏‎‎‎Answering will end your ongoing calls‎‏‎‎‏‎"</string>
+    <string name="answering_ends_other_managed_video_call" msgid="1585423762458248435">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‏‏‎‏‏‎‎‎‎‎‎‎‎‎‏‎‎‎‏‏‏‎‏‎‎‎‎‎‏‏‎‎‎‏‎‎‏‏‏‏‎‎‏‎‎‏‏‎‎‎‎‏‎‎‏‏‏‏‎‎‏‏‎Answering will end your ongoing video call‎‏‎‎‏‎"</string>
+    <string name="answer_incoming_call" msgid="4140530013111794587">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‎‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‏‏‎‎‎‎‎‎‎‏‎‏‎‏‎‏‏‏‏‏‎‎‏‏‏‎‏‏‏‎‎‏‏‎‏‏‎Answer‎‏‎‎‏‎"</string>
+    <string name="decline_incoming_call" msgid="806026168661598368">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‎‏‎‏‏‎‎‏‎‏‏‏‏‏‎‎‏‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‎‏‏‎‏‎‏‏‏‏‏‎‎‏‏‎‎‎‎‎‏‎‏‎‎‎‎‎‎Decline‎‏‎‎‏‎"</string>
+    <string name="cant_call_due_to_ongoing_call" msgid="4952615196237854748">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‎‎‎‏‎‎‏‎‏‏‏‎‏‏‎‎‏‏‏‎‎‏‎‏‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‏‏‏‎‏‎‏‎‏‏‏‏‎‎‎‎‎‎‏‏‏‎‎‎Call cannot be placed due to your ‎‏‎‎‏‏‎<xliff:g id="OTHER_CALL">%1$s</xliff:g>‎‏‎‎‏‏‏‎ call.‎‏‎‎‏‎"</string>
+    <string name="cant_call_due_to_ongoing_calls" msgid="1380804892363503856">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‏‏‎‎‏‏‎‎‏‎‏‎‎‏‏‎‎‏‏‎‏‎‏‎‏‏‏‎‏‏‏‏‎‏‏‎‎‏‎‏‏‏‎‎‏‎‏‎‏‏‏‎‎‎‏‏‏‏‎‎‎‎‎Call cannot be placed due to your ‎‏‎‎‏‏‎<xliff:g id="OTHER_CALL">%1$s</xliff:g>‎‏‎‎‏‏‏‎ calls.‎‏‎‎‏‎"</string>
+    <string name="cant_call_due_to_ongoing_unknown_call" msgid="149091978697302211">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‎‎‎‏‏‎‏‎‏‏‏‎‎‏‎‏‏‏‎‏‎‏‎‏‏‏‎‏‎‎‎‏‏‏‎‎‏‏‏‎‎‎‎‎‏‏‎‎‎‎‏‏‎Call cannot be placed due to a call in another app.‎‏‎‎‏‎"</string>
+    <string name="notification_channel_incoming_call" msgid="3513761697082968084">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‏‎‎‎‎‏‏‎‏‏‎‎‎‏‏‏‎‏‎‎‏‎‏‏‎‎‏‎‏‎‎‎‎‎‎‎‎‎‏‎‎‎‎‏‎‎‎‎‎‎‏‎‏‎‎‎Incoming calls‎‏‎‎‏‎"</string>
+    <string name="notification_channel_missed_call" msgid="8727062678632713146">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‎‎‏‏‎‎‎‎‎‏‎‏‎‎‎‏‎‎‏‎‏‎‏‏‎‎‎‏‏‏‏‎‎‎‏‏‎‎‏‎‏‏‏‎‏‏‏‎‏‎‎Missed calls‎‏‎‎‏‎"</string>
+    <string name="alert_outgoing_call" msgid="982908156825958001">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‎‏‏‎‏‏‎‏‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‏‎‏‏‎‎‏‏‏‎‎‏‏‏‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‏‎‎‎‏‎Placing this call will end your ‎‏‎‎‏‏‎<xliff:g id="OTHER_APP">%1$s</xliff:g>‎‏‎‎‏‏‏‎ call.‎‏‎‎‏‎"</string>
+</resources>
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
index 190b5aa..7217797 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/strings.xml
@@ -38,7 +38,7 @@
     <string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"Resposta rápida"</string>
     <string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"Mensaxe enviada ao <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
     <string name="enable_account_preference_title" msgid="2021848090086481720">"Contas de chamadas"</string>
-    <string name="outgoing_call_not_allowed_user_restriction" msgid="6872406278300131364">"Só se permiten chamadas de emerxencia."</string>
+    <string name="outgoing_call_not_allowed_user_restriction" msgid="6872406278300131364">"Só se permiten chamadas de urxencia."</string>
     <string name="outgoing_call_not_allowed_no_permission" msgid="1996571596464271228">"Esta aplicación non pode facer chamadas saíntes sen permiso do teléfono."</string>
     <string name="outgoing_call_error_no_phone_number_supplied" msgid="1940125199802007505">"Para realizar unha chamada, introduce un número válido."</string>
     <string name="duplicate_video_call_not_allowed" msgid="3749211605014548386">"Neste momento non se pode engadir a chamada."</string>
@@ -60,11 +60,11 @@
     <string name="non_primary_user" msgid="5180129233352533459">"Só o propietario do dispositivo pode ver e xestionar os números bloqueados."</string>
     <string name="delete_icon_description" msgid="8903995728252556724">"Desbloquear"</string>
     <string name="blocked_numbers_butter_bar_title" msgid="438170866438793182">"O bloqueo desactivouse temporalmente"</string>
-    <string name="blocked_numbers_butter_bar_body" msgid="2223244484319442431">"Despois de facer unha chamada ou enviar unha mensaxe a un número de emerxencia, desactívase o bloqueo para garantir que os servizos de emerxencia poidan poñerse en contacto contigo."</string>
+    <string name="blocked_numbers_butter_bar_body" msgid="2223244484319442431">"Despois de facer unha chamada ou enviar unha mensaxe a un número de urxencia, desactívase o bloqueo para garantir que os servizos de urxencia poidan poñerse en contacto contigo."</string>
     <string name="blocked_numbers_butter_bar_button" msgid="2197943354922010696">"Volver activar agora"</string>
     <string name="blocked_numbers_number_blocked_message" msgid="7678509606805029540">"Bloqueouse o <xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g>"</string>
     <string name="blocked_numbers_number_unblocked_message" msgid="977894647366750418">"Desbloqueouse o <xliff:g id="UNBLOCKED_NUMBER">%1$s</xliff:g>"</string>
-    <string name="blocked_numbers_block_emergency_number_message" msgid="917851876780698387">"Non se pode bloquear o número de emerxencia."</string>
+    <string name="blocked_numbers_block_emergency_number_message" msgid="917851876780698387">"Non se pode bloquear o número de urxencia."</string>
     <string name="blocked_numbers_number_already_blocked_message" msgid="4392247814500811798">"O <xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g> xa está bloqueado."</string>
     <string name="toast_personal_call_msg" msgid="5115361633476779723">"Usando o marcador persoal para facer a chamada"</string>
     <string name="notification_incoming_call" msgid="7713197997773986670">"Chamada de <xliff:g id="CALL_FROM">%2$s</xliff:g> a través de <xliff:g id="CALL_VIA">%1$s</xliff:g>"</string>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index 8bf0a6d..9f2991a 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -39,8 +39,8 @@
     <string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"संदेश <xliff:g id="PHONE_NUMBER">%s</xliff:g> वर पाठविला."</string>
     <string name="enable_account_preference_title" msgid="2021848090086481720">"कॉल करण्याची खाती"</string>
     <string name="outgoing_call_not_allowed_user_restriction" msgid="6872406278300131364">"फक्त आणीबाणी कॉल करण्याची परवानगी आहे."</string>
-    <string name="outgoing_call_not_allowed_no_permission" msgid="1996571596464271228">"हा अनुप्रयोग फोन परवानगी शिवाय कॉल करू शकत नाही."</string>
-    <string name="outgoing_call_error_no_phone_number_supplied" msgid="1940125199802007505">"कॉल करण्यासाठी, एक वैध नंबर प्रविष्ट करा."</string>
+    <string name="outgoing_call_not_allowed_no_permission" msgid="1996571596464271228">"हा अॅप्लिकेशन फोन परवानगी शिवाय कॉल करू शकत नाही."</string>
+    <string name="outgoing_call_error_no_phone_number_supplied" msgid="1940125199802007505">"कॉल करण्यासाठी, एक वैध नंबर एंटर करा."</string>
     <string name="duplicate_video_call_not_allowed" msgid="3749211605014548386">"यावेळी कॉल जोडला जाऊ शकत नाही."</string>
     <string name="no_vm_number" msgid="4164780423805688336">"व्हॉइसमेल नंबर गहाळ"</string>
     <string name="no_vm_number_msg" msgid="1300729501030053828">"सिम कार्डवर कोणताही व्हॉइसमेल नंबर संचयित केला नाही."</string>
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
index 18f69b2..5bf26f3 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -57,7 +57,7 @@
     <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>
+    <string name="non_primary_user" msgid="5180129233352533459">"ਸਿਰਫ਼ ਡੀਵਾਈਸ ਮਾਲਕ ਹੀ ਬਲੌਕ ਕੀਤੇ ਗਏ ਨੰਬਰਾਂ ਨੂੰ  ਦੇਖ  ਅਤੇ ਪ੍ਰਬੰਧਿਤ ਕਰ ਸਕਦਾ ਹੈ।"</string>
     <string name="delete_icon_description" msgid="8903995728252556724">"ਅਨਬਲੌਕ ਕਰੋ"</string>
     <string name="blocked_numbers_butter_bar_title" msgid="438170866438793182">"ਬਲੌਕਿੰਗ ਆਰਜ਼ੀ ਤੌਰ \'ਤੇ ਬੰਦ ਹੈ"</string>
     <string name="blocked_numbers_butter_bar_body" msgid="2223244484319442431">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਇੱਕ ਐਮਰਜੈਂਸੀ ਨੰਬਰ ਨੂੰ ਡਾਇਲ ਕੀਤੇ ਜਾਣ ਜਾਂ ਲਿਖਤ ਸੁਨੇਹਾ ਭੇਜੇ ਜਾਣ ਤੋਂ ਬਾਅਦ, ਇਹ ਯਕੀਨੀ ਬਣਾਉਣ ਲਈ ਬਲੌਕਿੰਗ ਨੂੰ ਬੰਦ ਕੀਤਾ ਜਾਂਦਾ ਹੈ ਕਿ ਐਮਰਜੈਂਸੀ ਸੇਵਾਵਾਂ ਤੁਹਾਨੂੰ ਸੰਪਰਕ ਕਰ ਸਕਣ।"</string>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 3ae5c3c..d130b0f 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -68,13 +68,13 @@
     <string name="blocked_numbers_number_already_blocked_message" msgid="4392247814500811798">"<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g> ถูกบล็อกอยู่แล้ว"</string>
     <string name="toast_personal_call_msg" msgid="5115361633476779723">"การใช้โทรศัพท์ส่วนตัวเพื่อทำการโทร"</string>
     <string name="notification_incoming_call" msgid="7713197997773986670">"สายเรียกเข้าใน <xliff:g id="CALL_VIA">%1$s</xliff:g> จาก <xliff:g id="CALL_FROM">%2$s</xliff:g>"</string>
-    <string name="notification_incoming_video_call" msgid="6638486071698373893">"แฮงเอาท์วิดีโอเรียกเข้าใน <xliff:g id="CALL_VIA">%1$s</xliff:g> จาก <xliff:g id="CALL_FROM">%2$s</xliff:g>"</string>
+    <string name="notification_incoming_video_call" msgid="6638486071698373893">" Hangouts วิดีโอเรียกเข้าใน <xliff:g id="CALL_VIA">%1$s</xliff:g> จาก <xliff:g id="CALL_FROM">%2$s</xliff:g>"</string>
     <string name="answering_ends_other_call" msgid="8282145910153766401">"การรับสายนี้จะวางสายใน <xliff:g id="CALL_VIA">%1$s</xliff:g>"</string>
     <string name="answering_ends_other_calls" msgid="1198589551399049197">"การรับสายนี้จะวางสายใน <xliff:g id="CALL_VIA">%1$s</xliff:g>"</string>
-    <string name="answering_ends_other_video_call" msgid="8510410917384186360">"การรับสายนี้จะวางสายแฮงเอาท์วิดีโอใน <xliff:g id="CALL_VIA">%1$s</xliff:g>"</string>
+    <string name="answering_ends_other_video_call" msgid="8510410917384186360">"การรับสายนี้จะวางสาย Hangouts วิดีโอใน <xliff:g id="CALL_VIA">%1$s</xliff:g>"</string>
     <string name="answering_ends_other_managed_call" msgid="5186137550267947785">"การรับสายนี้จะวางสายที่สนทนาอยู่"</string>
     <string name="answering_ends_other_managed_calls" msgid="6429838309560397988">"การรับสายนี้จะวางสายที่สนทนาอยู่"</string>
-    <string name="answering_ends_other_managed_video_call" msgid="1585423762458248435">"การรับสายนี้จะวางสายแฮงเอาท์วิดีโอที่สนทนาอยู่"</string>
+    <string name="answering_ends_other_managed_video_call" msgid="1585423762458248435">"การรับสายนี้จะวางสาย Hangouts วิดีโอที่สนทนาอยู่"</string>
     <string name="answer_incoming_call" msgid="4140530013111794587">"รับสาย"</string>
     <string name="decline_incoming_call" msgid="806026168661598368">"ปฏิเสธ"</string>
     <string name="cant_call_due_to_ongoing_call" msgid="4952615196237854748">"ไม่สามารถโทรออกได้เนื่องจากกำลังใช้สายอยู่ใน <xliff:g id="OTHER_CALL">%1$s</xliff:g>"</string>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index d789e31..714ddc9 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -50,7 +50,7 @@
     <string name="change_default_dialer_dialog_negative" msgid="9078144617060173845">"Bekor qilish"</string>
     <string name="change_default_dialer_warning_message" msgid="1417671460801684999">"<xliff:g id="NEW_APP">%s</xliff:g> ilovasi qo‘ng‘iroq qilishga yodam beradi va qo‘ng‘iroqlarga tegishli boshqa barcha parametrlarni boshqaradi. Qo‘ng‘iroqlar uchun faqat ishonarli ilovani asosiy ilova qilib o‘rnatish lozim."</string>
     <string name="blocked_numbers" msgid="2751843139572970579">"Bloklangan raqamlar"</string>
-    <string name="blocked_numbers_msg" msgid="1045015186124965643">"Bloklangan raqamlardan keladigan chaqiruv yoki SMS xabarlar qabul qilinmaydi."</string>
+    <string name="blocked_numbers_msg" msgid="1045015186124965643">"Bloklangan telefon raqamlaridan chaqiruv yoki matnli xabarlar qabul qilib bo‘lmaydi."</string>
     <string name="block_number" msgid="1101252256321306179">"Biror raqamni bloklash"</string>
     <string name="unblock_dialog_body" msgid="1614238499771862793">"<xliff:g id="NUMBER_TO_BLOCK">%1$s</xliff:g> raqami blokdan chiqarilsinmi?"</string>
     <string name="unblock_button" msgid="3078048901972674170">"Blokdan chiqarish"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 5c043ea..8a9ca00 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -32,8 +32,8 @@
     <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_setting_title" msgid="3754000371039709383">"快速回應"</string>
-    <string name="respond_via_sms_setting_title_2" msgid="6104662227299493906">"編輯快速回應"</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>
     <string name="respond_via_sms_edittext_dialog_title" msgid="20379890418289778">"快速回應"</string>
     <string name="respond_via_sms_confirmation_format" msgid="7229149977515784269">"訊息已傳送至 <xliff:g id="PHONE_NUMBER">%s</xliff:g>。"</string>
diff --git a/res/values/config.xml b/res/values/config.xml
index 111d86b..ecfa12b 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -47,7 +47,7 @@
          maximum ringing calls. -->
     <bool name="silence_incoming_when_different_service_and_maximum_ringing">false</bool>
 
-    <!-- Determines if the granting temporary location permission to the default dialer
-         during an emergency call should be allowed.  The default is false. -->
+    <!-- Determines if the granting of temporary location permission to the default dialer
+         during an emergency call should be allowed. -->
     <bool name="grant_location_permission_enabled">false</bool>
 </resources>
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index 65f9b5a..c6bde65 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -74,7 +74,8 @@
  *  connected etc).
  */
 @VisibleForTesting
-public class Call implements CreateConnectionResponse, EventManager.Loggable {
+public class Call implements CreateConnectionResponse, EventManager.Loggable,
+        ConnectionServiceFocusManager.CallFocus {
     public final static String CALL_ID_UNKNOWN = "-1";
     public final static long DATA_USAGE_NOT_SET = -1;
 
@@ -748,6 +749,11 @@
         return sb.toString();
     }
 
+    @Override
+    public ConnectionServiceFocusManager.ConnectionServiceFocus getConnectionServiceWrapper() {
+        return mConnectionService;
+    }
+
     @VisibleForTesting
     public int getState() {
         return mState;
diff --git a/src/com/android/server/telecom/CallAudioRouteStateMachine.java b/src/com/android/server/telecom/CallAudioRouteStateMachine.java
index 1073623..23e5e69 100644
--- a/src/com/android/server/telecom/CallAudioRouteStateMachine.java
+++ b/src/com/android/server/telecom/CallAudioRouteStateMachine.java
@@ -22,6 +22,7 @@
 import android.bluetooth.BluetoothHeadset;
 import android.content.Context;
 import android.content.pm.UserInfo;
+import android.media.AudioDeviceInfo;
 import android.media.AudioManager;
 import android.media.IAudioService;
 import android.os.Binder;
@@ -68,6 +69,12 @@
  * mIsMuted: a boolean indicating whether the audio is muted
  */
 public class CallAudioRouteStateMachine extends StateMachine {
+
+    /** Values for CallAudioRouteStateMachine constructor's earPieceRouting arg. */
+    public static final int EARPIECE_FORCE_DISABLED = 0;
+    public static final int EARPIECE_FORCE_ENABLED  = 1;
+    public static final int EARPIECE_AUTO_DETECT    = 2;
+
     /** Direct the audio stream through the device's earpiece. */
     public static final int ROUTE_EARPIECE      = CallAudioState.ROUTE_EARPIECE;
 
@@ -1259,7 +1266,7 @@
             WiredHeadsetManager wiredHeadsetManager,
             StatusBarNotifier statusBarNotifier,
             CallAudioManager.AudioServiceFactory audioServiceFactory,
-            boolean doesDeviceSupportEarpieceRoute) {
+            int earpieceControl) {
         super(NAME);
         addState(mActiveEarpieceRoute);
         addState(mActiveHeadsetRoute);
@@ -1278,7 +1285,16 @@
         mWiredHeadsetManager = wiredHeadsetManager;
         mStatusBarNotifier = statusBarNotifier;
         mAudioServiceFactory = audioServiceFactory;
-        mDoesDeviceSupportEarpieceRoute = doesDeviceSupportEarpieceRoute;
+        switch (earpieceControl) {
+            case EARPIECE_FORCE_DISABLED:
+                mDoesDeviceSupportEarpieceRoute = false;
+                break;
+            case EARPIECE_FORCE_ENABLED:
+                mDoesDeviceSupportEarpieceRoute = true;
+                break;
+            default:
+                mDoesDeviceSupportEarpieceRoute = checkForEarpieceSupport();
+        }
         mIsInbandRingSupported = BluetoothHeadset.isInbandRingingSupported(mContext);
         mLock = callsManager.getLock();
 
@@ -1600,14 +1616,15 @@
         return currentState.isActive();
     }
 
-    public static boolean doesDeviceSupportEarpieceRoute() {
-        String[] characteristics = SystemProperties.get("ro.build.characteristics").split(",");
-        for (String characteristic : characteristics) {
-            if ("watch".equals(characteristic)) {
-                return false;
+    private boolean checkForEarpieceSupport() {
+        AudioDeviceInfo[] deviceList = mAudioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
+        for (AudioDeviceInfo device: deviceList) {
+            if (device.getType() == AudioDeviceInfo.TYPE_BUILTIN_EARPIECE) {
+                return true;
             }
         }
-        return true;
+        // No earpiece found
+        return false;
     }
 
     private int calculateBaselineRouteMessage(boolean isExplicitUserRequest,
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index 35abca1..114fec9 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -340,7 +340,7 @@
                 wiredHeadsetManager,
                 statusBarNotifier,
                 audioServiceFactory,
-                CallAudioRouteStateMachine.doesDeviceSupportEarpieceRoute()
+                CallAudioRouteStateMachine.EARPIECE_AUTO_DETECT
         );
         callAudioRouteStateMachine.initialize();
 
diff --git a/src/com/android/server/telecom/ConnectionServiceFocusManager.java b/src/com/android/server/telecom/ConnectionServiceFocusManager.java
new file mode 100644
index 0000000..60fbbd1
--- /dev/null
+++ b/src/com/android/server/telecom/ConnectionServiceFocusManager.java
@@ -0,0 +1,404 @@
+/*
+ * Copyright 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;
+
+import android.annotation.Nullable;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+public class ConnectionServiceFocusManager {
+
+    private static final String TAG = "ConnectionServiceFocusManager";
+
+    /**
+     * Interface used by ConnectionServiceFocusManager to communicate with
+     * {@link ConnectionServiceWrapper}.
+     */
+    public interface ConnectionServiceFocus {
+        /**
+         * Notifies the {@link android.telecom.ConnectionService} that it has lose the connection
+         * service focus. It should release all call resource i.e camera, audio once it lost the
+         * focus.
+         */
+        void connectionServiceFocusLost();
+
+        /**
+         * Notifies the {@link android.telecom.ConnectionService} that it has gain the connection
+         * service focus. It can request the call resource i.e camera, audio as they expected to be
+         * free at the moment.
+         */
+        void connectionServiceFocusGained();
+
+        /**
+         * Sets the ConnectionServiceFocusListener.
+         *
+         * @see {@link ConnectionServiceFocusListener}.
+         */
+        void setConnectionServiceFocusListener(ConnectionServiceFocusListener listener);
+    }
+
+    /**
+     * Interface used to receive the changed of {@link android.telecom.ConnectionService} that
+     * ConnectionServiceFocusManager cares about.
+     */
+    public interface ConnectionServiceFocusListener {
+        /**
+         * Calls when {@link android.telecom.ConnectionService} has released the call resource. This
+         * usually happen after the {@link android.telecom.ConnectionService} lost the focus.
+         *
+         * @param connectionServiceFocus the {@link android.telecom.ConnectionService} that released
+         * the call resources.
+         */
+        void onConnectionServiceReleased(ConnectionServiceFocus connectionServiceFocus);
+
+        /**
+         * Calls when {@link android.telecom.ConnectionService} is disconnected.
+         *
+         * @param connectionServiceFocus the {@link android.telecom.ConnectionService} which is
+         * disconnected.
+         */
+        void onConnectionServiceDeath(ConnectionServiceFocus connectionServiceFocus);
+    }
+
+    /**
+     * Interface define to expose few information of {@link Call} that ConnectionServiceFocusManager
+     * cares about.
+     */
+    public interface CallFocus {
+        /**
+         * Returns the ConnectionService associated with the call.
+         */
+        ConnectionServiceFocus getConnectionServiceWrapper();
+
+        /**
+         * Returns the state of the call.
+         *
+         * @see {@link CallState}
+         */
+        int getState();
+    }
+
+    /** Interface define a call back for focus request event. */
+    public interface RequestFocusCallback {
+        /**
+         * Invokes after the focus request is done.
+         *
+         * @param call the call associated with the focus request.
+         */
+        void onRequestFocusDone(CallFocus call);
+    }
+
+    /**
+     * Interface define to allow the ConnectionServiceFocusManager to communicate with
+     * {@link CallsManager}.
+     */
+    public interface CallsManagerRequester {
+        /**
+         * Requests {@link CallsManager} to disconnect a {@link ConnectionServiceFocus}. This
+         * usually happen when the connection service doesn't respond to focus lost event.
+         */
+        void releaseConnectionService(ConnectionServiceFocus connectionService);
+
+        /**
+         * Sets the {@link com.android.server.telecom.CallsManager.CallsManagerListener} to listen
+         * the call event that ConnectionServiceFocusManager cares about.
+         */
+        void setCallsManagerListener(CallsManager.CallsManagerListener listener);
+    }
+
+    private static final int[] PRIORITY_FOCUS_CALL_STATE = new int[] {
+            CallState.ACTIVE, CallState.CONNECTING, CallState.DIALING
+    };
+
+    private static final int MSG_REQUEST_FOCUS = 1;
+    private static final int MSG_RELEASE_CONNECTION_FOCUS = 2;
+    private static final int MSG_RELEASE_FOCUS_TIMEOUT = 3;
+    private static final int MSG_CONNECTION_SERVICE_DEATH = 4;
+    private static final int MSG_ADD_CALL = 5;
+    private static final int MSG_REMOVE_CALL = 6;
+    private static final int MSG_CALL_STATE_CHANGED = 7;
+
+    @VisibleForTesting
+    public static final int RELEASE_FOCUS_TIMEOUT_MS = 5000;
+
+    private final List<CallFocus> mCalls;
+
+    private final CallsManagerListenerBase mCallsManagerListener =
+            new CallsManagerListenerBase() {
+                @Override
+                public void onCallAdded(Call call) {
+                    if (callShouldBeIgnored(call)) {
+                        return;
+                    }
+
+                    mEventHandler.obtainMessage(MSG_ADD_CALL, call).sendToTarget();
+                }
+
+                @Override
+                public void onCallRemoved(Call call) {
+                    if (callShouldBeIgnored(call)) {
+                        return;
+                    }
+
+                    mEventHandler.obtainMessage(MSG_REMOVE_CALL, call).sendToTarget();
+                }
+
+                @Override
+                public void onCallStateChanged(Call call, int oldState, int newState) {
+                    if (callShouldBeIgnored(call)) {
+                        return;
+                    }
+
+                    mEventHandler.obtainMessage(MSG_CALL_STATE_CHANGED, oldState, newState, call)
+                            .sendToTarget();
+                }
+
+                @Override
+                public void onExternalCallChanged(Call call, boolean isExternalCall) {
+                    if (isExternalCall) {
+                        mEventHandler.obtainMessage(MSG_REMOVE_CALL, call).sendToTarget();
+                    } else {
+                        mEventHandler.obtainMessage(MSG_ADD_CALL, call).sendToTarget();
+                    }
+                }
+
+                boolean callShouldBeIgnored(Call call) {
+                    return call.isExternalCall();
+                }
+            };
+
+    private final ConnectionServiceFocusListener mConnectionServiceFocusListener =
+            new ConnectionServiceFocusListener() {
+        @Override
+        public void onConnectionServiceReleased(ConnectionServiceFocus connectionServiceFocus) {
+            mEventHandler.obtainMessage(MSG_RELEASE_CONNECTION_FOCUS, connectionServiceFocus)
+                    .sendToTarget();
+        }
+
+        @Override
+        public void onConnectionServiceDeath(ConnectionServiceFocus connectionServiceFocus) {
+            mEventHandler.obtainMessage(MSG_CONNECTION_SERVICE_DEATH, connectionServiceFocus)
+                    .sendToTarget();
+        }
+    };
+
+    private ConnectionServiceFocus mCurrentFocus;
+    private CallFocus mCurrentFocusCall;
+    private CallsManagerRequester mCallsManagerRequester;
+    private FocusRequest mCurrentFocusRequest;
+    private FocusManagerHandler mEventHandler;
+
+    public ConnectionServiceFocusManager(
+            CallsManagerRequester callsManagerRequester, Looper looper) {
+        mCallsManagerRequester = callsManagerRequester;
+        mCallsManagerRequester.setCallsManagerListener(mCallsManagerListener);
+        mEventHandler = new FocusManagerHandler(looper);
+        mCalls = new ArrayList<>();
+    }
+
+    /**
+     * Requests the call focus for the given call. The {@code callback} will be invoked once
+     * the request is done.
+     * @param focus the call need to be focus.
+     * @param callback the callback associated with this request.
+     */
+    public void requestFocus(CallFocus focus, RequestFocusCallback callback) {
+        mEventHandler.obtainMessage(
+                MSG_REQUEST_FOCUS, new FocusRequest(focus, callback)).sendToTarget();
+    }
+
+    /**
+     * Returns the current focus call. The {@link android.telecom.ConnectionService} of the focus
+     * call is the current connection service focus. Also the state of the focus call must be one
+     * of {@link #PRIORITY_FOCUS_CALL_STATE}.
+     */
+    public CallFocus getCurrentFocusCall() {
+        return mCurrentFocusCall;
+    }
+
+    /** Returns the current connection service focus. */
+    public ConnectionServiceFocus getCurrentFocusConnectionService() {
+        return mCurrentFocus;
+    }
+
+    @VisibleForTesting
+    public Handler getHandler() {
+        return mEventHandler;
+    }
+
+    @VisibleForTesting
+    public List<CallFocus> getAllCall() { return mCalls; }
+
+    private void updateConnectionServiceFocus(ConnectionServiceFocus connSvrFocus) {
+        if (!Objects.equals(mCurrentFocus, connSvrFocus)) {
+            if (connSvrFocus != null) {
+                connSvrFocus.setConnectionServiceFocusListener(mConnectionServiceFocusListener);
+                connSvrFocus.connectionServiceFocusGained();
+            }
+            mCurrentFocus = connSvrFocus;
+        }
+    }
+
+    private void updateCurrentFocusCall() {
+        mCurrentFocusCall = null;
+
+        if (mCurrentFocus == null) {
+            return;
+        }
+
+        List<CallFocus> calls = mCalls
+                .stream()
+                .filter(call -> mCurrentFocus.equals(call.getConnectionServiceWrapper()))
+                .collect(Collectors.toList());
+
+        for (int i = 0; i < PRIORITY_FOCUS_CALL_STATE.length; i++) {
+            for (CallFocus call : calls) {
+                if (call.getState() == PRIORITY_FOCUS_CALL_STATE[i]) {
+                    mCurrentFocusCall = call;
+                    return;
+                }
+            }
+        }
+    }
+
+    private void onRequestFocusDone(FocusRequest focusRequest) {
+        if (focusRequest.callback != null) {
+            focusRequest.callback.onRequestFocusDone(focusRequest.call);
+        }
+    }
+
+    private void handleRequestFocus(FocusRequest focusRequest) {
+        if (mCurrentFocus == null
+                || mCurrentFocus.equals(focusRequest.call.getConnectionServiceWrapper())) {
+            updateConnectionServiceFocus(focusRequest.call.getConnectionServiceWrapper());
+            updateCurrentFocusCall();
+            onRequestFocusDone(focusRequest);
+        } else {
+            mCurrentFocus.connectionServiceFocusLost();
+            mCurrentFocusRequest = focusRequest;
+            Message msg = mEventHandler.obtainMessage(MSG_RELEASE_FOCUS_TIMEOUT);
+            msg.obj = focusRequest;
+            mEventHandler.sendMessageDelayed(msg, RELEASE_FOCUS_TIMEOUT_MS);
+        }
+    }
+
+    private void handleReleasedFocus(ConnectionServiceFocus connectionServiceFocus) {
+        // The ConnectionService can call onConnectionServiceFocusReleased even if it's not the
+        // current focus connection service, nothing will be changed in this case.
+        if (Objects.equals(mCurrentFocus, connectionServiceFocus)) {
+            mEventHandler.removeMessages(MSG_RELEASE_FOCUS_TIMEOUT, mCurrentFocusRequest);
+            ConnectionServiceFocus newCSF = null;
+            if (mCurrentFocusRequest != null) {
+                newCSF = mCurrentFocusRequest.call.getConnectionServiceWrapper();
+            }
+            updateConnectionServiceFocus(newCSF);
+            updateCurrentFocusCall();
+            if (mCurrentFocusRequest != null) {
+                onRequestFocusDone(mCurrentFocusRequest);
+                mCurrentFocusRequest = null;
+            }
+        }
+    }
+
+    private void handleReleasedFocusTimeout(FocusRequest focusRequest) {
+        mCallsManagerRequester.releaseConnectionService(mCurrentFocus);
+        updateConnectionServiceFocus(focusRequest.call.getConnectionServiceWrapper());
+        updateCurrentFocusCall();
+        onRequestFocusDone(focusRequest);
+        mCurrentFocusRequest = null;
+    }
+
+    private void handleConnectionServiceDeath(ConnectionServiceFocus connectionServiceFocus) {
+        if (Objects.equals(connectionServiceFocus, mCurrentFocus)) {
+            updateConnectionServiceFocus(null);
+            updateCurrentFocusCall();
+        }
+    }
+
+    private void handleAddedCall(CallFocus call) {
+        if (!mCalls.contains(call)) {
+            mCalls.add(call);
+        }
+        if (Objects.equals(mCurrentFocus, call.getConnectionServiceWrapper())) {
+            updateCurrentFocusCall();
+        }
+    }
+
+    private void handleRemovedCall(CallFocus call) {
+        mCalls.remove(call);
+        if (call.equals(mCurrentFocusCall)) {
+            updateCurrentFocusCall();
+        }
+    }
+
+    private void handleCallStateChanged(CallFocus call, int oldState, int newState) {
+        if (mCalls.contains(call)
+                && Objects.equals(mCurrentFocus, call.getConnectionServiceWrapper())) {
+            updateCurrentFocusCall();
+        }
+    }
+
+    private final class FocusManagerHandler extends Handler {
+        FocusManagerHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_REQUEST_FOCUS:
+                    handleRequestFocus((FocusRequest) msg.obj);
+                    break;
+                case MSG_RELEASE_CONNECTION_FOCUS:
+                    handleReleasedFocus((ConnectionServiceFocus) msg.obj);
+                    break;
+                case MSG_RELEASE_FOCUS_TIMEOUT:
+                    handleReleasedFocusTimeout((FocusRequest) msg.obj);
+                    break;
+                case MSG_CONNECTION_SERVICE_DEATH:
+                    handleConnectionServiceDeath((ConnectionServiceFocus) msg.obj);
+                    break;
+                case MSG_ADD_CALL:
+                    handleAddedCall((CallFocus) msg.obj);
+                    break;
+                case MSG_REMOVE_CALL:
+                    handleRemovedCall((CallFocus) msg.obj);
+                    break;
+                case MSG_CALL_STATE_CHANGED:
+                    handleCallStateChanged((CallFocus) msg.obj, msg.arg1, msg.arg2);
+                    break;
+            }
+        }
+    }
+
+    private static final class FocusRequest {
+        CallFocus call;
+        @Nullable RequestFocusCallback callback;
+
+        FocusRequest(CallFocus call, RequestFocusCallback callback) {
+            this.call = call;
+            this.callback = callback;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/server/telecom/ConnectionServiceWrapper.java b/src/com/android/server/telecom/ConnectionServiceWrapper.java
index 46af93f..dce085c 100644
--- a/src/com/android/server/telecom/ConnectionServiceWrapper.java
+++ b/src/com/android/server/telecom/ConnectionServiceWrapper.java
@@ -64,7 +64,8 @@
  * {@link IConnectionService}.
  */
 @VisibleForTesting
-public class ConnectionServiceWrapper extends ServiceBinder {
+public class ConnectionServiceWrapper extends ServiceBinder implements
+        ConnectionServiceFocusManager.ConnectionServiceFocus {
 
     private final class Adapter extends IConnectionServiceAdapter.Stub {
 
@@ -854,6 +855,13 @@
                 Log.endSession();
             }
         }
+
+        @Override
+        public void onConnectionServiceFocusReleased(Session.Info sessionInfo)
+                throws RemoteException {
+            // TODO(mpq): This method is added to avoid the compiled error. Add the real
+            // implementation once ag/3273964 done.
+        }
     }
 
     private final Adapter mAdapter = new Adapter();
@@ -867,6 +875,8 @@
     private final CallsManager mCallsManager;
     private final AppOpsManager mAppOpsManager;
 
+    private ConnectionServiceFocusManager.ConnectionServiceFocusListener mConnSvrFocusListener;
+
     /**
      * Creates a connection service.
      *
@@ -1406,6 +1416,24 @@
         mServiceInterface = null;
     }
 
+    @Override
+    public void connectionServiceFocusLost() {
+        // Immediately response to the Telecom that it has released the call resources.
+        // TODO(mpq): Change back to the default implementation once b/69651192 done.
+        if (mConnSvrFocusListener != null) {
+            mConnSvrFocusListener.onConnectionServiceReleased(this);
+        }
+    }
+
+    @Override
+    public void connectionServiceFocusGained() {}
+
+    @Override
+    public void setConnectionServiceFocusListener(
+            ConnectionServiceFocusManager.ConnectionServiceFocusListener listener) {
+        mConnSvrFocusListener = listener;
+    }
+
     private void handleCreateConnectionComplete(
             String callId,
             ConnectionRequest request,
@@ -1440,6 +1468,10 @@
             }
         }
         mCallIdMapper.clear();
+
+        if (mConnSvrFocusListener != null) {
+            mConnSvrFocusListener.onConnectionServiceDeath(this);
+        }
     }
 
     private void logIncoming(String msg, Object... params) {
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
index 74b25be..2979bf9 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -980,15 +980,9 @@
         public boolean isTtySupported(String callingPackage) {
             try {
                 Log.startSession("TSI.iTS");
-                if (!isPrivilegedDialerCalling(callingPackage)) {
-                    try {
-                        enforceModifyPermission(
-                                "isTtySupported requires MODIFY_PHONE_STATE permission.");
-                    } catch (SecurityException e) {
-                        EventLog.writeEvent(0x534e4554, "62347125", "isTtySupported: " +
-                                callingPackage);
-                        throw e;
-                    }
+                if (!canReadPhoneState(callingPackage, "isTtySupported")) {
+                    throw new SecurityException("Only default dialer or an app with" +
+                            "READ_PRIVILEGED_PHONE_STATE or READ_PHONE_STATE can call this api");
                 }
 
                 synchronized (mLock) {
diff --git a/tests/Android.mk b/tests/Android.mk
index 77abcad..7f449fa 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -41,9 +41,12 @@
 
 LOCAL_JAVA_LIBRARIES := \
         android.test.mock \
-        legacy-android-test \
+        android.test.base \
+        android.test.runner \
         telephony-common
 
+LOCAL_USE_AAPT2 := true
+
 LOCAL_AAPT_FLAGS := \
     --auto-add-overlay \
     --extra-packages com.android.server.telecom:android.support.compat
diff --git a/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java b/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java
index 9e94df9..5bd921a 100644
--- a/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java
+++ b/tests/src/com/android/server/telecom/tests/CallAudioRouteStateMachineTest.java
@@ -89,7 +89,7 @@
         public int expectedRoute;
         public BluetoothDevice expectedBluetoothDevice = null;
         public int expectedAvailableRoutes; // also may exclude the speakerphone.
-        public boolean doesDeviceSupportEarpiece; // set to false in the case of Wear devices
+        public int earpieceControl; // Allows disabling the earpiece to simulate Wear or Car
         public boolean shouldRunWithFocus;
 
         public int callSupportedRoutes = CallAudioState.ROUTE_ALL;
@@ -97,7 +97,7 @@
         public RoutingTestParameters(String name, int initialRoute,
                 int availableRoutes, int speakerInteraction,
                 int bluetoothInteraction, int action, int expectedRoute,
-                int expectedAvailableRoutes, boolean doesDeviceSupportEarpiece,
+                int expectedAvailableRoutes, int earpieceControl,
                 boolean shouldRunWithFocus) {
             this.name = name;
             this.initialRoute = initialRoute;
@@ -107,7 +107,7 @@
             this.action = action;
             this.expectedRoute = expectedRoute;
             this.expectedAvailableRoutes = expectedAvailableRoutes;
-            this.doesDeviceSupportEarpiece = doesDeviceSupportEarpiece;
+            this.earpieceControl = earpieceControl;
             this.shouldRunWithFocus = shouldRunWithFocus;
         }
 
@@ -142,7 +142,7 @@
                     ", action=" + action +
                     ", expectedRoute=" + expectedRoute +
                     ", expectedAvailableRoutes=" + expectedAvailableRoutes +
-                    ", doesDeviceSupportEarpiece=" + doesDeviceSupportEarpiece +
+                    ", earpieceControl=" + earpieceControl +
                     ", shouldRunWithFocus=" + shouldRunWithFocus +
                     '}';
         }
@@ -186,6 +186,23 @@
                 any(CallAudioState.class));
     }
 
+    @SmallTest
+    public void testEarpieceAutodetect() {
+        CallAudioRouteStateMachine stateMachine = new CallAudioRouteStateMachine(
+                mContext,
+                mockCallsManager,
+                mockBluetoothRouteManager,
+                mockWiredHeadsetManager,
+                mockStatusBarNotifier,
+                mAudioServiceFactory,
+                CallAudioRouteStateMachine.EARPIECE_AUTO_DETECT);
+
+        // Since we don't know if we're on a platform with an earpiece or not, all we can do
+        // is ensure the stateMachine construction didn't fail.  But at least we exercised the
+        // autodetection code...
+        assertNotNull(stateMachine);
+    }
+
     @LargeTest
     public void testStateMachineTransitionsWithFocus() throws Throwable {
         List<RoutingTestParameters> paramList = generateTransitionTests(true);
@@ -207,7 +224,7 @@
                 mockWiredHeadsetManager,
                 mockStatusBarNotifier,
                 mAudioServiceFactory,
-                true);
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED);
 
         when(mockBluetoothRouteManager.isBluetoothAudioConnectedOrPending()).thenReturn(false);
         when(mockBluetoothRouteManager.isBluetoothAvailable()).thenReturn(true);
@@ -250,7 +267,7 @@
                 mockWiredHeadsetManager,
                 mockStatusBarNotifier,
                 mAudioServiceFactory,
-                true);
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED);
 
         when(mockBluetoothRouteManager.isBluetoothAudioConnectedOrPending()).thenReturn(false);
         when(mockBluetoothRouteManager.isBluetoothAvailable()).thenReturn(true);
@@ -291,7 +308,7 @@
                 mockWiredHeadsetManager,
                 mockStatusBarNotifier,
                 mAudioServiceFactory,
-                true);
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED);
         Collection<BluetoothDevice> availableDevices = Collections.singleton(bluetoothDevice1);
 
         when(mockBluetoothRouteManager.isBluetoothAudioConnectedOrPending()).thenReturn(false);
@@ -362,7 +379,7 @@
                 mockWiredHeadsetManager,
                 mockStatusBarNotifier,
                 mAudioServiceFactory,
-                true);
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED);
 
         when(mockBluetoothRouteManager.isBluetoothAudioConnectedOrPending()).thenReturn(false);
         when(mockBluetoothRouteManager.isBluetoothAvailable()).thenReturn(true);
@@ -395,7 +412,7 @@
                 mockWiredHeadsetManager,
                 mockStatusBarNotifier,
                 mAudioServiceFactory,
-                true);
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED);
         setInBandRing(false);
         when(mockBluetoothRouteManager.isBluetoothAudioConnectedOrPending()).thenReturn(false);
         when(mockBluetoothRouteManager.isBluetoothAvailable()).thenReturn(false);
@@ -440,7 +457,7 @@
                 mockWiredHeadsetManager,
                 mockStatusBarNotifier,
                 mAudioServiceFactory,
-                true);
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED);
         List<BluetoothDevice> availableDevices =
                 Arrays.asList(bluetoothDevice1, bluetoothDevice2, bluetoothDevice3);
 
@@ -482,14 +499,14 @@
     public void testInitializationWithEarpieceNoHeadsetNoBluetooth() {
         CallAudioState expectedState = new CallAudioState(false, CallAudioState.ROUTE_EARPIECE,
                 CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_SPEAKER);
-        initializationTestHelper(expectedState, true);
+        initializationTestHelper(expectedState, CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED);
     }
 
     @SmallTest
     public void testInitializationWithEarpieceAndHeadsetNoBluetooth() {
         CallAudioState expectedState = new CallAudioState(false, CallAudioState.ROUTE_WIRED_HEADSET,
                 CallAudioState.ROUTE_WIRED_HEADSET | CallAudioState.ROUTE_SPEAKER);
-        initializationTestHelper(expectedState, true);
+        initializationTestHelper(expectedState, CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED);
     }
 
     @SmallTest
@@ -497,7 +514,7 @@
         CallAudioState expectedState = new CallAudioState(false, CallAudioState.ROUTE_BLUETOOTH,
                 CallAudioState.ROUTE_WIRED_HEADSET | CallAudioState.ROUTE_SPEAKER
                 | CallAudioState.ROUTE_BLUETOOTH);
-        initializationTestHelper(expectedState, true);
+        initializationTestHelper(expectedState, CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED);
     }
 
     @SmallTest
@@ -505,21 +522,21 @@
         CallAudioState expectedState = new CallAudioState(false, CallAudioState.ROUTE_BLUETOOTH,
                 CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_SPEAKER
                         | CallAudioState.ROUTE_BLUETOOTH);
-        initializationTestHelper(expectedState, true);
+        initializationTestHelper(expectedState, CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED);
     }
 
     @SmallTest
     public void testInitializationWithNoEarpieceNoHeadsetNoBluetooth() {
         CallAudioState expectedState = new CallAudioState(false, CallAudioState.ROUTE_SPEAKER,
                 CallAudioState.ROUTE_SPEAKER);
-        initializationTestHelper(expectedState, false);
+        initializationTestHelper(expectedState, CallAudioRouteStateMachine.EARPIECE_FORCE_DISABLED);
     }
 
     @SmallTest
     public void testInitializationWithHeadsetNoBluetoothNoEarpiece() {
         CallAudioState expectedState = new CallAudioState(false, CallAudioState.ROUTE_WIRED_HEADSET,
                 CallAudioState.ROUTE_WIRED_HEADSET | CallAudioState.ROUTE_SPEAKER);
-        initializationTestHelper(expectedState, false);
+        initializationTestHelper(expectedState, CallAudioRouteStateMachine.EARPIECE_FORCE_DISABLED);
     }
 
     @SmallTest
@@ -527,18 +544,18 @@
         CallAudioState expectedState = new CallAudioState(false, CallAudioState.ROUTE_BLUETOOTH,
                 CallAudioState.ROUTE_WIRED_HEADSET | CallAudioState.ROUTE_SPEAKER
                 | CallAudioState.ROUTE_BLUETOOTH);
-        initializationTestHelper(expectedState, false);
+        initializationTestHelper(expectedState, CallAudioRouteStateMachine.EARPIECE_FORCE_DISABLED);
     }
 
     @SmallTest
     public void testInitializationWithBluetoothNoHeadsetNoEarpiece() {
         CallAudioState expectedState = new CallAudioState(false, CallAudioState.ROUTE_BLUETOOTH,
                 CallAudioState.ROUTE_SPEAKER | CallAudioState.ROUTE_BLUETOOTH);
-        initializationTestHelper(expectedState, false);
+        initializationTestHelper(expectedState, CallAudioRouteStateMachine.EARPIECE_FORCE_DISABLED);
     }
 
     private void initializationTestHelper(CallAudioState expectedState,
-            boolean doesDeviceSupportEarpiece) {
+            int earpieceControl) {
         when(mockWiredHeadsetManager.isPluggedIn()).thenReturn(
                 (expectedState.getSupportedRouteMask() & CallAudioState.ROUTE_WIRED_HEADSET) != 0);
         when(mockBluetoothRouteManager.isBluetoothAvailable()).thenReturn(
@@ -551,7 +568,7 @@
                 mockWiredHeadsetManager,
                 mockStatusBarNotifier,
                 mAudioServiceFactory,
-                doesDeviceSupportEarpiece);
+                earpieceControl);
         stateMachine.initialize();
         assertEquals(expectedState, stateMachine.getCurrentCallAudioState());
     }
@@ -567,7 +584,7 @@
                 CallAudioRouteStateMachine.CONNECT_WIRED_HEADSET, // action
                 CallAudioState.ROUTE_WIRED_HEADSET, // expectedRoute
                 CallAudioState.ROUTE_WIRED_HEADSET, // expectedAvailableRoutes
-                true, // doesDeviceSupportEarpiece
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED, // earpieceControl
                 shouldRunWithFocus
         ));
 
@@ -580,7 +597,7 @@
                 CallAudioRouteStateMachine.CONNECT_WIRED_HEADSET, // action
                 CallAudioState.ROUTE_WIRED_HEADSET, // expectedRoute
                 CallAudioState.ROUTE_WIRED_HEADSET | CallAudioState.ROUTE_BLUETOOTH, // expectedAvai
-                true, // doesDeviceSupportEarpiece
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED, // earpieceControl
                 shouldRunWithFocus
         ));
 
@@ -593,7 +610,7 @@
                 CallAudioRouteStateMachine.CONNECT_WIRED_HEADSET, // action
                 CallAudioState.ROUTE_WIRED_HEADSET, // expectedRoute
                 CallAudioState.ROUTE_WIRED_HEADSET, // expectedAvailableRoutes
-                true, // doesDeviceSupportEarpiece
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED, // earpieceControl
                 shouldRunWithFocus
         ));
 
@@ -606,7 +623,7 @@
                 CallAudioRouteStateMachine.DISCONNECT_WIRED_HEADSET, // action
                 CallAudioState.ROUTE_EARPIECE, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE, // expectedAvailableRoutes
-                true, // doesDeviceSupportEarpiece
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED, // earpieceControl
                 shouldRunWithFocus
         ));
 
@@ -619,7 +636,7 @@
                 CallAudioRouteStateMachine.DISCONNECT_WIRED_HEADSET, // action
                 CallAudioState.ROUTE_BLUETOOTH, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, // expectedAvailable
-                true, // doesDeviceSupportEarpiece
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED, // earpieceControl
                 shouldRunWithFocus
         ));
 
@@ -632,7 +649,7 @@
                 CallAudioRouteStateMachine.DISCONNECT_WIRED_HEADSET, // action
                 CallAudioState.ROUTE_BLUETOOTH, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, // expectedAvailable
-                true, // doesDeviceSupportEarpiece
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED, // earpieceControl
                 shouldRunWithFocus
         ));
 
@@ -645,7 +662,7 @@
                 CallAudioRouteStateMachine.DISCONNECT_WIRED_HEADSET, // action
                 CallAudioState.ROUTE_SPEAKER, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE, // expectedAvailableRoutes
-                true, // doesDeviceSupportEarpiece
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED, // earpieceControl
                 shouldRunWithFocus
         ));
 
@@ -658,7 +675,7 @@
                 CallAudioRouteStateMachine.DISCONNECT_WIRED_HEADSET, // action
                 CallAudioState.ROUTE_SPEAKER, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, // expectedAvailable
-                true, // doesDeviceSupportEarpiece
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED, // earpieceControl
                 shouldRunWithFocus
         ));
 
@@ -671,7 +688,7 @@
                 CallAudioRouteStateMachine.CONNECT_BLUETOOTH, // action
                 CallAudioState.ROUTE_BLUETOOTH, // expectedRoute
                 CallAudioState.ROUTE_BLUETOOTH | CallAudioState.ROUTE_EARPIECE, // expectedAvailable
-                true, // doesDeviceSupportEarpiece
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED, // earpieceControl
                 shouldRunWithFocus
         ));
 
@@ -684,7 +701,7 @@
                 CallAudioRouteStateMachine.CONNECT_BLUETOOTH, // action
                 CallAudioState.ROUTE_BLUETOOTH, // expectedRoute
                 CallAudioState.ROUTE_BLUETOOTH | CallAudioState.ROUTE_WIRED_HEADSET, // expectedAvai
-                true, // doesDeviceSupportEarpiece
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED, // earpieceControl
                 shouldRunWithFocus
         ));
 
@@ -697,7 +714,7 @@
                 CallAudioRouteStateMachine.CONNECT_BLUETOOTH, // action
                 CallAudioState.ROUTE_BLUETOOTH, // expectedRoute
                 CallAudioState.ROUTE_BLUETOOTH | CallAudioState.ROUTE_EARPIECE, // expectedAvailable
-                true, // doesDeviceSupportEarpiece
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED, // earpieceControl
                 shouldRunWithFocus
         ));
 
@@ -710,7 +727,7 @@
                 CallAudioRouteStateMachine.DISCONNECT_BLUETOOTH, // action
                 CallAudioState.ROUTE_EARPIECE, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE, // expectedAvailableRoutes
-                true, // doesDeviceSupportEarpiece
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED, // earpieceControl
                 shouldRunWithFocus
         ));
 
@@ -723,7 +740,7 @@
                 CallAudioRouteStateMachine.DISCONNECT_BLUETOOTH, // action
                 CallAudioState.ROUTE_EARPIECE, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE, // expectedAvailableRoutes
-                true, // doesDeviceSupportEarpiece
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED, // earpieceControl
                 shouldRunWithFocus
         ));
 
@@ -736,7 +753,7 @@
                 CallAudioRouteStateMachine.DISCONNECT_BLUETOOTH, // action
                 CallAudioState.ROUTE_WIRED_HEADSET, // expectedRoute
                 CallAudioState.ROUTE_WIRED_HEADSET, // expectedAvailableRoutes
-                true, // doesDeviceSupportEarpiece
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED, // earpieceControl
                 shouldRunWithFocus
         ));
 
@@ -749,7 +766,7 @@
                 CallAudioRouteStateMachine.DISCONNECT_BLUETOOTH, // action
                 CallAudioState.ROUTE_SPEAKER, // expectedRoute
                 CallAudioState.ROUTE_WIRED_HEADSET, // expectedAvailableRoutes
-                true, // doesDeviceSupportEarpiece
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED, // earpieceControl
                 shouldRunWithFocus
         ));
 
@@ -762,7 +779,7 @@
                 CallAudioRouteStateMachine.DISCONNECT_BLUETOOTH, // action
                 CallAudioState.ROUTE_EARPIECE, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE, // expectedAvailableRoutes
-                true, // doesDeviceSupportEarpiece
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED, // earpieceControl
                 shouldRunWithFocus
         ));
 
@@ -775,7 +792,7 @@
                 CallAudioRouteStateMachine.SWITCH_SPEAKER, // action
                 CallAudioState.ROUTE_SPEAKER, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE, // expectedAvailableRoutes
-                true, // doesDeviceSupportEarpiece
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED, // earpieceControl
                 shouldRunWithFocus
         ));
 
@@ -788,7 +805,7 @@
                 CallAudioRouteStateMachine.SWITCH_SPEAKER, // action
                 CallAudioState.ROUTE_SPEAKER, // expectedRoute
                 CallAudioState.ROUTE_WIRED_HEADSET, // expectedAvailableRoutes
-                true, // doesDeviceSupportEarpiece
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED, // earpieceControl
                 shouldRunWithFocus
         ));
 
@@ -801,7 +818,7 @@
                 CallAudioRouteStateMachine.SWITCH_SPEAKER, // action
                 CallAudioState.ROUTE_SPEAKER, // expectedRoute
                 CallAudioState.ROUTE_WIRED_HEADSET | CallAudioState.ROUTE_BLUETOOTH, // expectedAvai
-                true, // doesDeviceSupportEarpiece
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED, // earpieceControl
                 shouldRunWithFocus
         ));
 
@@ -814,7 +831,7 @@
                 CallAudioRouteStateMachine.SWITCH_EARPIECE, // action
                 CallAudioState.ROUTE_EARPIECE, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, // expectedAvailable
-                true, // doesDeviceSupportEarpiece
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED, // earpieceControl
                 shouldRunWithFocus
         ));
 
@@ -827,7 +844,7 @@
                 CallAudioRouteStateMachine.SWITCH_EARPIECE, // action
                 CallAudioState.ROUTE_EARPIECE, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE, // expectedAvailableRoutes
-                true, // doesDeviceSupportEarpiece
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED, // earpieceControl
                 shouldRunWithFocus
         ));
 
@@ -840,7 +857,7 @@
                 CallAudioRouteStateMachine.SWITCH_EARPIECE, // action
                 CallAudioState.ROUTE_EARPIECE, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE, // expectedAvailableRoutes
-                true, // doesDeviceSupportEarpiece
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED, // earpieceControl
                 shouldRunWithFocus
         ));
 
@@ -853,7 +870,7 @@
                 CallAudioRouteStateMachine.SWITCH_EARPIECE, // action
                 CallAudioState.ROUTE_EARPIECE, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE, // expectedAvailableRoutes
-                true, // doesDeviceSupportEarpiece
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED, // earpieceControl
                 shouldRunWithFocus
         ));
 
@@ -866,7 +883,7 @@
                 CallAudioRouteStateMachine.SWITCH_BLUETOOTH, // action
                 CallAudioState.ROUTE_BLUETOOTH, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, // expectedAvailable
-                true, // doesDeviceSupportEarpiece
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED, // earpieceControl
                 shouldRunWithFocus
         ));
 
@@ -879,7 +896,7 @@
                 CallAudioRouteStateMachine.SWITCH_BLUETOOTH, // action
                 CallAudioState.ROUTE_BLUETOOTH, // expectedRoute
                 CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH, // expectedAvailable
-                true, // doesDeviceSupportEarpiece
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED, // earpieceControl
                 shouldRunWithFocus
         ));
 
@@ -892,7 +909,7 @@
                 CallAudioRouteStateMachine.SWITCH_BLUETOOTH, // action
                 CallAudioState.ROUTE_BLUETOOTH, // expectedRoute
                 CallAudioState.ROUTE_WIRED_HEADSET | CallAudioState.ROUTE_BLUETOOTH, // expectedAvai
-                true, // doesDeviceSupportEarpiece
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED, // earpieceControl
                 shouldRunWithFocus
         ));
 
@@ -905,7 +922,7 @@
                 CallAudioRouteStateMachine.SWITCH_BASELINE_ROUTE, // action
                 CallAudioState.ROUTE_SPEAKER, // expectedRoute
                 CallAudioState.ROUTE_BLUETOOTH, // expectedAvailableRoutes
-                false, // doesDeviceSupportEarpiece
+                CallAudioRouteStateMachine.EARPIECE_FORCE_DISABLED, // earpieceControl
                 shouldRunWithFocus
         ));
 
@@ -918,7 +935,7 @@
                 CallAudioRouteStateMachine.DISCONNECT_WIRED_HEADSET, // action
                 CallAudioState.ROUTE_SPEAKER, // expectedRoute
                 CallAudioState.ROUTE_SPEAKER, // expectedAvailableRoutes
-                false, // doesDeviceSupportEarpiece
+                CallAudioRouteStateMachine.EARPIECE_FORCE_DISABLED, // earpieceControl
                 shouldRunWithFocus
         ));
 
@@ -931,7 +948,7 @@
                 CallAudioRouteStateMachine.DISCONNECT_WIRED_HEADSET, // action
                 CallAudioState.ROUTE_SPEAKER, // expectedRoute
                 CallAudioState.ROUTE_SPEAKER, // expectedAvailableRoutes
-                true, // doesDeviceSupportEarpiece
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED, // earpieceControl
                 shouldRunWithFocus
         ).setCallSupportedRoutes(CallAudioState.ROUTE_ALL & ~CallAudioState.ROUTE_EARPIECE));
 
@@ -944,7 +961,7 @@
                 CallAudioRouteStateMachine.DISCONNECT_BLUETOOTH, // action
                 CallAudioState.ROUTE_SPEAKER, // expectedRoute
                 CallAudioState.ROUTE_SPEAKER, // expectedAvailableRoutes
-                true, // doesDeviceSupportEarpiece
+                CallAudioRouteStateMachine.EARPIECE_FORCE_ENABLED, // earpieceControl
                 shouldRunWithFocus
         ).setCallSupportedRoutes(CallAudioState.ROUTE_ALL & ~CallAudioState.ROUTE_EARPIECE));
 
@@ -973,7 +990,7 @@
                 mockWiredHeadsetManager,
                 mockStatusBarNotifier,
                 mAudioServiceFactory,
-                params.doesDeviceSupportEarpiece);
+                params.earpieceControl);
 
         setupMocksForParams(stateMachine, params);
 
@@ -1086,7 +1103,7 @@
                 mockWiredHeadsetManager,
                 mockStatusBarNotifier,
                 mAudioServiceFactory,
-                params.doesDeviceSupportEarpiece);
+                params.earpieceControl);
 
         // Set up bluetooth and speakerphone state
         when(mockBluetoothRouteManager.isBluetoothAvailable()).thenReturn(
diff --git a/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java b/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
index f4f83e3..27202cf 100644
--- a/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
+++ b/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
@@ -355,6 +355,14 @@
         }
 
         @Override
+        public void connectionServiceFocusLost(Session.Info sessionInfo) throws RemoteException {
+        }
+
+        @Override
+        public void connectionServiceFocusGained(Session.Info sessionInfo) throws RemoteException {
+        }
+
+        @Override
         public IBinder asBinder() {
             return this;
         }
diff --git a/tests/src/com/android/server/telecom/tests/ConnectionServiceFocusManagerTest.java b/tests/src/com/android/server/telecom/tests/ConnectionServiceFocusManagerTest.java
new file mode 100644
index 0000000..affa4e9
--- /dev/null
+++ b/tests/src/com/android/server/telecom/tests/ConnectionServiceFocusManagerTest.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright 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.os.Looper;
+import android.test.suitebuilder.annotation.SmallTest;
+import com.android.server.telecom.Call;
+import com.android.server.telecom.CallState;
+import com.android.server.telecom.CallsManager;
+import com.android.server.telecom.ConnectionServiceFocusManager;
+import com.android.server.telecom.ConnectionServiceFocusManager.*;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class ConnectionServiceFocusManagerTest extends TelecomTestCase {
+
+    @Mock CallsManagerRequester mockCallsManagerRequester;
+    @Mock RequestFocusCallback mockRequestFocusCallback;
+
+    @Mock ConnectionServiceFocus mNewConnectionService;
+    @Mock ConnectionServiceFocus mActiveConnectionService;
+
+    private static final int CHECK_HANDLER_INTERVAL_MS = 10;
+
+    private ConnectionServiceFocusManager mFocusManagerUT;
+    private CallFocus mNewCall;
+    private CallFocus mActiveCall;
+    private CallsManager.CallsManagerListener mCallsManagerListener;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mFocusManagerUT = new ConnectionServiceFocusManager(
+                mockCallsManagerRequester, Looper.getMainLooper());
+        mNewCall = createFakeCall(mNewConnectionService, CallState.NEW);
+        mActiveCall = createFakeCall(mActiveConnectionService, CallState.ACTIVE);
+        ArgumentCaptor<CallsManager.CallsManagerListener> captor =
+                ArgumentCaptor.forClass(CallsManager.CallsManagerListener.class);
+        verify(mockCallsManagerRequester).setCallsManagerListener(captor.capture());
+        mCallsManagerListener = captor.getValue();
+    }
+
+    @SmallTest
+    public void testRequestFocusWithoutActiveFocusExisted() {
+        // GIVEN the ConnectionServiceFocusManager without focus ConnectionService.
+
+        // WHEN request calling focus for the given call.
+        requestFocus(mNewCall, mockRequestFocusCallback);
+
+        // THEN the request is done and the ConnectionService of the given call has gain the focus.
+        verifyRequestFocusDone(mFocusManagerUT, mNewCall, mockRequestFocusCallback, true);
+    }
+
+    @SmallTest
+    public void testRequestFocusWithActiveFocusExisted() {
+        // GIVEN the ConnectionServiceFocusManager with the focus ConnectionService.
+        requestFocus(mActiveCall, null);
+        ConnectionServiceFocusListener connSvrFocusListener =
+                getConnectionServiceFocusListener(mActiveConnectionService);
+
+        // WHEN request calling focus for the given call.
+        requestFocus(mNewCall, mockRequestFocusCallback);
+
+        // THEN the current focus ConnectionService is informed it has lose the focus.
+        verify(mActiveConnectionService).connectionServiceFocusLost();
+        // and the focus request is not done.
+        verify(mockRequestFocusCallback, never())
+                .onRequestFocusDone(any(CallFocus.class));
+
+        // WHEN the current focus released the call resource.
+        connSvrFocusListener.onConnectionServiceReleased(mActiveConnectionService);
+        waitForHandlerAction(mFocusManagerUT.getHandler(), CHECK_HANDLER_INTERVAL_MS);
+
+        // THEN the request is done and the ConnectionService of the given call has gain the focus.
+        verifyRequestFocusDone(mFocusManagerUT, mNewCall, mockRequestFocusCallback, true);
+
+        // and the timeout event of the focus released is canceled.
+        waitForHandlerActionDelayed(
+                mFocusManagerUT.getHandler(),
+                mFocusManagerUT.RELEASE_FOCUS_TIMEOUT_MS,
+                CHECK_HANDLER_INTERVAL_MS);
+        verify(mockCallsManagerRequester, never()).releaseConnectionService(
+                any(ConnectionServiceFocus.class));
+    }
+
+    @SmallTest
+    public void testRequestConnectionServiceSameAsFocusConnectionService() {
+        // GIVEN the ConnectionServiceFocusManager with the focus ConnectionService.
+        requestFocus(mActiveCall, null);
+        reset(mActiveConnectionService);
+
+        // WHEN request calling focus for the given call that has the same ConnectionService as the
+        // active call.
+        when(mNewCall.getConnectionServiceWrapper()).thenReturn(mActiveConnectionService);
+        requestFocus(mNewCall, mockRequestFocusCallback);
+
+        // THEN the request is done without any change on the focus ConnectionService.
+        verify(mNewConnectionService, never()).connectionServiceFocusLost();
+        verifyRequestFocusDone(mFocusManagerUT, mNewCall, mockRequestFocusCallback, false);
+    }
+
+    @SmallTest
+    public void testFocusConnectionServiceDoesNotRespondToFocusLost() {
+        // GIVEN the ConnectionServiceFocusManager with the focus ConnectionService.
+        requestFocus(mActiveCall, null);
+
+        // WHEN request calling focus for the given call.
+        requestFocus(mNewCall, mockRequestFocusCallback);
+
+        // THEN the current focus ConnectionService is informed it has lose the focus.
+        verify(mActiveConnectionService).connectionServiceFocusLost();
+        // and the focus request is not done.
+        verify(mockRequestFocusCallback, never())
+                .onRequestFocusDone(any(CallFocus.class));
+
+        // but the current focus ConnectionService didn't respond to the focus lost.
+        waitForHandlerActionDelayed(
+                mFocusManagerUT.getHandler(),
+                CHECK_HANDLER_INTERVAL_MS,
+                mFocusManagerUT.RELEASE_FOCUS_TIMEOUT_MS + 100);
+
+        // THEN the focusManager sends a request to disconnect the focus ConnectionService
+        verify(mockCallsManagerRequester).releaseConnectionService(mActiveConnectionService);
+        // THEN the request is done and the ConnectionService of the given call has gain the focus.
+        verifyRequestFocusDone(mFocusManagerUT, mNewCall, mockRequestFocusCallback, true);
+    }
+
+    @SmallTest
+    public void testNonFocusConnectionServiceReleased() {
+        // GIVEN the ConnectionServiceFocusManager with the focus ConnectionService
+        requestFocus(mActiveCall, null);
+        ConnectionServiceFocusListener connSvrFocusListener =
+                getConnectionServiceFocusListener(mActiveConnectionService);
+
+        // WHEN there is a released request for a non focus ConnectionService.
+        connSvrFocusListener.onConnectionServiceReleased(mNewConnectionService);
+
+        // THEN nothing changed.
+        assertEquals(mActiveCall, mFocusManagerUT.getCurrentFocusCall());
+        assertEquals(mActiveConnectionService, mFocusManagerUT.getCurrentFocusConnectionService());
+    }
+
+    @SmallTest
+    public void testFocusConnectionServiceReleased() {
+        // GIVEN the ConnectionServiceFocusManager with the focus ConnectionService
+        requestFocus(mActiveCall, null);
+        ConnectionServiceFocusListener connSvrFocusListener =
+                getConnectionServiceFocusListener(mActiveConnectionService);
+
+        // WHEN the focus ConnectionService request to release.
+        connSvrFocusListener.onConnectionServiceReleased(mActiveConnectionService);
+        waitForHandlerAction(mFocusManagerUT.getHandler(), CHECK_HANDLER_INTERVAL_MS);
+
+        // THEN both focus call and ConnectionService are null.
+        assertNull(mFocusManagerUT.getCurrentFocusCall());
+        assertNull(mFocusManagerUT.getCurrentFocusConnectionService());
+    }
+
+    @SmallTest
+    public void testCallStateChangedAffectCallFocus() {
+        // GIVEN the ConnectionServiceFocusManager with the focus ConnectionService.
+        CallFocus activeCall = createFakeCall(mActiveConnectionService, CallState.ACTIVE);
+        CallFocus newActivateCall = createFakeCall(mActiveConnectionService, CallState.ACTIVE);
+        requestFocus(activeCall, null);
+
+        // WHEN hold the active call.
+        int previousState = activeCall.getState();
+        when(activeCall.getState()).thenReturn(CallState.ON_HOLD);
+        mCallsManagerListener.onCallStateChanged(
+                (Call) activeCall, previousState, activeCall.getState());
+        waitForHandlerAction(mFocusManagerUT.getHandler(), CHECK_HANDLER_INTERVAL_MS);
+
+        // THEN the focus call is null
+        assertNull(mFocusManagerUT.getCurrentFocusCall());
+        // and the focus ConnectionService is not changed.
+        assertEquals(mActiveConnectionService, mFocusManagerUT.getCurrentFocusConnectionService());
+
+        // WHEN a new active call is added.
+        when(newActivateCall.getState()).thenReturn(CallState.ACTIVE);
+        mCallsManagerListener.onCallAdded((Call) newActivateCall);
+        waitForHandlerAction(mFocusManagerUT.getHandler(), CHECK_HANDLER_INTERVAL_MS);
+
+        // THEN the focus call changed as excepted.
+        assertEquals(newActivateCall, mFocusManagerUT.getCurrentFocusCall());
+    }
+
+    @SmallTest
+    public void testCallStateChangedDoesNotAffectCallFocusIfConnectionServiceIsDifferent() {
+        // GIVEN the ConnectionServiceFocusManager with the focus ConnectionService
+        requestFocus(mActiveCall, null);
+
+        // WHEN a new active call is added (actually this should not happen).
+        when(mNewCall.getState()).thenReturn(CallState.ACTIVE);
+        mCallsManagerListener.onCallAdded((Call) mNewCall);
+
+        // THEN the call focus isn't changed.
+        assertEquals(mActiveCall, mFocusManagerUT.getCurrentFocusCall());
+
+        // WHEN the hold the active call.
+        when(mActiveCall.getState()).thenReturn(CallState.ON_HOLD);
+        mCallsManagerListener.onCallStateChanged(
+                (Call) mActiveCall, CallState.ACTIVE, CallState.ON_HOLD);
+        waitForHandlerAction(mFocusManagerUT.getHandler(), CHECK_HANDLER_INTERVAL_MS);
+
+        // THEN the focus call is null.
+        assertNull(mFocusManagerUT.getCurrentFocusCall());
+    }
+
+    @SmallTest
+    public void testFocusCallIsNullWhenRemoveTheFocusCall() {
+        // GIVEN the ConnectionServiceFocusManager with the focus ConnectionService
+        requestFocus(mActiveCall, null);
+        assertEquals(mActiveCall, mFocusManagerUT.getCurrentFocusCall());
+
+        // WHEN remove the active call
+        mCallsManagerListener.onCallRemoved((Call) mActiveCall);
+        waitForHandlerAction(mFocusManagerUT.getHandler(), CHECK_HANDLER_INTERVAL_MS);
+
+        // THEN the focus call is null
+        assertNull(mFocusManagerUT.getCurrentFocusCall());
+    }
+
+    @SmallTest
+    public void testConnectionServiceFocusDeath() {
+        // GIVEN the ConnectionServiceFocusManager with the focus ConnectionService
+        requestFocus(mActiveCall, null);
+        ConnectionServiceFocusListener connSvrFocusListener =
+                getConnectionServiceFocusListener(mActiveConnectionService);
+
+        // WHEN the active connection service focus is death
+        connSvrFocusListener.onConnectionServiceDeath(mActiveConnectionService);
+        waitForHandlerAction(mFocusManagerUT.getHandler(), CHECK_HANDLER_INTERVAL_MS);
+
+        // THEN both connection service focus and call focus are null.
+        assertNull(mFocusManagerUT.getCurrentFocusConnectionService());
+        assertNull(mFocusManagerUT.getCurrentFocusCall());
+    }
+
+    @SmallTest
+    public void testNonExternalCallChangedToExternalCall() {
+        // GIVEN the ConnectionServiceFocusManager with the focus ConnectionService.
+        requestFocus(mActiveCall, null);
+        assertTrue(mFocusManagerUT.getAllCall().contains(mActiveCall));
+
+        // WHEN the non-external call changed to external call
+        mCallsManagerListener.onExternalCallChanged((Call) mActiveCall, true);
+        waitForHandlerAction(mFocusManagerUT.getHandler(), CHECK_HANDLER_INTERVAL_MS);
+
+        // THEN the call should be removed as it's an external call now.
+        assertFalse(mFocusManagerUT.getAllCall().contains(mActiveCall));
+    }
+
+    @SmallTest
+    public void testExternalCallChangedToNonExternalCall() {
+        // GIVEN the ConnectionServiceFocusManager without focus ConnectionService
+
+        // WHEN an external call changed to external call
+        mCallsManagerListener.onExternalCallChanged((Call) mActiveCall, false);
+        waitForHandlerAction(mFocusManagerUT.getHandler(), CHECK_HANDLER_INTERVAL_MS);
+
+        // THEN the call should be added as it's a non-external call now.
+        assertTrue(mFocusManagerUT.getAllCall().contains(mActiveCall));
+    }
+
+    private void requestFocus(CallFocus call, RequestFocusCallback callback) {
+        mCallsManagerListener.onCallAdded((Call) call);
+        mFocusManagerUT.requestFocus(call, callback);
+        waitForHandlerAction(mFocusManagerUT.getHandler(), CHECK_HANDLER_INTERVAL_MS);
+    }
+
+    private static void verifyRequestFocusDone(
+            ConnectionServiceFocusManager focusManager,
+            CallFocus call,
+            RequestFocusCallback callback,
+            boolean isConnectionServiceFocusChanged) {
+        verify(callback).onRequestFocusDone(call);
+        verify(call.getConnectionServiceWrapper(), times(isConnectionServiceFocusChanged ? 1 : 0))
+                .connectionServiceFocusGained();
+        assertEquals(
+                call.getConnectionServiceWrapper(),
+                focusManager.getCurrentFocusConnectionService());
+    }
+
+    /**
+     * Returns the {@link ConnectionServiceFocusListener} of the ConnectionServiceFocusManager.
+     * Make sure the given parameter {@code ConnectionServiceFocus} is a mock object and
+     * {@link ConnectionServiceFocus#setConnectionServiceFocusListener(
+     * ConnectionServiceFocusListener)} is called.
+     */
+    private static ConnectionServiceFocusListener getConnectionServiceFocusListener(
+            ConnectionServiceFocus connSvrFocus) {
+        ArgumentCaptor<ConnectionServiceFocusListener> captor =
+                ArgumentCaptor.forClass(ConnectionServiceFocusListener.class);
+        verify(connSvrFocus).setConnectionServiceFocusListener(captor.capture());
+        return captor.getValue();
+    }
+
+    private static Call createFakeCall(ConnectionServiceFocus connSvr, int state) {
+        Call call = Mockito.mock(Call.class);
+        when(call.getConnectionServiceWrapper()).thenReturn(connSvr);
+        when(call.getState()).thenReturn(state);
+        return call;
+    }
+}
diff --git a/tests/src/com/android/server/telecom/tests/TelecomTestCase.java b/tests/src/com/android/server/telecom/tests/TelecomTestCase.java
index b735df9..1892b99 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomTestCase.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomTestCase.java
@@ -58,4 +58,16 @@
             }
         }
     }
+
+    protected final void waitForHandlerActionDelayed(Handler h, long timeoutMillis, long delayMs) {
+        final CountDownLatch lock = new CountDownLatch(1);
+        h.postDelayed(lock::countDown, delayMs);
+        while (lock.getCount() > 0) {
+            try {
+                lock.await(timeoutMillis, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                // do nothing
+            }
+        }
+    }
 }