Merge "Implement call filters part of the missed call information."
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 02bd056..2e14650 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -15,7 +15,9 @@
"exclude-annotation": "androidx.test.filters.FlakyTest"
}
]
- },
+ }
+ ],
+ "presubmit-large": [
{
"name": "CtsTelecomTestCases",
"options": [
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index e157655..bd87d66 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -57,9 +57,9 @@
<string name="change_default_dialer_dialog_affirmative" msgid="8604665314757739550">"デフォルトに設定"</string>
<string name="change_default_dialer_dialog_negative" msgid="8648669840052697821">"キャンセル"</string>
<string name="change_default_dialer_warning_message" msgid="8461963987376916114">"<xliff:g id="NEW_APP">%s</xliff:g> はすべての通話の発信や制御を行えるようになります。デフォルトの電話アプリに設定するのは信頼できるアプリだけにしてください。"</string>
- <string name="change_default_call_screening_dialog_title" msgid="5365787219927262408">"<xliff:g id="NEW_APP">%s</xliff:g> をデフォルトのコール スクリーニング アプリにしますか?"</string>
+ <string name="change_default_call_screening_dialog_title" msgid="5365787219927262408">"<xliff:g id="NEW_APP">%s</xliff:g> をデフォルトの通話スクリーニング アプリにしますか?"</string>
<string name="change_default_call_screening_warning_message_for_disable_old_app" msgid="2039830033533243164">"<xliff:g id="OLD_APP">%s</xliff:g> では通話をスクリーニングできなくなります。"</string>
- <string name="change_default_call_screening_warning_message" msgid="9020537562292754269">"<xliff:g id="NEW_APP">%s</xliff:g> をデフォルトにすると、連絡先に登録されていない発信者の情報を確認したり、そのような発信者からの通話をブロックしたりできるようになります。デフォルトのコール スクリーニング アプリに設定するのは信頼できるアプリだけにしてください。"</string>
+ <string name="change_default_call_screening_warning_message" msgid="9020537562292754269">"<xliff:g id="NEW_APP">%s</xliff:g> をデフォルトにすると、連絡先に登録されていない発信者の情報を確認したり、そのような発信者からの通話をブロックしたりできるようになります。デフォルトの通話スクリーニング アプリに設定するのは信頼できるアプリだけにしてください。"</string>
<string name="change_default_call_screening_dialog_affirmative" msgid="7162433828280058647">"デフォルトに設定"</string>
<string name="change_default_call_screening_dialog_negative" msgid="1839266125623106342">"キャンセル"</string>
<string name="blocked_numbers" msgid="8322134197039865180">"ブロックした番号"</string>
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
index 23c8033..99e211f 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -44,7 +44,7 @@
<string name="respond_via_sms_setting_summary" msgid="8054571501085436868"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="6579353156073272157">"Брз одговор"</string>
<string name="respond_via_sms_confirmation_format" msgid="2932395476561267842">"Порака е испратена на <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
- <string name="respond_via_sms_failure_format" msgid="5198680980054596391">"Пораката не можеше да се испрати на <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
+ <string name="respond_via_sms_failure_format" msgid="5198680980054596391">"Пораката не може да се испрати на <xliff:g id="PHONE_NUMBER">%s</xliff:g>."</string>
<string name="enable_account_preference_title" msgid="6949224486748457976">"Сметки за повици"</string>
<string name="outgoing_call_not_allowed_user_restriction" msgid="3424338207838851646">"Дозволени се само итни повици."</string>
<string name="outgoing_call_not_allowed_no_permission" msgid="8590468836581488679">"Оваа апликација не може да прави појдовни повици без дозволата Телефон."</string>
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
index c941fdd..cdef26b 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/strings.xml
@@ -25,7 +25,7 @@
<string name="notification_missedCallsMsg" msgid="5055782736170916682">"<xliff:g id="NUM_MISSED_CALLS">%s</xliff:g> аваагүй дуудлага"</string>
<string name="notification_missedCallTicker" msgid="6731461957487087769">"<xliff:g id="MISSED_CALL_FROM">%s</xliff:g>-н аваагүй дуудлага"</string>
<string name="notification_missedCall_call_back" msgid="7900333283939789732">"Буцааж залгах"</string>
- <string name="notification_missedCall_message" msgid="4054698824390076431">"Мессэж"</string>
+ <string name="notification_missedCall_message" msgid="4054698824390076431">"Мессеж"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"Дуудлага саллаа"</string>
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"Яаралтай дуудлага ирсэн тул <xliff:g id="CALLER">%s</xliff:g> руу хийсэн дуудлагыг салгалаа."</string>
<string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"Яаралтай дуудлага ирсэн тул таны дуудлагыг салгалаа."</string>
@@ -43,8 +43,8 @@
<string name="respond_via_sms_setting_title_2" msgid="4914853536609553457">"Шуурхай хариуг засах"</string>
<string name="respond_via_sms_setting_summary" msgid="8054571501085436868"></string>
<string name="respond_via_sms_edittext_dialog_title" msgid="6579353156073272157">"Шуурхай хариу"</string>
- <string name="respond_via_sms_confirmation_format" msgid="2932395476561267842">"Зурвасыг <xliff:g id="PHONE_NUMBER">%s</xliff:g> руу илгээв."</string>
- <string name="respond_via_sms_failure_format" msgid="5198680980054596391">"<xliff:g id="PHONE_NUMBER">%s</xliff:g> руу зурвас илгээж чадсангүй."</string>
+ <string name="respond_via_sms_confirmation_format" msgid="2932395476561267842">"Мессежийг <xliff:g id="PHONE_NUMBER">%s</xliff:g> руу илгээв."</string>
+ <string name="respond_via_sms_failure_format" msgid="5198680980054596391">"<xliff:g id="PHONE_NUMBER">%s</xliff:g> руу мессеж илгээж чадсангүй."</string>
<string name="enable_account_preference_title" msgid="6949224486748457976">"Дуудлагын эрхтэй бүртгэлүүд"</string>
<string name="outgoing_call_not_allowed_user_restriction" msgid="3424338207838851646">"Зөвхөн яаралтай тусламжийн дуудлага хийх боломжтой."</string>
<string name="outgoing_call_not_allowed_no_permission" msgid="8590468836581488679">"Энэ апп нь утасны зөвшөөрөлгүйгээр дуудлага хийх боломжгүй."</string>
@@ -71,11 +71,11 @@
<string name="add_blocked_number_hint" msgid="8769422085658041097">"Утасны дугаар"</string>
<string name="block_button" msgid="485080149164258770">"Блоклох"</string>
<string name="non_primary_user" msgid="315564589279622098">"Зөвхөн энэ төхөөрөмжийн эзэн блоклосон дугаарыг харж, өөрчлөх боломжтой."</string>
- <string name="delete_icon_description" msgid="5335959254954774373">"Хоригийг тайлах"</string>
+ <string name="delete_icon_description" msgid="5335959254954774373">"Блокоос гаргах"</string>
<string name="blocked_numbers_butter_bar_title" msgid="582982373755950791">"Дугаар хориглох түр хугацаанд идэвхгүй болсон"</string>
<string name="blocked_numbers_butter_bar_body" msgid="1261213114919301485">"Түргэн тусламжийн дугаар руу залгах буюу мессеж бичсэний дараа түргэн тусламжаас тантай холбогдох боломжтой байлгахын тулд дугаар хориглохыг идэвхгүй болгоно."</string>
<string name="blocked_numbers_butter_bar_button" msgid="2704456308072489793">"Одоо дахин идэвхжүүлэх"</string>
- <string name="blocked_numbers_number_blocked_message" msgid="4314736791180919167">"<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g>-г хориглосон"</string>
+ <string name="blocked_numbers_number_blocked_message" msgid="4314736791180919167">"<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g>-г блоклосон"</string>
<string name="blocked_numbers_number_unblocked_message" msgid="2933071624674945601">"<xliff:g id="UNBLOCKED_NUMBER">%1$s</xliff:g>-г блокоос гаргасан"</string>
<string name="blocked_numbers_block_emergency_number_message" msgid="4198550501500893890">"Яаралтай дугаарыг хориглох боломжгүй."</string>
<string name="blocked_numbers_number_already_blocked_message" msgid="2301270825735665458">"<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g>-г аль хэдийн хориглосон байна."</string>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index 3b87593..331cf5c 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -30,7 +30,7 @@
<string name="notification_disconnectedCall_body" msgid="600491714584417536">"आणीबाणी कॉल केल्यामुळे <xliff:g id="CALLER">%s</xliff:g> ला केलेला कॉल डिस्कनेक्ट केला गेला."</string>
<string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"आणीबाणी कॉल केल्यामुळे तुमचा कॉल डिस्कनेक्ट केला गेला आहे."</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"बॅकग्राउंड कॉल"</string>
- <string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> यांनी कॉल बॅकग्राउंडवर ठेवला आहे हे ॲप कदाचित कॉलद्वारे ऑडिओ ॲक्सेस आणि प्ले करत आहे."</string>
+ <string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> यांनी कॉल बॅकग्राउंडवर ठेवला आहे हे अॅप कदाचित कॉलद्वारे ऑडिओ ॲक्सेस आणि प्ले करत आहे."</string>
<string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> ने प्रतिसाद देणे थांबवले आहे"</string>
<string name="notification_incallservice_not_responding_body" msgid="9209308270131968623">"तुमच्या कॉलने डिव्हाइससोबत दिलेले फोन अॅप वापरले आहे"</string>
<string name="accessibility_call_muted" msgid="2968461092554300779">"कॉल नि.शब्द केला."</string>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index e65fa1d..1e2b32f 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -27,8 +27,8 @@
<string name="notification_missedCall_call_back" msgid="7900333283939789732">"फेरि कल गर्नुहोस्"</string>
<string name="notification_missedCall_message" msgid="4054698824390076431">"सन्देश"</string>
<string name="notification_disconnectedCall_title" msgid="1790131923692416928">"विच्छेद गरिएको कल"</string>
- <string name="notification_disconnectedCall_body" msgid="600491714584417536">"आपत्कालीन कल गरिएको हुनाले <xliff:g id="CALLER">%s</xliff:g> लाई गरिएको कल विच्छेद गरियो।"</string>
- <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"आपत्कालीन कल जारी रहेको हुनाले तपाईंको कल विच्छेद गरिएको छ।"</string>
+ <string name="notification_disconnectedCall_body" msgid="600491714584417536">"आपत्कालीन कल गरिएको हुनाले <xliff:g id="CALLER">%s</xliff:g> लाई गरिएको कल विच्छेद गरियो।"</string>
+ <string name="notification_disconnectedCall_generic_body" msgid="5282765206349184853">"आपत्कालीन कल जारी रहेको हुनाले तपाईंको कल विच्छेद गरिएको छ।"</string>
<string name="notification_audioProcessing_title" msgid="1619035039880584575">"पृष्ठभूमिको कल"</string>
<string name="notification_audioProcessing_body" msgid="6397005913770420388">"<xliff:g id="AUDIO_PROCESSING_APP_NAME">%s</xliff:g> ले एउटा कल पृष्ठभूमिमा राखेको छ। कल गरेको बेला यो अनुप्रयोगले अडियोमाथि पहुँच राखेर प्ले गरिरहेको हुन सक्छ।"</string>
<string name="notification_incallservice_not_responding_title" msgid="5347557574288598548">"<xliff:g id="IN_CALL_SERVICE_APP_NAME">%s</xliff:g> ले काम गर्न छाड्यो"</string>
@@ -46,7 +46,7 @@
<string name="respond_via_sms_confirmation_format" msgid="2932395476561267842">"<xliff:g id="PHONE_NUMBER">%s</xliff:g> लाई सन्देश पठाइयो।"</string>
<string name="respond_via_sms_failure_format" msgid="5198680980054596391">"<xliff:g id="PHONE_NUMBER">%s</xliff:g> मा सन्देश पठाउन सकिएन।"</string>
<string name="enable_account_preference_title" msgid="6949224486748457976">"कलिङ खाताहरू"</string>
- <string name="outgoing_call_not_allowed_user_restriction" msgid="3424338207838851646">"आपतकालीन कलहरूलाई मात्र अनुमति दिइएको छ।"</string>
+ <string name="outgoing_call_not_allowed_user_restriction" msgid="3424338207838851646">"आपत्कालीन कलहरूलाई मात्र अनुमति दिइएको छ।"</string>
<string name="outgoing_call_not_allowed_no_permission" msgid="8590468836581488679">"यो अनुप्रयोगले फोनको अनुमति बिना बहिर्गमन कलहरू गर्न सक्दैन।"</string>
<string name="outgoing_call_error_no_phone_number_supplied" msgid="7665135102566099778">"एक कल गर्नको लागि, एक वैध नम्बर प्रविष्टि गर्नुहोस्।"</string>
<string name="duplicate_video_call_not_allowed" msgid="5754746140185781159">"यस समयमा कल थप गर्न सकिँदैन।"</string>
@@ -56,14 +56,14 @@
<string name="change_default_dialer_dialog_title" msgid="5861469279421508060">"तपाईंको पूर्वनिर्धारित फोन एप <xliff:g id="NEW_APP">%s</xliff:g> बनाउने हो?"</string>
<string name="change_default_dialer_dialog_affirmative" msgid="8604665314757739550">"पूर्वनिर्धारित रूपमा सेट गर्नुहोस्"</string>
<string name="change_default_dialer_dialog_negative" msgid="8648669840052697821">"रद्द गर्नुहोस्"</string>
- <string name="change_default_dialer_warning_message" msgid="8461963987376916114">"<xliff:g id="NEW_APP">%s</xliff:g> कलका सबै पक्षहरूलाई स्थापित गर्न र नियन्त्रण गर्न सक्षम हुने छ। तपाईंलाई विश्वास लाग्ने अनुप्रयोगहरूलाई मात्र फोनमा पूर्वनिर्धारित अनुप्रयोगका रूपमा सेट गर्नुपर्छ।"</string>
+ <string name="change_default_dialer_warning_message" msgid="8461963987376916114">"<xliff:g id="NEW_APP">%s</xliff:g> कलका सबै पक्षहरूलाई स्थापित गर्न र नियन्त्रण गर्न सक्षम हुने छ। तपाईंलाई विश्वास लाग्ने एपहरूलाई मात्र फोनमा पूर्वनिर्धारित एपका रूपमा सेट गर्नुपर्छ।"</string>
<string name="change_default_call_screening_dialog_title" msgid="5365787219927262408">"तपाईंको पूर्वनिर्धारित कल स्क्रिन एप <xliff:g id="NEW_APP">%s</xliff:g> बनाउने हो?"</string>
<string name="change_default_call_screening_warning_message_for_disable_old_app" msgid="2039830033533243164">"<xliff:g id="OLD_APP">%s</xliff:g> ले अब उप्रान्त कलहरू स्क्रिन गर्न सक्ने छैनन्।"</string>
- <string name="change_default_call_screening_warning_message" msgid="9020537562292754269">"<xliff:g id="NEW_APP">%s</xliff:g> ले तपाईंको सम्पर्कमा नभएका कल गर्ने व्यक्तिका जानकारी हेर्न सक्छ र तिनीहरूमाथि रोक लगाउन सक्छ। तपाईंलाई विश्वास लाग्ने अनुप्रयोगहरूलाई मात्र कल स्क्रिन पूर्वनिर्धारित अनुप्रयोगका रूपमा सेट गर्नुपर्छ।"</string>
+ <string name="change_default_call_screening_warning_message" msgid="9020537562292754269">"<xliff:g id="NEW_APP">%s</xliff:g> ले तपाईंको सम्पर्कमा नभएका कल गर्ने व्यक्तिका जानकारी हेर्न सक्छ र तिनीहरूमाथि रोक लगाउन सक्छ। तपाईंलाई विश्वास लाग्ने एपहरूलाई मात्र कल स्क्रिन पूर्वनिर्धारित एपका रूपमा सेट गर्नुपर्छ।"</string>
<string name="change_default_call_screening_dialog_affirmative" msgid="7162433828280058647">"पूर्वनिर्धारित रूपमा सेट गर्नुहोस्"</string>
<string name="change_default_call_screening_dialog_negative" msgid="1839266125623106342">"रद्द गर्नुहोस्"</string>
<string name="blocked_numbers" msgid="8322134197039865180">"रोकिएका नम्बरहरू"</string>
- <string name="blocked_numbers_msg" msgid="2797422132329662697">"तपाईँले रोक लगाइएका नम्बरहरूबाट फोन वा पाठ सन्देशहरू प्राप्त गर्नुहुने छैन।"</string>
+ <string name="blocked_numbers_msg" msgid="2797422132329662697">"तपाईँले रोक लगाइएका नम्बरहरूबाट फोन वा टेक्स्ट म्यासेजहरू प्राप्त गर्नुहुने छैन।"</string>
<string name="block_number" msgid="3784343046852802722">"नम्बर थप्नुहोस्"</string>
<string name="unblock_dialog_body" msgid="2723393535797217261">"<xliff:g id="NUMBER_TO_BLOCK">%1$s</xliff:g> लाई अनब्लक गर्ने हो?"</string>
<string name="unblock_button" msgid="8732021675729981781">"अनब्लक गर्नुहोस्"</string>
@@ -73,11 +73,11 @@
<string name="non_primary_user" msgid="315564589279622098">"यन्त्रको मालिकले रोकिएका नम्बरहरूलाई हेर्न र व्यवस्थापन गर्न सक्छ।"</string>
<string name="delete_icon_description" msgid="5335959254954774373">"अनब्लक गर्नुहोस्"</string>
<string name="blocked_numbers_butter_bar_title" msgid="582982373755950791">"रोक लगाउने काम अस्थायी रूपमा निष्क्रिय छ"</string>
- <string name="blocked_numbers_butter_bar_body" msgid="1261213114919301485">"तपाईँले आपतकालीन नम्बरमा डायल गरेपछि वा पाठ सन्देश पठाएपछि आपतकालीन सेवाहरूले तपाईँलाई सम्पर्क गर्न सकून् भन्ने कुरा सुनिश्चित गर्न कलमाथिको अवरोध निष्क्रिय गरिन्छ।"</string>
+ <string name="blocked_numbers_butter_bar_body" msgid="1261213114919301485">"तपाईँले आपत्कालीन नम्बरमा डायल गरेपछि वा पाठ सन्देश पठाएपछि आपत्कालीन सेवाहरूले तपाईँलाई सम्पर्क गर्न सकून् भन्ने कुरा सुनिश्चित गर्न कलमाथिको अवरोध निष्क्रिय गरिन्छ।"</string>
<string name="blocked_numbers_butter_bar_button" msgid="2704456308072489793">"अब पुन:-सक्रिय गर्नुहोस्"</string>
<string name="blocked_numbers_number_blocked_message" msgid="4314736791180919167">"<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g> माथि रोक लगाइयो"</string>
<string name="blocked_numbers_number_unblocked_message" msgid="2933071624674945601">"<xliff:g id="UNBLOCKED_NUMBER">%1$s</xliff:g> माथिको रोक हटाइयो"</string>
- <string name="blocked_numbers_block_emergency_number_message" msgid="4198550501500893890">"आपतकालीन नम्बरमाथि रोक लगाउन सकिएन।"</string>
+ <string name="blocked_numbers_block_emergency_number_message" msgid="4198550501500893890">"आपत्कालीन नम्बरमाथि रोक लगाउन सकिएन।"</string>
<string name="blocked_numbers_number_already_blocked_message" msgid="2301270825735665458">"<xliff:g id="BLOCKED_NUMBER">%1$s</xliff:g> लाई पहिले नै रोकिएको छ।"</string>
<string name="toast_personal_call_msg" msgid="5817631570381795610">"कल गर्न व्यक्तिगत डायलर प्रयोग गर्दै"</string>
<string name="notification_incoming_call" msgid="1233481138362230894">"<xliff:g id="CALL_FROM">%2$s</xliff:g> ले गरेको <xliff:g id="CALL_VIA">%1$s</xliff:g> कल"</string>
@@ -116,8 +116,8 @@
<string name="phone_settings_unknown_summary_txt" msgid="5446657192535779645">"अज्ञात कल गर्ने व्यक्तिहरूको कलमाथि रोक लगाउनुहोस्"</string>
<string name="phone_strings_call_blocking_turned_off_notification_title_txt" msgid="2895809176537908791">"कलमाथि रोक लगाउने सुविधा"</string>
<string name="phone_strings_call_blocking_turned_off_notification_text_txt" msgid="1713632946174016619">"कलमाथि रोक लगाउने सुविधालाई असक्षम पारियो"</string>
- <string name="phone_strings_emergency_call_made_dialog_title_txt" msgid="6629412508584507377">"आपतकालीन कल गरियो"</string>
- <string name="phone_strings_emergency_call_made_dialog_call_blocking_text_txt" msgid="3140411733995271126">"आपतकालीन अवस्थामा उद्दार गर्ने मान्छेहरूलाई तपाईंलाई सम्पर्क गर्न दिन कलमाथि रोक लगाउने सुविधा असक्षम पारिएको छ।"</string>
+ <string name="phone_strings_emergency_call_made_dialog_title_txt" msgid="6629412508584507377">"आपत्कालीन कल गरियो"</string>
+ <string name="phone_strings_emergency_call_made_dialog_call_blocking_text_txt" msgid="3140411733995271126">"आपत्कालीन अवस्थामा उद्दार गर्ने मान्छेहरूलाई तपाईंलाई सम्पर्क गर्न दिन कलमाथि रोक लगाउने सुविधा असक्षम पारिएको छ।"</string>
<string name="developer_title" msgid="9146088855661672353">"टेलिकमको विकासकर्ताको मेनु"</string>
- <string name="toast_emergency_can_not_pull_call" msgid="9074229465338410869">"आपत्कालीन कल चलिराखेको बेलामा अरु कल स्वीकार गर्न सकिँदैन।"</string>
+ <string name="toast_emergency_can_not_pull_call" msgid="9074229465338410869">"आपत्कालीन कल चलिराखेको बेलामा अरु कल स्वीकार गर्न सकिँदैन।"</string>
</resources>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index d59fc79..70c4566 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -57,9 +57,9 @@
<string name="change_default_dialer_dialog_affirmative" msgid="8604665314757739550">"Ange standard"</string>
<string name="change_default_dialer_dialog_negative" msgid="8648669840052697821">"Avbryt"</string>
<string name="change_default_dialer_warning_message" msgid="8461963987376916114">"<xliff:g id="NEW_APP">%s</xliff:g> kan ringa och styra allt omkring samtal. Endast appar du litar på bör ställas in som standardtelefonapp."</string>
- <string name="change_default_call_screening_dialog_title" msgid="5365787219927262408">"Vill du göra <xliff:g id="NEW_APP">%s</xliff:g> till din standardapp för samtalsspärr?"</string>
- <string name="change_default_call_screening_warning_message_for_disable_old_app" msgid="2039830033533243164">"<xliff:g id="OLD_APP">%s</xliff:g> kommer inte längre att användas för samtalsspärr."</string>
- <string name="change_default_call_screening_warning_message" msgid="9020537562292754269">"<xliff:g id="NEW_APP">%s</xliff:g> kommer att kunna se information om uppringare som inte finns i dina kontakter och blockera dessa samtal. Endast appar du litar på bör ställas in som standardapp för samtalsspärr."</string>
+ <string name="change_default_call_screening_dialog_title" msgid="5365787219927262408">"Vill du göra <xliff:g id="NEW_APP">%s</xliff:g> till din standardapp för samtalsfiltrering?"</string>
+ <string name="change_default_call_screening_warning_message_for_disable_old_app" msgid="2039830033533243164">"<xliff:g id="OLD_APP">%s</xliff:g> kommer inte längre att användas för samtalsfiltrering."</string>
+ <string name="change_default_call_screening_warning_message" msgid="9020537562292754269">"<xliff:g id="NEW_APP">%s</xliff:g> kommer att kunna se information om uppringare som inte finns i dina kontakter och blockera dessa samtal. Endast appar du litar på bör ställas in som standardapp för samtalsfiltrering."</string>
<string name="change_default_call_screening_dialog_affirmative" msgid="7162433828280058647">"Ange standard"</string>
<string name="change_default_call_screening_dialog_negative" msgid="1839266125623106342">"Avbryt"</string>
<string name="blocked_numbers" msgid="8322134197039865180">"Blockerade nummer"</string>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
index 94a72e4..58eb225 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -118,6 +118,6 @@
<string name="phone_strings_call_blocking_turned_off_notification_text_txt" msgid="1713632946174016619">"కాల్ బ్లాక్ చేయడం నిలిపివేయబడింది"</string>
<string name="phone_strings_emergency_call_made_dialog_title_txt" msgid="6629412508584507377">"అత్యవసర కాల్ చేయబడింది"</string>
<string name="phone_strings_emergency_call_made_dialog_call_blocking_text_txt" msgid="3140411733995271126">"మిమ్మల్ని సంప్రదించడానికి అత్యవసర ప్రతిస్పందనదారులను అనుమతించడానికి కాల్ బ్లాక్ చేయడం నిలిపివేయబడింది."</string>
- <string name="developer_title" msgid="9146088855661672353">"టెలికామ్ డెవలపర్ మెను"</string>
+ <string name="developer_title" msgid="9146088855661672353">"టెలికామ్ డెవలపర్ మెనూ"</string>
<string name="toast_emergency_can_not_pull_call" msgid="9074229465338410869">"అత్యవసర కాల్లో వున్నప్పుడు కాల్లను స్వీకరించడానికి వీలుపడదు."</string>
</resources>
diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml
index ae77978..20cca1b 100644
--- a/res/values-ur/strings.xml
+++ b/res/values-ur/strings.xml
@@ -104,7 +104,7 @@
<string name="alert_redirect_outgoing_call_or_not" msgid="665409645789521636">"یہ کال کرنے کا طریقہ منتخب کریں"</string>
<string name="alert_place_outgoing_call_with_redirection" msgid="5221065030959024121">"<xliff:g id="OTHER_APP">%1$s</xliff:g> کے ذریعے کال کو ریڈائریکٹ کریں"</string>
<string name="alert_place_unredirect_outgoing_call" msgid="2467608535225764006">"میرا فون نمبر استعمال کر کے کال کريں"</string>
- <string name="alert_redirect_outgoing_call_timeout" msgid="5568101425637373060">"<xliff:g id="OTHER_APP">%1$s</xliff:g> کے ذریعے کال نہیں کی جا سکتی۔ کال آگے بڑھانے والی کوئی دوسری ایپ آزما کر یا مدد کے لیے ڈیولپر سے رابطہ کر کے دیکھیں۔"</string>
+ <string name="alert_redirect_outgoing_call_timeout" msgid="5568101425637373060">"<xliff:g id="OTHER_APP">%1$s</xliff:g> کے ذریعے کال نہیں کی جا سکتی۔ کال آگے بڑھانے والی کوئی دوسری ایپ آزما کر یا مدد کے لیے ڈویلپر سے رابطہ کر کے دیکھیں۔"</string>
<string name="phone_settings_call_blocking_txt" msgid="7311523114822507178">"کال مسدود کرنا"</string>
<string name="phone_settings_number_not_in_contact_txt" msgid="2602249106007265757">"وہ نمبرز جو رابطوں میں نہیں ہیں"</string>
<string name="phone_settings_number_not_in_contact_summary_txt" msgid="963327038085718969">"ان نمبرز کو مسدود کریں جو آپ کے رابطوں میں مندرج نہیں ہیں"</string>
@@ -118,6 +118,6 @@
<string name="phone_strings_call_blocking_turned_off_notification_text_txt" msgid="1713632946174016619">"کال مسدود کرنا غیر فعال ہو گیا ہے"</string>
<string name="phone_strings_emergency_call_made_dialog_title_txt" msgid="6629412508584507377">"ہنگامی کال کی گئی"</string>
<string name="phone_strings_emergency_call_made_dialog_call_blocking_text_txt" msgid="3140411733995271126">"ہنگامی حالت میں جواب دہندگان کو آپ سے رابطہ کرنے کی اجازت دینے کیلئے کال مسدود کرنا غیر فعال ہو گیا ہے۔"</string>
- <string name="developer_title" msgid="9146088855661672353">"ٹیلی کام ڈیولپر مینو"</string>
+ <string name="developer_title" msgid="9146088855661672353">"ٹیلی کام ڈویلپر مینو"</string>
<string name="toast_emergency_can_not_pull_call" msgid="9074229465338410869">"ہنگامی کال کے دوران کالز نہیں لی جائیں گی۔"</string>
</resources>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index 5f1c946..0f26c9d 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -57,9 +57,9 @@
<string name="change_default_dialer_dialog_affirmative" msgid="8604665314757739550">"設為預設"</string>
<string name="change_default_dialer_dialog_negative" msgid="8648669840052697821">"取消"</string>
<string name="change_default_dialer_warning_message" msgid="8461963987376916114">"「<xliff:g id="NEW_APP">%s</xliff:g>」將可撥打電話並控制所有相關功能。只有您信任的應用程式,才應設為預設手機應用程式。"</string>
- <string name="change_default_call_screening_dialog_title" msgid="5365787219927262408">"要將「<xliff:g id="NEW_APP">%s</xliff:g>」設為預設來電篩選應用程式嗎?"</string>
+ <string name="change_default_call_screening_dialog_title" msgid="5365787219927262408">"要將「<xliff:g id="NEW_APP">%s</xliff:g>」設為預設來電過濾應用程式嗎?"</string>
<string name="change_default_call_screening_warning_message_for_disable_old_app" msgid="2039830033533243164">"「<xliff:g id="OLD_APP">%s</xliff:g>」無法再篩選來電。"</string>
- <string name="change_default_call_screening_warning_message" msgid="9020537562292754269">"「<xliff:g id="NEW_APP">%s</xliff:g>」將可查看通訊錄以外來電者的相關資訊,並封鎖這些來電。只有您信任的應用程式才適合設為預設來電篩選應用程式。"</string>
+ <string name="change_default_call_screening_warning_message" msgid="9020537562292754269">"「<xliff:g id="NEW_APP">%s</xliff:g>」將可查看通訊錄以外來電者的相關資訊,並封鎖這些來電。只有您信任的應用程式才適合設為預設來電過濾應用程式。"</string>
<string name="change_default_call_screening_dialog_affirmative" msgid="7162433828280058647">"設為預設"</string>
<string name="change_default_call_screening_dialog_negative" msgid="1839266125623106342">"取消"</string>
<string name="blocked_numbers" msgid="8322134197039865180">"已封鎖的號碼"</string>
diff --git a/src/com/android/server/telecom/BluetoothHeadsetProxy.java b/src/com/android/server/telecom/BluetoothHeadsetProxy.java
index a43b3cd..e4eed87 100644
--- a/src/com/android/server/telecom/BluetoothHeadsetProxy.java
+++ b/src/com/android/server/telecom/BluetoothHeadsetProxy.java
@@ -36,19 +36,6 @@
mBluetoothHeadset = headset;
}
- public void clccResponse(int index, int direction, int status, int mode, boolean mpty,
- String number, int type) {
-
- mBluetoothHeadset.clccResponse(index, direction, status, mode, mpty, number, type);
- }
-
- public void phoneStateChanged(int numActive, int numHeld, int callState, String number,
- int type, String name) {
-
- mBluetoothHeadset.phoneStateChanged(numActive, numHeld, callState, number, type,
- name);
- }
-
public List<BluetoothDevice> getConnectedDevices() {
return mBluetoothHeadset.getConnectedDevices();
}
diff --git a/src/com/android/server/telecom/BluetoothPhoneServiceImpl.java b/src/com/android/server/telecom/BluetoothPhoneServiceImpl.java
deleted file mode 100644
index f2ea950..0000000
--- a/src/com/android/server/telecom/BluetoothPhoneServiceImpl.java
+++ /dev/null
@@ -1,932 +0,0 @@
-/*
- * Copyright (C) 2014 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.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothHeadset;
-import android.bluetooth.BluetoothProfile;
-import android.bluetooth.IBluetoothHeadsetPhone;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.Uri;
-import android.os.Binder;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.telecom.Connection;
-import android.telecom.Log;
-import android.telecom.PhoneAccount;
-import android.telecom.VideoProfile;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.telecom.CallsManager.CallsManagerListener;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Bluetooth headset manager for Telecom. This class shares the call state with the bluetooth device
- * and accepts call-related commands to perform on behalf of the BT device.
- */
-public class BluetoothPhoneServiceImpl {
-
- public interface BluetoothPhoneServiceImplFactory {
- BluetoothPhoneServiceImpl makeBluetoothPhoneServiceImpl(Context context,
- TelecomSystem.SyncRoot lock, CallsManager callsManager,
- PhoneAccountRegistrar phoneAccountRegistrar);
- }
-
- private static final String TAG = "BluetoothPhoneService";
-
- // match up with bthf_call_state_t of bt_hf.h
- private static final int CALL_STATE_ACTIVE = 0;
- private static final int CALL_STATE_HELD = 1;
- private static final int CALL_STATE_DIALING = 2;
- private static final int CALL_STATE_ALERTING = 3;
- private static final int CALL_STATE_INCOMING = 4;
- private static final int CALL_STATE_WAITING = 5;
- private static final int CALL_STATE_IDLE = 6;
- private static final int CALL_STATE_DISCONNECTED = 7;
-
- // match up with bthf_call_state_t of bt_hf.h
- // Terminate all held or set UDUB("busy") to a waiting call
- private static final int CHLD_TYPE_RELEASEHELD = 0;
- // Terminate all active calls and accepts a waiting/held call
- private static final int CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD = 1;
- // Hold all active calls and accepts a waiting/held call
- private static final int CHLD_TYPE_HOLDACTIVE_ACCEPTHELD = 2;
- // Add all held calls to a conference
- private static final int CHLD_TYPE_ADDHELDTOCONF = 3;
-
- // Indicates that no call is ringing
- private static final int DEFAULT_RINGING_ADDRESS_TYPE = 128;
-
- private int mNumActiveCalls = 0;
- private int mNumHeldCalls = 0;
- private int mNumChildrenOfActiveCall = 0;
- private int mBluetoothCallState = CALL_STATE_IDLE;
- private String mRingingAddress = "";
- private int mRingingAddressType = DEFAULT_RINGING_ADDRESS_TYPE;
- private Call mOldHeldCall = null;
- private boolean mIsDisconnectedTonePlaying = false;
-
- /**
- * Binder implementation of IBluetoothHeadsetPhone. Implements the command interface that the
- * bluetooth headset code uses to control call.
- */
- @VisibleForTesting
- public final IBluetoothHeadsetPhone.Stub mBinder = new IBluetoothHeadsetPhone.Stub() {
- @Override
- public boolean answerCall() throws RemoteException {
- synchronized (mLock) {
- enforceModifyPermission();
- Log.startSession("BPSI.aC");
- long token = Binder.clearCallingIdentity();
- try {
- Log.i(TAG, "BT - answering call");
- Call call = mCallsManager.getRingingOrSimulatedRingingCall();
- if (call != null) {
- mCallsManager.answerCall(call, VideoProfile.STATE_AUDIO_ONLY);
- return true;
- }
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- Log.endSession();
- }
-
- }
- }
-
- @Override
- public boolean hangupCall() throws RemoteException {
- synchronized (mLock) {
- enforceModifyPermission();
- Log.startSession("BPSI.hC");
- long token = Binder.clearCallingIdentity();
- try {
- Log.i(TAG, "BT - hanging up call");
- Call call = mCallsManager.getForegroundCall();
- if (call != null) {
- mCallsManager.disconnectCall(call);
- return true;
- }
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- Log.endSession();
- }
- }
- }
-
- @Override
- public boolean sendDtmf(int dtmf) throws RemoteException {
- synchronized (mLock) {
- enforceModifyPermission();
- Log.startSession("BPSI.sD");
- long token = Binder.clearCallingIdentity();
- try {
- Log.i(TAG, "BT - sendDtmf %c", Log.DEBUG ? dtmf : '.');
- Call call = mCallsManager.getForegroundCall();
- if (call != null) {
- // TODO: Consider making this a queue instead of starting/stopping
- // in quick succession.
- mCallsManager.playDtmfTone(call, (char) dtmf);
- mCallsManager.stopDtmfTone(call);
- return true;
- }
- return false;
- } finally {
- Binder.restoreCallingIdentity(token);
- Log.endSession();
- }
- }
- }
-
- @Override
- public String getNetworkOperator() throws RemoteException {
- synchronized (mLock) {
- enforceModifyPermission();
- Log.startSession("BPSI.gNO");
- long token = Binder.clearCallingIdentity();
- try {
- Log.i(TAG, "getNetworkOperator");
- PhoneAccount account = getBestPhoneAccount();
- if (account != null && account.getLabel() != null) {
- return account.getLabel().toString();
- } else {
- // Finally, just get the network name from telephony.
- return mContext.getSystemService(TelephonyManager.class)
- .getNetworkOperatorName();
- }
- } finally {
- Binder.restoreCallingIdentity(token);
- Log.endSession();
- }
- }
- }
-
- @Override
- public String getSubscriberNumber() throws RemoteException {
- synchronized (mLock) {
- enforceModifyPermission();
- Log.startSession("BPSI.gSN");
- long token = Binder.clearCallingIdentity();
- try {
- Log.i(TAG, "getSubscriberNumber");
- String address = null;
- PhoneAccount account = getBestPhoneAccount();
- if (account != null) {
- Uri addressUri = account.getAddress();
- if (addressUri != null) {
- address = addressUri.getSchemeSpecificPart();
- }
- }
- if (TextUtils.isEmpty(address)) {
- address = mContext.getSystemService(TelephonyManager.class)
- .getLine1Number();
- if (address == null) address = "";
- }
- return address;
- } finally {
- Binder.restoreCallingIdentity(token);
- Log.endSession();
- }
- }
- }
-
- @Override
- public boolean listCurrentCalls() throws RemoteException {
- synchronized (mLock) {
- enforceModifyPermission();
- Log.startSession("BPSI.lCC");
- long token = Binder.clearCallingIdentity();
- try {
- // only log if it is after we recently updated the headset state or else it can
- // clog the android log since this can be queried every second.
- boolean logQuery = mHeadsetUpdatedRecently;
- mHeadsetUpdatedRecently = false;
-
- if (logQuery) {
- Log.i(TAG, "listcurrentCalls");
- }
-
- sendListOfCalls(logQuery);
- return true;
- } finally {
- Binder.restoreCallingIdentity(token);
- Log.endSession();
- }
- }
- }
-
- @Override
- public boolean queryPhoneState() throws RemoteException {
- synchronized (mLock) {
- enforceModifyPermission();
- Log.startSession("BPSI.qPS");
- long token = Binder.clearCallingIdentity();
- try {
- Log.i(TAG, "queryPhoneState");
- updateHeadsetWithCallState(true /* force */);
- return true;
- } finally {
- Binder.restoreCallingIdentity(token);
- Log.endSession();
- }
- }
- }
-
- @Override
- public boolean processChld(int chld) throws RemoteException {
- synchronized (mLock) {
- enforceModifyPermission();
- Log.startSession("BPSI.pC");
- long token = Binder.clearCallingIdentity();
- try {
- Log.i(TAG, "processChld %d", chld);
- return BluetoothPhoneServiceImpl.this.processChld(chld);
- } finally {
- Binder.restoreCallingIdentity(token);
- Log.endSession();
- }
- }
- }
-
- @Override
- public void updateBtHandsfreeAfterRadioTechnologyChange() throws RemoteException {
- Log.d(TAG, "RAT change - deprecated");
- // deprecated
- }
-
- @Override
- public void cdmaSetSecondCallState(boolean state) throws RemoteException {
- Log.d(TAG, "cdma 1 - deprecated");
- // deprecated
- }
-
- @Override
- public void cdmaSwapSecondCallState() throws RemoteException {
- Log.d(TAG, "cdma 2 - deprecated");
- // deprecated
- }
- };
-
- /**
- * Listens to call changes from the CallsManager and calls into methods to update the bluetooth
- * headset with the new states.
- */
- @VisibleForTesting
- public CallsManagerListener mCallsManagerListener = new CallsManagerListenerBase() {
- @Override
- public void onCallAdded(Call call) {
- if (call.isExternalCall()) {
- return;
- }
- updateHeadsetWithCallState(false /* force */);
- }
-
- @Override
- public void onCallRemoved(Call call) {
- if (call.isExternalCall()) {
- return;
- }
- mClccIndexMap.remove(call);
- updateHeadsetWithCallState(false /* force */);
- }
-
- /**
- * Where a call which was external becomes a regular call, or a regular call becomes
- * external, treat as an add or remove, respectively.
- *
- * @param call The call.
- * @param isExternalCall {@code True} if the call became external, {@code false} otherwise.
- */
- @Override
- public void onExternalCallChanged(Call call, boolean isExternalCall) {
- if (isExternalCall) {
- onCallRemoved(call);
- } else {
- onCallAdded(call);
- }
- }
-
- @Override
- public void onCallStateChanged(Call call, int oldState, int newState) {
- if (call.isExternalCall()) {
- return;
- }
- // If a call is being put on hold because of a new connecting call, ignore the
- // CONNECTING since the BT state update needs to send out the numHeld = 1 + dialing
- // state atomically.
- // When the call later transitions to DIALING/DISCONNECTED we will then send out the
- // aggregated update.
- if (oldState == CallState.ACTIVE && newState == CallState.ON_HOLD) {
- for (Call otherCall : mCallsManager.getCalls()) {
- if (otherCall.getState() == CallState.CONNECTING) {
- return;
- }
- }
- }
-
- // To have an active call and another dialing at the same time is an invalid BT
- // state. We can assume that the active call will be automatically held which will
- // send another update at which point we will be in the right state.
- if (mCallsManager.getActiveCall() != null
- && oldState == CallState.CONNECTING &&
- (newState == CallState.DIALING || newState == CallState.PULLING)) {
- return;
- }
- updateHeadsetWithCallState(false /* force */);
- }
-
- @Override
- public void onIsConferencedChanged(Call call) {
- if (call.isExternalCall()) {
- return;
- }
- /*
- * Filter certain onIsConferencedChanged callbacks. Unfortunately this needs to be done
- * because conference change events are not atomic and multiple callbacks get fired
- * when two calls are conferenced together. This confuses updateHeadsetWithCallState
- * if it runs in the middle of two calls being conferenced and can cause spurious and
- * incorrect headset state updates. One of the scenarios is described below for CDMA
- * conference calls.
- *
- * 1) Call 1 and Call 2 are being merged into conference Call 3.
- * 2) Call 1 has its parent set to Call 3, but Call 2 does not have a parent yet.
- * 3) updateHeadsetWithCallState now thinks that there are two active calls (Call 2 and
- * Call 3) when there is actually only one active call (Call 3).
- */
- if (call.getParentCall() != null) {
- // If this call is newly conferenced, ignore the callback. We only care about the
- // one sent for the parent conference call.
- Log.d(this, "Ignoring onIsConferenceChanged from child call with new parent");
- return;
- }
- if (call.getChildCalls().size() == 1) {
- // If this is a parent call with only one child, ignore the callback as well since
- // the minimum number of child calls to start a conference call is 2. We expect
- // this to be called again when the parent call has another child call added.
- Log.d(this, "Ignoring onIsConferenceChanged from parent with only one child call");
- return;
- }
- updateHeadsetWithCallState(false /* force */);
- }
-
- @Override
- public void onDisconnectedTonePlaying(boolean isTonePlaying) {
- mIsDisconnectedTonePlaying = isTonePlaying;
- updateHeadsetWithCallState(false /* force */);
- }
- };
-
- /**
- * Listens to connections and disconnections of bluetooth headsets. We need to save the current
- * bluetooth headset so that we know where to send call updates.
- */
- @VisibleForTesting
- public BluetoothProfile.ServiceListener mProfileListener =
- new BluetoothProfile.ServiceListener() {
- @Override
- public void onServiceConnected(int profile, BluetoothProfile proxy) {
- synchronized (mLock) {
- setBluetoothHeadset(new BluetoothHeadsetProxy((BluetoothHeadset) proxy));
- updateHeadsetWithCallState(true /* force */);
- }
- }
-
- @Override
- public void onServiceDisconnected(int profile) {
- synchronized (mLock) {
- mBluetoothHeadset = null;
- }
- }
- };
-
- /**
- * Receives events for global state changes of the bluetooth adapter.
- */
- @VisibleForTesting
- public final BroadcastReceiver mBluetoothAdapterReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- synchronized (mLock) {
- int state = intent
- .getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
- Log.d(TAG, "Bluetooth Adapter state: %d", state);
- if (state == BluetoothAdapter.STATE_ON) {
- try {
- mBinder.queryPhoneState();
- } catch (RemoteException e) {
- // Remote exception not expected
- }
- }
- }
- }
- };
-
- private BluetoothAdapterProxy mBluetoothAdapter;
- private BluetoothHeadsetProxy mBluetoothHeadset;
-
- // A map from Calls to indexes used to identify calls for CLCC (C* List Current Calls).
- private Map<Call, Integer> mClccIndexMap = new HashMap<>();
-
- private boolean mHeadsetUpdatedRecently = false;
-
- private final Context mContext;
- private final TelecomSystem.SyncRoot mLock;
- private final CallsManager mCallsManager;
- private final PhoneAccountRegistrar mPhoneAccountRegistrar;
-
- public IBinder getBinder() {
- return mBinder;
- }
-
- public BluetoothPhoneServiceImpl(
- Context context,
- TelecomSystem.SyncRoot lock,
- CallsManager callsManager,
- BluetoothAdapterProxy bluetoothAdapter,
- PhoneAccountRegistrar phoneAccountRegistrar) {
- Log.d(this, "onCreate");
-
- mContext = context;
- mLock = lock;
- mCallsManager = callsManager;
- mPhoneAccountRegistrar = phoneAccountRegistrar;
-
- mBluetoothAdapter = bluetoothAdapter;
- if (mBluetoothAdapter == null) {
- Log.d(this, "BluetoothPhoneService shutting down, no BT Adapter found.");
- return;
- }
- mBluetoothAdapter.getProfileProxy(context, mProfileListener, BluetoothProfile.HEADSET);
-
- IntentFilter intentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
- context.registerReceiver(mBluetoothAdapterReceiver, intentFilter);
-
- mCallsManager.addListener(mCallsManagerListener);
- updateHeadsetWithCallState(false /* force */);
- }
-
- @VisibleForTesting
- public void setBluetoothHeadset(BluetoothHeadsetProxy bluetoothHeadset) {
- mBluetoothHeadset = bluetoothHeadset;
- }
-
- private boolean processChld(int chld) {
- Call activeCall = mCallsManager.getActiveCall();
- Call ringingCall = mCallsManager.getRingingOrSimulatedRingingCall();
- Call heldCall = mCallsManager.getHeldCall();
-
- // TODO: Keeping as Log.i for now. Move to Log.d after L release if BT proves stable.
- Log.i(TAG, "Active: %s\nRinging: %s\nHeld: %s", activeCall, ringingCall, heldCall);
-
- if (chld == CHLD_TYPE_RELEASEHELD) {
- if (ringingCall != null) {
- mCallsManager.rejectCall(ringingCall, false, null);
- return true;
- } else if (heldCall != null) {
- mCallsManager.disconnectCall(heldCall);
- return true;
- }
- } else if (chld == CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD) {
- if (activeCall == null && ringingCall == null && heldCall == null)
- return false;
- if (activeCall != null) {
- mCallsManager.disconnectCall(activeCall);
- if (ringingCall != null) {
- mCallsManager.answerCall(ringingCall, VideoProfile.STATE_AUDIO_ONLY);
- }
- return true;
- }
- if (ringingCall != null) {
- mCallsManager.answerCall(ringingCall, ringingCall.getVideoState());
- } else if (heldCall != null) {
- mCallsManager.unholdCall(heldCall);
- }
- return true;
- } else if (chld == CHLD_TYPE_HOLDACTIVE_ACCEPTHELD) {
- if (activeCall != null && activeCall.can(Connection.CAPABILITY_SWAP_CONFERENCE)) {
- activeCall.swapConference();
- Log.i(TAG, "CDMA calls in conference swapped, updating headset");
- updateHeadsetWithCallState(true /* force */);
- return true;
- } else if (ringingCall != null) {
- mCallsManager.answerCall(ringingCall, VideoProfile.STATE_AUDIO_ONLY);
- return true;
- } else if (heldCall != null) {
- // CallsManager will hold any active calls when unhold() is called on a
- // currently-held call.
- mCallsManager.unholdCall(heldCall);
- return true;
- } else if (activeCall != null && activeCall.can(Connection.CAPABILITY_HOLD)) {
- mCallsManager.holdCall(activeCall);
- return true;
- }
- } else if (chld == CHLD_TYPE_ADDHELDTOCONF) {
- if (activeCall != null) {
- if (activeCall.can(Connection.CAPABILITY_MERGE_CONFERENCE)) {
- activeCall.mergeConference();
- return true;
- } else {
- List<Call> conferenceable = activeCall.getConferenceableCalls();
- if (!conferenceable.isEmpty()) {
- mCallsManager.conference(activeCall, conferenceable.get(0));
- return true;
- }
- }
- }
- }
- return false;
- }
-
- private void enforceModifyPermission() {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.MODIFY_PHONE_STATE, null);
- }
-
- private void sendListOfCalls(boolean shouldLog) {
- Collection<Call> mCalls = mCallsManager.getCalls();
- for (Call call : mCalls) {
- // We don't send the parent conference call to the bluetooth device.
- // We do, however want to send conferences that have no children to the bluetooth
- // device (e.g. IMS Conference).
- if (!call.isConference() ||
- (call.isConference() && call
- .can(Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN))) {
- sendClccForCall(call, shouldLog);
- }
- }
- sendClccEndMarker();
- }
-
- /**
- * Sends a single clcc (C* List Current Calls) event for the specified call.
- */
- private void sendClccForCall(Call call, boolean shouldLog) {
- boolean isForeground = mCallsManager.getForegroundCall() == call;
- int state = getBtCallState(call, isForeground);
- boolean isPartOfConference = false;
- boolean isConferenceWithNoChildren = call.isConference() && call
- .can(Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
-
- if (state == CALL_STATE_IDLE) {
- return;
- }
-
- Call conferenceCall = call.getParentCall();
- if (conferenceCall != null) {
- isPartOfConference = true;
-
- // Run some alternative states for Conference-level merge/swap support.
- // Basically, if call supports swapping or merging at the conference-level, then we need
- // to expose the calls as having distinct states (ACTIVE vs CAPABILITY_HOLD) or the
- // functionality won't show up on the bluetooth device.
-
- // Before doing any special logic, ensure that we are dealing with an ACTIVE call and
- // that the conference itself has a notion of the current "active" child call.
- Call activeChild = conferenceCall.getConferenceLevelActiveCall();
- if (state == CALL_STATE_ACTIVE && activeChild != null) {
- // Reevaluate state if we can MERGE or if we can SWAP without previously having
- // MERGED.
- boolean shouldReevaluateState =
- conferenceCall.can(Connection.CAPABILITY_MERGE_CONFERENCE) ||
- (conferenceCall.can(Connection.CAPABILITY_SWAP_CONFERENCE) &&
- !conferenceCall.wasConferencePreviouslyMerged());
-
- if (shouldReevaluateState) {
- isPartOfConference = false;
- if (call == activeChild) {
- state = CALL_STATE_ACTIVE;
- } else {
- // At this point we know there is an "active" child and we know that it is
- // not this call, so set it to HELD instead.
- state = CALL_STATE_HELD;
- }
- }
- }
- if (conferenceCall.getState() == CallState.ON_HOLD &&
- conferenceCall.can(Connection.CAPABILITY_MANAGE_CONFERENCE)) {
- // If the parent IMS CEP conference call is on hold, we should mark this call as
- // being on hold regardless of what the other children are doing.
- state = CALL_STATE_HELD;
- }
- } else if (isConferenceWithNoChildren) {
- // Handle the special case of an IMS conference call without conference event package
- // support. The call will be marked as a conference, but the conference will not have
- // child calls where conference event packages are not used by the carrier.
- isPartOfConference = true;
- }
-
- int index = getIndexForCall(call);
- int direction = call.isIncoming() ? 1 : 0;
- final Uri addressUri;
- if (call.getGatewayInfo() != null) {
- addressUri = call.getGatewayInfo().getOriginalAddress();
- } else {
- addressUri = call.getHandle();
- }
-
- String address = addressUri == null ? null : addressUri.getSchemeSpecificPart();
- if (address != null) {
- address = PhoneNumberUtils.stripSeparators(address);
- }
-
- int addressType = address == null ? -1 : PhoneNumberUtils.toaFromString(address);
-
- if (shouldLog) {
- Log.i(this, "sending clcc for call %d, %d, %d, %b, %s, %d",
- index, direction, state, isPartOfConference, Log.piiHandle(address),
- addressType);
- }
-
- if (mBluetoothHeadset != null) {
- mBluetoothHeadset.clccResponse(
- index, direction, state, 0, isPartOfConference, address, addressType);
- }
- }
-
- private void sendClccEndMarker() {
- // End marker is recognized with an index value of 0. All other parameters are ignored.
- if (mBluetoothHeadset != null) {
- mBluetoothHeadset.clccResponse(0 /* index */, 0, 0, 0, false, null, 0);
- }
- }
-
- /**
- * Returns the caches index for the specified call. If no such index exists, then an index is
- * given (smallest number starting from 1 that isn't already taken).
- */
- private int getIndexForCall(Call call) {
- if (mClccIndexMap.containsKey(call)) {
- return mClccIndexMap.get(call);
- }
-
- int i = 1; // Indexes for bluetooth clcc are 1-based.
- while (mClccIndexMap.containsValue(i)) {
- i++;
- }
-
- // NOTE: Indexes are removed in {@link #onCallRemoved}.
- mClccIndexMap.put(call, i);
- return i;
- }
-
- /**
- * Sends an update of the current call state to the current Headset.
- *
- * @param force {@code true} if the headset state should be sent regardless if no changes to the
- * state have occurred, {@code false} if the state should only be sent if the state has
- * changed.
- */
- private void updateHeadsetWithCallState(boolean force) {
- Call activeCall = mCallsManager.getActiveCall();
- Call ringingCall = mCallsManager.getRingingOrSimulatedRingingCall();
- Call heldCall = mCallsManager.getHeldCall();
-
- int bluetoothCallState = getBluetoothCallStateForUpdate();
-
- String ringingAddress = null;
- int ringingAddressType = DEFAULT_RINGING_ADDRESS_TYPE;
- String ringingName = null;
- if (ringingCall != null && ringingCall.getHandle() != null
- && !ringingCall.isSilentRingingRequested()) {
- ringingAddress = ringingCall.getHandle().getSchemeSpecificPart();
- if (ringingAddress != null) {
- ringingAddressType = PhoneNumberUtils.toaFromString(ringingAddress);
- }
- ringingName = ringingCall.getCallerDisplayName();
- if (TextUtils.isEmpty(ringingName)) {
- ringingName = ringingCall.getName();
- }
- }
- if (ringingAddress == null) {
- ringingAddress = "";
- }
-
- int numActiveCalls = activeCall == null ? 0 : 1;
- int numHeldCalls = mCallsManager.getNumHeldCalls();
- int numChildrenOfActiveCall = activeCall == null ? 0 : activeCall.getChildCalls().size();
-
- // Intermediate state for GSM calls which are in the process of being swapped.
- // TODO: Should we be hardcoding this value to 2 or should we check if all top level calls
- // are held?
- boolean callsPendingSwitch = (numHeldCalls == 2);
-
- // For conference calls which support swapping the active call within the conference
- // (namely CDMA calls) we need to expose that as a held call in order for the BT device
- // to show "swap" and "merge" functionality.
- boolean ignoreHeldCallChange = false;
- if (activeCall != null && activeCall.isConference() &&
- !activeCall.can(Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN)) {
- if (activeCall.can(Connection.CAPABILITY_SWAP_CONFERENCE)) {
- // Indicate that BT device should show SWAP command by indicating that there is a
- // call on hold, but only if the conference wasn't previously merged.
- numHeldCalls = activeCall.wasConferencePreviouslyMerged() ? 0 : 1;
- } else if (activeCall.can(Connection.CAPABILITY_MERGE_CONFERENCE)) {
- numHeldCalls = 1; // Merge is available, so expose via numHeldCalls.
- }
-
- for (Call childCall : activeCall.getChildCalls()) {
- // Held call has changed due to it being combined into a CDMA conference. Keep
- // track of this and ignore any future update since it doesn't really count as
- // a call change.
- if (mOldHeldCall == childCall) {
- ignoreHeldCallChange = true;
- break;
- }
- }
- }
-
- if (mBluetoothHeadset != null &&
- (force ||
- (!callsPendingSwitch &&
- (numActiveCalls != mNumActiveCalls ||
- numChildrenOfActiveCall != mNumChildrenOfActiveCall ||
- numHeldCalls != mNumHeldCalls ||
- bluetoothCallState != mBluetoothCallState ||
- !TextUtils.equals(ringingAddress, mRingingAddress) ||
- ringingAddressType != mRingingAddressType ||
- (heldCall != mOldHeldCall && !ignoreHeldCallChange))))) {
-
- // If the call is transitioning into the alerting state, send DIALING first.
- // Some devices expect to see a DIALING state prior to seeing an ALERTING state
- // so we need to send it first.
- boolean sendDialingFirst = mBluetoothCallState != bluetoothCallState &&
- bluetoothCallState == CALL_STATE_ALERTING;
-
- mOldHeldCall = heldCall;
- mNumActiveCalls = numActiveCalls;
- mNumChildrenOfActiveCall = numChildrenOfActiveCall;
- mNumHeldCalls = numHeldCalls;
- mBluetoothCallState = bluetoothCallState;
- mRingingAddress = ringingAddress;
- mRingingAddressType = ringingAddressType;
-
- if (sendDialingFirst) {
- // Log in full to make logs easier to debug.
- Log.i(TAG, "updateHeadsetWithCallState " +
- "numActive %s, " +
- "numHeld %s, " +
- "callState %s, " +
- "ringing number %s, " +
- "ringing type %s, " +
- "ringing name %s",
- mNumActiveCalls,
- mNumHeldCalls,
- CALL_STATE_DIALING,
- Log.pii(mRingingAddress),
- mRingingAddressType,
- Log.pii(ringingName));
- mBluetoothHeadset.phoneStateChanged(
- mNumActiveCalls,
- mNumHeldCalls,
- CALL_STATE_DIALING,
- mRingingAddress,
- mRingingAddressType,
- ringingName);
- }
-
- Log.i(TAG, "updateHeadsetWithCallState " +
- "numActive %s, " +
- "numHeld %s, " +
- "callState %s, " +
- "ringing number %s, " +
- "ringing type %s, " +
- "ringing name %s",
- mNumActiveCalls,
- mNumHeldCalls,
- mBluetoothCallState,
- Log.pii(mRingingAddress),
- mRingingAddressType,
- Log.pii(ringingName));
-
- mBluetoothHeadset.phoneStateChanged(
- mNumActiveCalls,
- mNumHeldCalls,
- mBluetoothCallState,
- mRingingAddress,
- mRingingAddressType,
- ringingName);
-
- mHeadsetUpdatedRecently = true;
- }
- }
-
- private int getBluetoothCallStateForUpdate() {
- Call ringingCall = mCallsManager.getRingingOrSimulatedRingingCall();
- Call dialingCall = mCallsManager.getOutgoingCall();
- boolean hasOnlyDisconnectedCalls = mCallsManager.hasOnlyDisconnectedCalls();
-
- //
- // !! WARNING !!
- // You will note that CALL_STATE_WAITING, CALL_STATE_HELD, and CALL_STATE_ACTIVE are not
- // used in this version of the call state mappings. This is on purpose.
- // phone_state_change() in btif_hf.c is not written to handle these states. Only with the
- // listCalls*() method are WAITING and ACTIVE used.
- // Using the unsupported states here caused problems with inconsistent state in some
- // bluetooth devices (like not getting out of ringing state after answering a call).
- //
- int bluetoothCallState = CALL_STATE_IDLE;
- if (ringingCall != null && !ringingCall.isSilentRingingRequested()) {
- bluetoothCallState = CALL_STATE_INCOMING;
- } else if (dialingCall != null) {
- bluetoothCallState = CALL_STATE_ALERTING;
- } else if (hasOnlyDisconnectedCalls || mIsDisconnectedTonePlaying) {
- // Keep the DISCONNECTED state until the disconnect tone's playback is done
- bluetoothCallState = CALL_STATE_DISCONNECTED;
- }
- return bluetoothCallState;
- }
-
- private int getBtCallState(Call call, boolean isForeground) {
- switch (call.getState()) {
- case CallState.NEW:
- case CallState.ABORTED:
- case CallState.DISCONNECTED:
- case CallState.AUDIO_PROCESSING:
- return CALL_STATE_IDLE;
-
- case CallState.ACTIVE:
- return CALL_STATE_ACTIVE;
-
- case CallState.CONNECTING:
- case CallState.SELECT_PHONE_ACCOUNT:
- case CallState.DIALING:
- case CallState.PULLING:
- // Yes, this is correctly returning ALERTING.
- // "Dialing" for BT means that we have sent information to the service provider
- // to place the call but there is no confirmation that the call is going through.
- // When there finally is confirmation, the ringback is played which is referred to
- // as an "alert" tone, thus, ALERTING.
- // TODO: We should consider using the ALERTING terms in Telecom because that
- // seems to be more industry-standard.
- return CALL_STATE_ALERTING;
-
- case CallState.ON_HOLD:
- return CALL_STATE_HELD;
-
- case CallState.RINGING:
- case CallState.ANSWERED:
- case CallState.SIMULATED_RINGING:
- if (call.isSilentRingingRequested()) {
- return CALL_STATE_IDLE;
- } else if (isForeground) {
- return CALL_STATE_INCOMING;
- } else {
- return CALL_STATE_WAITING;
- }
- }
- return CALL_STATE_IDLE;
- }
-
- /**
- * Returns the best phone account to use for the given state of all calls.
- * First, tries to return the phone account for the foreground call, second the default
- * phone account for PhoneAccount.SCHEME_TEL.
- */
- private PhoneAccount getBestPhoneAccount() {
- if (mPhoneAccountRegistrar == null) {
- return null;
- }
-
- Call call = mCallsManager.getForegroundCall();
-
- PhoneAccount account = null;
- if (call != null) {
- // First try to get the network name of the foreground call.
- account = mPhoneAccountRegistrar.getPhoneAccountOfCurrentUser(
- call.getTargetPhoneAccount());
- }
-
- if (account == null) {
- // Second, Try to get the label for the default Phone Account.
- account = mPhoneAccountRegistrar.getPhoneAccountUnchecked(
- mPhoneAccountRegistrar.getOutgoingPhoneAccountForSchemeOfCurrentUser(
- PhoneAccount.SCHEME_TEL));
- }
- return account;
- }
-}
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index 69e41a6..dc862ab 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -2462,7 +2462,7 @@
"reject call failed due to null CS callId=%s", getId());
}
Log.addEvent(this, LogUtils.Events.REQUEST_REJECT, reason);
- } else if (isRinging("reject")) {
+ } else if (isRinging("reject") || isAnswered("reject")) {
// Ensure video state history tracks video state at time of rejection.
mVideoStateHistory |= mVideoState;
@@ -2494,7 +2494,7 @@
"reject call failed due to null CS callId=%s", getId());
}
Log.addEvent(this, LogUtils.Events.REQUEST_REJECT);
- } else if (isRinging("reject")) {
+ } else if (isRinging("reject") || isAnswered("reject")) {
// Ensure video state history tracks video state at time of rejection.
mVideoStateHistory |= mVideoState;
@@ -3175,6 +3175,18 @@
return false;
}
+ /**
+ * @return True if the call is answered, else logs the action name.
+ */
+ private boolean isAnswered(String actionName) {
+ if (mState == CallState.ANSWERED) {
+ return true;
+ }
+
+ Log.i(this, "Request to %s a non-answered call %s", actionName, this);
+ return false;
+ }
+
@SuppressWarnings("rawtypes")
private void decrementAssociatedCallCount(ServiceBinder binder) {
if (binder != null) {
diff --git a/src/com/android/server/telecom/CallIntentProcessor.java b/src/com/android/server/telecom/CallIntentProcessor.java
index 7305ab9..7f864b8 100644
--- a/src/com/android/server/telecom/CallIntentProcessor.java
+++ b/src/com/android/server/telecom/CallIntentProcessor.java
@@ -141,6 +141,23 @@
clientExtras.putString(TelecomManager.EXTRA_CALL_SUBJECT, callsubject);
}
+ if (intent.hasExtra(android.telecom.TelecomManager.EXTRA_PRIORITY)) {
+ clientExtras.putInt(android.telecom.TelecomManager.EXTRA_PRIORITY, intent.getIntExtra(
+ android.telecom.TelecomManager.EXTRA_PRIORITY,
+ android.telecom.TelecomManager.PRIORITY_NORMAL));
+ }
+
+ if (intent.hasExtra(android.telecom.TelecomManager.EXTRA_LOCATION)) {
+ clientExtras.putParcelable(android.telecom.TelecomManager.EXTRA_LOCATION,
+ intent.getParcelableExtra(android.telecom.TelecomManager.EXTRA_LOCATION));
+ }
+
+ if (intent.hasExtra(android.telecom.TelecomManager.EXTRA_OUTGOING_PICTURE)) {
+ clientExtras.putParcelable(android.telecom.TelecomManager.EXTRA_OUTGOING_PICTURE,
+ intent.getParcelableExtra(
+ android.telecom.TelecomManager.EXTRA_OUTGOING_PICTURE));
+ }
+
final int videoState = intent.getIntExtra( TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE,
VideoProfile.STATE_AUDIO_ONLY);
clientExtras.putInt(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, videoState);
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index 5a7a47f..1e963c4 100755
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -178,6 +178,7 @@
void onConnectionTimeChanged(Call call);
void onConferenceStateChanged(Call call, boolean isConference);
void onCdmaConferenceSwap(Call call);
+ void onSetCamera(Call call, String cameraId);
}
/** Interface used to define the action which is executed delay under some condition. */
@@ -1027,6 +1028,18 @@
}
}
+ /**
+ * Handles a change to the currently active camera for a call by notifying listeners.
+ * @param call The call.
+ * @param cameraId The ID of the camera in use, or {@code null} if no camera is in use.
+ */
+ @Override
+ public void onSetCamera(Call call, String cameraId) {
+ for (CallsManagerListener listener : mListeners) {
+ listener.onSetCamera(call, cameraId);
+ }
+ }
+
public Collection<Call> getCalls() {
return Collections.unmodifiableCollection(mCalls);
}
diff --git a/src/com/android/server/telecom/CallsManagerListenerBase.java b/src/com/android/server/telecom/CallsManagerListenerBase.java
index e0d2831..55c7b53 100644
--- a/src/com/android/server/telecom/CallsManagerListenerBase.java
+++ b/src/com/android/server/telecom/CallsManagerListenerBase.java
@@ -104,4 +104,8 @@
@Override
public void onCdmaConferenceSwap(Call call) {
}
+
+ @Override
+ public void onSetCamera(Call call, String cameraId) {
+ }
}
diff --git a/src/com/android/server/telecom/InCallController.java b/src/com/android/server/telecom/InCallController.java
index 1fa914a..954aa44 100644
--- a/src/com/android/server/telecom/InCallController.java
+++ b/src/com/android/server/telecom/InCallController.java
@@ -222,7 +222,7 @@
Log.startSession("ICSBC.oSD", Log.getPackageAbbreviation(name));
synchronized (mLock) {
try {
- Log.d(this, "onDisconnected: %s", name);
+ Log.d(this, "onServiceDisconnected: %s", name);
mIsBound = false;
onDisconnected();
} finally {
@@ -343,6 +343,8 @@
mInCallServiceInfo.getDisconnectTime()
- mInCallServiceInfo.getBindingStartTime(), mIsNullBinding);
}
+
+ InCallController.this.onDisconnected(mInCallServiceInfo);
} else {
Log.i(InCallController.this, "ICSBC#disconnect: already disconnected; %s",
mInCallServiceInfo);
@@ -953,6 +955,17 @@
private final CarModeTracker mCarModeTracker;
+ /**
+ * The package name of the app which is showing the calling UX.
+ */
+ private String mCurrentUserInterfacePackageName = null;
+
+ /**
+ * {@code true} if InCallController is tracking a managed, not external call which is using the
+ * microphone, {@code false} otherwise.
+ */
+ private boolean mIsCallUsingMicrophone = false;
+
public InCallController(Context context, TelecomSystem.SyncRoot lock, CallsManager callsManager,
SystemStateHelper systemStateHelper,
DefaultDialerCache defaultDialerCache, Timeouts.Adapter timeoutsAdapter,
@@ -1046,6 +1059,7 @@
}
call.removeListener(mCallListener);
mCallIdMapper.removeCall(call);
+ maybeTrackMicrophoneUse(isMuted());
}
@Override
@@ -1121,10 +1135,12 @@
}
Log.i(this, "External call removed from components: %s", componentsUpdated);
}
+ maybeTrackMicrophoneUse(isMuted());
}
@Override
public void onCallStateChanged(Call call, int oldState, int newState) {
+ maybeTrackMicrophoneUse(isMuted());
updateCall(call);
}
@@ -1142,6 +1158,7 @@
if (!mInCallServices.isEmpty()) {
Log.i(this, "Calling onAudioStateChanged, audioState: %s -> %s", oldCallAudioState,
newCallAudioState);
+ maybeTrackMicrophoneUse(newCallAudioState.isMuted());
for (IInCallService inCallService : mInCallServices.values()) {
try {
inCallService.onCallAudioStateChanged(newCallAudioState);
@@ -1206,6 +1223,23 @@
updateCall(call);
}
+ /**
+ * Track changes to camera usage for a call.
+ * @param call The call.
+ * @param cameraId The id of the camera to use, or {@code null} if camera is off.
+ */
+ @Override
+ public void onSetCamera(Call call, String cameraId) {
+ Log.i(this, "onSetCamera callId=%s, cameraId=%s", call.getId(), cameraId);
+ if (cameraId != null) {
+ mAppOpsManager.startOp(AppOpsManager.OP_PHONE_CALL_CAMERA, myUid(),
+ mContext.getOpPackageName(), false, null, null);
+ } else {
+ mAppOpsManager.finishOp(AppOpsManager.OP_PHONE_CALL_CAMERA, myUid(),
+ mContext.getOpPackageName(), null);
+ }
+ }
+
void bringToForeground(boolean showDialpad) {
if (!mInCallServices.isEmpty()) {
for (IInCallService inCallService : mInCallServices.values()) {
@@ -1600,6 +1634,11 @@
private boolean onConnected(InCallServiceInfo info, IBinder service) {
Log.i(this, "onConnected to %s", info.getComponentName());
+ if (info.getType() == IN_CALL_SERVICE_TYPE_CAR_MODE_UI
+ || info.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI
+ || info.getType() == IN_CALL_SERVICE_TYPE_DIALER_UI) {
+ trackCallingUserInterfaceStarted(info);
+ }
IInCallService inCallService = IInCallService.Stub.asInterface(service);
mInCallServices.put(info, inCallService);
@@ -1667,7 +1706,11 @@
*/
private void onDisconnected(InCallServiceInfo disconnectedInfo) {
Log.i(this, "onDisconnected from %s", disconnectedInfo.getComponentName());
-
+ if (disconnectedInfo.getType() == IN_CALL_SERVICE_TYPE_CAR_MODE_UI
+ || disconnectedInfo.getType() == IN_CALL_SERVICE_TYPE_SYSTEM_UI
+ || disconnectedInfo.getType() == IN_CALL_SERVICE_TYPE_DIALER_UI) {
+ trackCallingUserInterfaceStopped(disconnectedInfo);
+ }
mInCallServices.remove(disconnectedInfo);
}
@@ -1734,6 +1777,7 @@
mCallIdMapper.addCall(call);
call.addListener(mCallListener);
}
+ maybeTrackMicrophoneUse(isMuted());
}
/**
@@ -1913,6 +1957,69 @@
}
}
+ /**
+ * Tracks start of microphone use on binding to the current calling UX.
+ * @param info
+ */
+ private void trackCallingUserInterfaceStarted(InCallServiceInfo info) {
+ String packageName = info.getComponentName().getPackageName();
+ if (!Objects.equals(mCurrentUserInterfacePackageName, packageName)) {
+ Log.i(this, "trackCallingUserInterfaceStarted: %s is now calling UX.", packageName);
+ mCurrentUserInterfacePackageName = packageName;
+ }
+ maybeTrackMicrophoneUse(isMuted());
+ }
+
+ /**
+ * Tracks stop of microphone use on unbind from the current calling UX.
+ * @param info
+ */
+ private void trackCallingUserInterfaceStopped(InCallServiceInfo info) {
+ maybeTrackMicrophoneUse(isMuted());
+ mCurrentUserInterfacePackageName = null;
+ String packageName = info.getComponentName().getPackageName();
+ Log.i(this, "trackCallingUserInterfaceStopped: %s is no longer calling UX", packageName);
+ }
+
+ /**
+ * As calls are added, removed and change between external and non-external status, track
+ * whether the current active calling UX is using the microphone. We assume if there is a
+ * managed call present and the mic is not muted that the microphone is in use.
+ */
+ private void maybeTrackMicrophoneUse(boolean isMuted) {
+ boolean wasTrackingManagedCall = mIsCallUsingMicrophone;
+ mIsCallUsingMicrophone = isTrackingManagedAliveCall() && !isMuted;
+ if (wasTrackingManagedCall != mIsCallUsingMicrophone) {
+ if (mIsCallUsingMicrophone) {
+ mAppOpsManager.startOp(AppOpsManager.OP_PHONE_CALL_MICROPHONE, myUid(),
+ mContext.getOpPackageName(), false, null, null);
+ } else {
+ mAppOpsManager.finishOp(AppOpsManager.OP_PHONE_CALL_MICROPHONE, myUid(),
+ mContext.getOpPackageName(), null);
+ }
+ }
+ }
+
+ /**
+ * @return {@code true} if InCallController is tracking a managed call (i.e. not self managed
+ * and not external) that is active.
+ */
+ private boolean isTrackingManagedAliveCall() {
+ return mCallIdMapper.getCalls().stream().anyMatch(c -> !c.isExternalCall()
+ && !c.isSelfManaged() && c.isAlive() && c.getState() != CallState.ON_HOLD
+ && c.getState() != CallState.AUDIO_PROCESSING);
+ }
+
+ /**
+ * @return {@code true} if the audio is currently muted, {@code false} otherwise.
+ */
+ private boolean isMuted() {
+ if (mCallsManager.getAudioState() == null) {
+ return false;
+ }
+ return mCallsManager.getAudioState().isMuted();
+ }
+
private boolean isAppOpsPermittedManageOngoingCalls(int uid, String callingPackage) {
return PermissionChecker.checkPermissionForPreflight(mContext,
Manifest.permission.MANAGE_ONGOING_CALLS, PermissionChecker.PID_UNKNOWN, uid,
@@ -1922,6 +2029,10 @@
private void sendCrashedInCallServiceNotification(String packageName) {
PackageManager packageManager = mContext.getPackageManager();
CharSequence appName;
+ String systemDialer = mDefaultDialerCache.getSystemDialerApplication();
+ if ((systemDialer != null) && systemDialer.equals(packageName)) {
+ return;
+ }
try {
appName = packageManager.getApplicationLabel(
packageManager.getApplicationInfo(packageName, 0));
diff --git a/src/com/android/server/telecom/TelecomSystem.java b/src/com/android/server/telecom/TelecomSystem.java
index 4842796..8928e76 100644
--- a/src/com/android/server/telecom/TelecomSystem.java
+++ b/src/com/android/server/telecom/TelecomSystem.java
@@ -26,7 +26,6 @@
import com.android.server.telecom.ui.DisconnectedCallNotifier;
import com.android.server.telecom.ui.IncomingCallNotifier;
import com.android.server.telecom.ui.MissedCallNotifierImpl.MissedCallNotifierImplFactory;
-import com.android.server.telecom.BluetoothPhoneServiceImpl.BluetoothPhoneServiceImplFactory;
import com.android.server.telecom.CallAudioManager.AudioServiceFactory;
import com.android.server.telecom.DefaultDialerCache.DefaultDialerManagerAdapter;
import com.android.server.telecom.ui.ToastFactory;
@@ -115,7 +114,6 @@
private final CallsManager mCallsManager;
private final RespondViaSmsManager mRespondViaSmsManager;
private final Context mContext;
- private final BluetoothPhoneServiceImpl mBluetoothPhoneServiceImpl;
private final CallIntentProcessor mCallIntentProcessor;
private final TelecomBroadcastIntentProcessor mTelecomBroadcastIntentProcessor;
private final TelecomServiceImpl mTelecomServiceImpl;
@@ -192,8 +190,6 @@
ProximitySensorManagerFactory proximitySensorManagerFactory,
InCallWakeLockControllerFactory inCallWakeLockControllerFactory,
AudioServiceFactory audioServiceFactory,
- BluetoothPhoneServiceImplFactory
- bluetoothPhoneServiceImplFactory,
ConnectionServiceFocusManager.ConnectionServiceFocusManagerFactory
connectionServiceFocusManagerFactory,
Timeouts.Adapter timeoutsAdapter,
@@ -350,8 +346,6 @@
mCallsManager.onUserSwitch(currentUserHandle);
}
- mBluetoothPhoneServiceImpl = bluetoothPhoneServiceImplFactory.makeBluetoothPhoneServiceImpl(
- mContext, mLock, mCallsManager, mPhoneAccountRegistrar);
mCallIntentProcessor = new CallIntentProcessor(mContext, mCallsManager, defaultDialerCache);
mTelecomBroadcastIntentProcessor = new TelecomBroadcastIntentProcessor(
mContext, mCallsManager);
@@ -389,10 +383,6 @@
return mCallsManager;
}
- public BluetoothPhoneServiceImpl getBluetoothPhoneServiceImpl() {
- return mBluetoothPhoneServiceImpl;
- }
-
public CallIntentProcessor getCallIntentProcessor() {
return mCallIntentProcessor;
}
diff --git a/src/com/android/server/telecom/VideoProviderProxy.java b/src/com/android/server/telecom/VideoProviderProxy.java
index 364e0f4..df11403 100644
--- a/src/com/android/server/telecom/VideoProviderProxy.java
+++ b/src/com/android/server/telecom/VideoProviderProxy.java
@@ -55,6 +55,7 @@
*/
public interface Listener {
void onSessionModifyRequestReceived(Call call, VideoProfile videoProfile);
+ void onSetCamera(Call call, String cameraId);
}
/**
@@ -346,6 +347,12 @@
return;
}
}
+
+ // Inform other Telecom components of the change in camera status.
+ for (Listener listener : mListeners) {
+ listener.onSetCamera(mCall, cameraId);
+ }
+
try {
mConectionServiceVideoProvider.setCamera(cameraId, callingPackage,
targetSdkVersion);
diff --git a/src/com/android/server/telecom/components/BluetoothPhoneService.java b/src/com/android/server/telecom/components/BluetoothPhoneService.java
deleted file mode 100644
index c5e195c..0000000
--- a/src/com/android/server/telecom/components/BluetoothPhoneService.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2014 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.components;
-
-import com.android.server.telecom.TelecomSystem;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.IBinder;
-
-/**
- * Bluetooth headset manager for Telecom. This class shares the call state with the bluetooth device
- * and accepts call-related commands to perform on behalf of the BT device.
- */
-public final class BluetoothPhoneService extends Service implements TelecomSystem.Component {
-
- @Override
- public IBinder onBind(Intent intent) {
- synchronized (getTelecomSystem().getLock()) {
- return getTelecomSystem().getBluetoothPhoneServiceImpl().getBinder();
- }
- }
-
- @Override
- public TelecomSystem getTelecomSystem() {
- return TelecomSystem.getInstance();
- }
-}
diff --git a/src/com/android/server/telecom/components/TelecomService.java b/src/com/android/server/telecom/components/TelecomService.java
index 271264d..9ad0da4 100644
--- a/src/com/android/server/telecom/components/TelecomService.java
+++ b/src/com/android/server/telecom/components/TelecomService.java
@@ -18,7 +18,6 @@
import android.app.Service;
import android.app.role.RoleManager;
-import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.Intent;
import android.media.IAudioService;
@@ -35,8 +34,6 @@
import com.android.internal.telecom.ITelecomLoader;
import com.android.internal.telecom.ITelecomService;
import com.android.server.telecom.AsyncRingtonePlayer;
-import com.android.server.telecom.BluetoothAdapterProxy;
-import com.android.server.telecom.BluetoothPhoneServiceImpl;
import com.android.server.telecom.CallAudioModeStateMachine;
import com.android.server.telecom.CallAudioRouteStateMachine;
import com.android.server.telecom.CallerInfoAsyncQueryFactory;
@@ -172,17 +169,6 @@
ServiceManager.getService(Context.AUDIO_SERVICE));
}
},
- new BluetoothPhoneServiceImpl.BluetoothPhoneServiceImplFactory() {
- @Override
- public BluetoothPhoneServiceImpl makeBluetoothPhoneServiceImpl(
- Context context, TelecomSystem.SyncRoot lock,
- CallsManager callsManager,
- PhoneAccountRegistrar phoneAccountRegistrar) {
- return new BluetoothPhoneServiceImpl(context, lock,
- callsManager, new BluetoothAdapterProxy(),
- phoneAccountRegistrar);
- }
- },
ConnectionServiceFocusManager::new,
new Timeouts.Adapter(),
new AsyncRingtonePlayer(),
@@ -207,9 +193,6 @@
new ContactsAsyncHelper.Factory(),
internalServiceRetriever.getDeviceIdleController()));
}
- if (BluetoothAdapter.getDefaultAdapter() != null) {
- context.startService(new Intent(context, BluetoothPhoneService.class));
- }
}
@Override
diff --git a/tests/src/com/android/server/telecom/tests/BluetoothPhoneServiceTest.java b/tests/src/com/android/server/telecom/tests/BluetoothPhoneServiceTest.java
deleted file mode 100644
index 532cc7e..0000000
--- a/tests/src/com/android/server/telecom/tests/BluetoothPhoneServiceTest.java
+++ /dev/null
@@ -1,1136 +0,0 @@
-/*
- * Copyright (C) 2015 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.bluetooth.BluetoothAdapter;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.graphics.drawable.Icon;
-import android.net.Uri;
-import android.os.Binder;
-import android.telecom.Connection;
-import android.telecom.GatewayInfo;
-import android.telecom.PhoneAccount;
-import android.telecom.PhoneAccountHandle;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.TelephonyManager;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import com.android.server.telecom.BluetoothAdapterProxy;
-import com.android.server.telecom.BluetoothHeadsetProxy;
-import com.android.server.telecom.BluetoothPhoneServiceImpl;
-import com.android.server.telecom.Call;
-import com.android.server.telecom.CallState;
-import com.android.server.telecom.CallsManager;
-import com.android.server.telecom.PhoneAccountRegistrar;
-import com.android.server.telecom.TelecomSystem;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.LinkedList;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.nullable;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Matchers.anyChar;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Matchers.isNull;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.when;
-import static org.mockito.Mockito.verify;
-
-@RunWith(JUnit4.class)
-public class BluetoothPhoneServiceTest extends TelecomTestCase {
-
- private static final int TEST_DTMF_TONE = 0;
- private static final String TEST_ACCOUNT_ADDRESS = "//foo.com/";
- private static final int TEST_ACCOUNT_INDEX = 0;
-
- // match up with BluetoothPhoneServiceImpl
- private static final int CALL_STATE_ACTIVE = 0;
- private static final int CALL_STATE_HELD = 1;
- private static final int CALL_STATE_DIALING = 2;
- private static final int CALL_STATE_ALERTING = 3;
- private static final int CALL_STATE_INCOMING = 4;
- private static final int CALL_STATE_WAITING = 5;
- private static final int CALL_STATE_IDLE = 6;
- private static final int CALL_STATE_DISCONNECTED = 7;
- // Terminate all held or set UDUB("busy") to a waiting call
- private static final int CHLD_TYPE_RELEASEHELD = 0;
- // Terminate all active calls and accepts a waiting/held call
- private static final int CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD = 1;
- // Hold all active calls and accepts a waiting/held call
- private static final int CHLD_TYPE_HOLDACTIVE_ACCEPTHELD = 2;
- // Add all held calls to a conference
- private static final int CHLD_TYPE_ADDHELDTOCONF = 3;
-
- private BluetoothPhoneServiceImpl mBluetoothPhoneService;
- private final TelecomSystem.SyncRoot mLock = new TelecomSystem.SyncRoot() {
- };
-
- @Mock CallsManager mMockCallsManager;
- @Mock PhoneAccountRegistrar mMockPhoneAccountRegistrar;
- @Mock BluetoothHeadsetProxy mMockBluetoothHeadset;
-
- @Override
- @Before
- public void setUp() throws Exception {
- super.setUp();
- MockitoAnnotations.initMocks(this);
- mContext = mComponentContextFixture.getTestDouble().getApplicationContext();
-
- // Ensure initialization does not actually try to access any of the CallsManager fields.
- // This also works to return null if it is not overwritten later in the test.
- doNothing().when(mMockCallsManager).addListener(any(
- CallsManager.CallsManagerListener.class));
- doReturn(null).when(mMockCallsManager).getActiveCall();
- doReturn(null).when(mMockCallsManager).getRingingOrSimulatedRingingCall();
- doReturn(null).when(mMockCallsManager).getHeldCall();
- doReturn(null).when(mMockCallsManager).getOutgoingCall();
- doReturn(0).when(mMockCallsManager).getNumHeldCalls();
- doReturn(false).when(mMockCallsManager).hasOnlyDisconnectedCalls();
- mBluetoothPhoneService = new BluetoothPhoneServiceImpl(mContext, mLock, mMockCallsManager,
- mock(BluetoothAdapterProxy.class), mMockPhoneAccountRegistrar);
-
- // Bring in test Bluetooth Headset
- mBluetoothPhoneService.setBluetoothHeadset(mMockBluetoothHeadset);
- }
-
- @Override
- @After
- public void tearDown() throws Exception {
-
- mBluetoothPhoneService = null;
- super.tearDown();
- }
-
- @SmallTest
- @Test
- public void testHeadsetAnswerCall() throws Exception {
- Call mockCall = createRingingCall();
-
- boolean callAnswered = mBluetoothPhoneService.mBinder.answerCall();
-
- verify(mMockCallsManager).answerCall(eq(mockCall), any(int.class));
- assertEquals(callAnswered, true);
- }
-
- @SmallTest
- @Test
- public void testHeadsetAnswerCallNull() throws Exception {
- when(mMockCallsManager.getRingingOrSimulatedRingingCall()).thenReturn(null);
-
- boolean callAnswered = mBluetoothPhoneService.mBinder.answerCall();
-
- verify(mMockCallsManager,never()).answerCall(any(Call.class), any(int.class));
- assertEquals(callAnswered, false);
- }
-
- @SmallTest
- @Test
- public void testHeadsetHangupCall() throws Exception {
- Call mockCall = createForegroundCall();
-
- boolean callHungup = mBluetoothPhoneService.mBinder.hangupCall();
-
- verify(mMockCallsManager).disconnectCall(eq(mockCall));
- assertEquals(callHungup, true);
- }
-
- @SmallTest
- @Test
- public void testHeadsetHangupCallNull() throws Exception {
- when(mMockCallsManager.getForegroundCall()).thenReturn(null);
-
- boolean callHungup = mBluetoothPhoneService.mBinder.hangupCall();
-
- verify(mMockCallsManager,never()).disconnectCall(any(Call.class));
- assertEquals(callHungup, false);
- }
-
- @SmallTest
- @Test
- public void testHeadsetSendDTMF() throws Exception {
- Call mockCall = createForegroundCall();
-
- boolean sentDtmf = mBluetoothPhoneService.mBinder.sendDtmf(TEST_DTMF_TONE);
-
- verify(mMockCallsManager).playDtmfTone(eq(mockCall), eq((char) TEST_DTMF_TONE));
- verify(mMockCallsManager).stopDtmfTone(eq(mockCall));
- assertEquals(sentDtmf, true);
- }
-
- @SmallTest
- @Test
- public void testHeadsetSendDTMFNull() throws Exception {
- when(mMockCallsManager.getForegroundCall()).thenReturn(null);
-
- boolean sentDtmf = mBluetoothPhoneService.mBinder.sendDtmf(TEST_DTMF_TONE);
-
- verify(mMockCallsManager,never()).playDtmfTone(any(Call.class), anyChar());
- verify(mMockCallsManager,never()).stopDtmfTone(any(Call.class));
- assertEquals(sentDtmf, false);
- }
-
- @SmallTest
- @Test
- public void testGetNetworkOperator() throws Exception {
- Call mockCall = createForegroundCall();
- PhoneAccount fakePhoneAccount = makeQuickAccount("id0", TEST_ACCOUNT_INDEX);
- when(mMockPhoneAccountRegistrar.getPhoneAccountOfCurrentUser(
- nullable(PhoneAccountHandle.class))).thenReturn(fakePhoneAccount);
-
- String networkOperator = mBluetoothPhoneService.mBinder.getNetworkOperator();
-
- assertEquals(networkOperator, "label0");
- }
-
- @SmallTest
- @Test
- public void testGetNetworkOperatorNoPhoneAccount() throws Exception {
- when(mMockCallsManager.getForegroundCall()).thenReturn(null);
-
- String networkOperator = mBluetoothPhoneService.mBinder.getNetworkOperator();
-
- assertEquals(networkOperator, "label1");
- }
-
- @SmallTest
- @Test
- public void testGetSubscriberNumber() throws Exception {
- Call mockCall = createForegroundCall();
- PhoneAccount fakePhoneAccount = makeQuickAccount("id0", TEST_ACCOUNT_INDEX);
- when(mMockPhoneAccountRegistrar.getPhoneAccountOfCurrentUser(
- nullable(PhoneAccountHandle.class))).thenReturn(fakePhoneAccount);
-
- String subscriberNumber = mBluetoothPhoneService.mBinder.getSubscriberNumber();
-
- assertEquals(subscriberNumber, TEST_ACCOUNT_ADDRESS + TEST_ACCOUNT_INDEX);
- }
-
- @SmallTest
- @Test
- public void testGetSubscriberNumberFallbackToTelephony() throws Exception {
- Call mockCall = createForegroundCall();
- String fakeNumber = "8675309";
- when(mMockPhoneAccountRegistrar.getPhoneAccountOfCurrentUser(
- nullable(PhoneAccountHandle.class))).thenReturn(null);
- when(mMockPhoneAccountRegistrar.getPhoneAccountUnchecked(
- nullable(PhoneAccountHandle.class))).thenReturn(null);
- when(mComponentContextFixture.getTelephonyManager().getLine1Number())
- .thenReturn(fakeNumber);
-
- String subscriberNumber = mBluetoothPhoneService.mBinder.getSubscriberNumber();
-
- assertEquals(subscriberNumber, fakeNumber);
- }
-
- @MediumTest
- @Test
- public void testListCurrentCallsOneCall() throws Exception {
- ArrayList<Call> calls = new ArrayList<>();
- Call activeCall = createActiveCall();
- when(activeCall.getState()).thenReturn(CallState.ACTIVE);
- calls.add(activeCall);
- when(activeCall.isConference()).thenReturn(false);
- when(activeCall.getHandle()).thenReturn(Uri.parse("tel:555-000"));
- when(mMockCallsManager.getCalls()).thenReturn(calls);
-
- mBluetoothPhoneService.mBinder.listCurrentCalls();
-
- verify(mMockBluetoothHeadset).clccResponse(eq(1), eq(0), eq(0), eq(0), eq(false),
- eq("555000"), eq(PhoneNumberUtils.TOA_Unknown));
- verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
- }
-
- @MediumTest
- @Test
- public void testListCurrentCallsSilentRinging() throws Exception {
- ArrayList<Call> calls = new ArrayList<>();
- Call silentRingingCall = createActiveCall();
- when(silentRingingCall.getState()).thenReturn(CallState.RINGING);
- when(silentRingingCall.isSilentRingingRequested()).thenReturn(true);
- calls.add(silentRingingCall);
- when(silentRingingCall.isConference()).thenReturn(false);
- when(silentRingingCall.getHandle()).thenReturn(Uri.parse("tel:555-000"));
- when(mMockCallsManager.getCalls()).thenReturn(calls);
- when(mMockCallsManager.getRingingOrSimulatedRingingCall()).thenReturn(silentRingingCall);
-
- mBluetoothPhoneService.mBinder.listCurrentCalls();
-
- verify(mMockBluetoothHeadset, never()).clccResponse(eq(1), eq(0), eq(0), eq(0), eq(false),
- eq("555000"), eq(PhoneNumberUtils.TOA_Unknown));
- verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
- }
-
- @MediumTest
- @Test
- public void testConferenceInProgressCDMA() throws Exception {
- // If two calls are being conferenced and updateHeadsetWithCallState runs while this is
- // still occuring, it will look like there is an active and held call still while we are
- // transitioning into a conference.
- // Call has been put into a CDMA "conference" with one call on hold.
- ArrayList<Call> calls = new ArrayList<>();
- Call parentCall = createActiveCall();
- final Call confCall1 = mock(Call.class);
- final Call confCall2 = createHeldCall();
- calls.add(parentCall);
- calls.add(confCall1);
- calls.add(confCall2);
- when(mMockCallsManager.getCalls()).thenReturn(calls);
- when(confCall1.getState()).thenReturn(CallState.ACTIVE);
- when(confCall2.getState()).thenReturn(CallState.ACTIVE);
- when(confCall1.isIncoming()).thenReturn(false);
- when(confCall2.isIncoming()).thenReturn(true);
- when(confCall1.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
- Uri.parse("tel:555-0000")));
- when(confCall2.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
- Uri.parse("tel:555-0001")));
- addCallCapability(parentCall, Connection.CAPABILITY_MERGE_CONFERENCE);
- addCallCapability(parentCall, Connection.CAPABILITY_SWAP_CONFERENCE);
- removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
- when(parentCall.getConferenceLevelActiveCall()).thenReturn(confCall1);
- when(parentCall.isConference()).thenReturn(true);
- when(parentCall.getChildCalls()).thenReturn(new LinkedList<Call>() {{
- add(confCall1);
- add(confCall2);
- }});
- //Add links from child calls to parent
- when(confCall1.getParentCall()).thenReturn(parentCall);
- when(confCall2.getParentCall()).thenReturn(parentCall);
-
- mBluetoothPhoneService.mBinder.queryPhoneState();
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(1), eq(CALL_STATE_IDLE),
- eq(""), eq(128), nullable(String.class));
- when(parentCall.wasConferencePreviouslyMerged()).thenReturn(true);
- mBluetoothPhoneService.mCallsManagerListener.onIsConferencedChanged(parentCall);
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(0), eq(CALL_STATE_IDLE),
- eq(""), eq(128), nullable(String.class));
- when(mMockCallsManager.getHeldCall()).thenReturn(null);
- // Spurious call to onIsConferencedChanged.
- mBluetoothPhoneService.mCallsManagerListener.onIsConferencedChanged(parentCall);
- // Make sure the call has only occurred collectively 2 times (not on the third)
- verify(mMockBluetoothHeadset, times(2)).phoneStateChanged(any(int.class),
- any(int.class), any(int.class), nullable(String.class), any(int.class),
- nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testListCurrentCallsCdmaHold() throws Exception {
- // Call has been put into a CDMA "conference" with one call on hold.
- ArrayList<Call> calls = new ArrayList<>();
- Call parentCall = createActiveCall();
- final Call foregroundCall = mock(Call.class);
- final Call heldCall = createHeldCall();
- calls.add(parentCall);
- calls.add(foregroundCall);
- calls.add(heldCall);
- when(mMockCallsManager.getCalls()).thenReturn(calls);
- when(foregroundCall.getState()).thenReturn(CallState.ACTIVE);
- when(heldCall.getState()).thenReturn(CallState.ACTIVE);
- when(foregroundCall.isIncoming()).thenReturn(false);
- when(heldCall.isIncoming()).thenReturn(true);
- when(foregroundCall.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
- Uri.parse("tel:555-0000")));
- when(heldCall.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
- Uri.parse("tel:555-0001")));
- addCallCapability(parentCall, Connection.CAPABILITY_MERGE_CONFERENCE);
- addCallCapability(parentCall, Connection.CAPABILITY_SWAP_CONFERENCE);
- removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
- when(parentCall.getConferenceLevelActiveCall()).thenReturn(foregroundCall);
- when(parentCall.isConference()).thenReturn(true);
- when(parentCall.getChildCalls()).thenReturn(new LinkedList<Call>() {{
- add(foregroundCall);
- add(heldCall);
- }});
- //Add links from child calls to parent
- when(foregroundCall.getParentCall()).thenReturn(parentCall);
- when(heldCall.getParentCall()).thenReturn(parentCall);
-
- mBluetoothPhoneService.mBinder.listCurrentCalls();
-
- verify(mMockBluetoothHeadset).clccResponse(eq(1), eq(0), eq(CALL_STATE_ACTIVE), eq(0),
- eq(false), eq("5550000"), eq(PhoneNumberUtils.TOA_Unknown));
- verify(mMockBluetoothHeadset).clccResponse(eq(2), eq(1), eq(CALL_STATE_HELD), eq(0),
- eq(false), eq("5550001"), eq(PhoneNumberUtils.TOA_Unknown));
- verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
- }
-
- @MediumTest
- @Test
- public void testListCurrentCallsCdmaConference() throws Exception {
- // Call is in a true CDMA conference
- ArrayList<Call> calls = new ArrayList<>();
- Call parentCall = createActiveCall();
- final Call confCall1 = mock(Call.class);
- final Call confCall2 = createHeldCall();
- calls.add(parentCall);
- calls.add(confCall1);
- calls.add(confCall2);
- when(mMockCallsManager.getCalls()).thenReturn(calls);
- when(confCall1.getState()).thenReturn(CallState.ACTIVE);
- when(confCall2.getState()).thenReturn(CallState.ACTIVE);
- when(confCall1.isIncoming()).thenReturn(false);
- when(confCall2.isIncoming()).thenReturn(true);
- when(confCall1.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
- Uri.parse("tel:555-0000")));
- when(confCall2.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
- Uri.parse("tel:555-0001")));
- removeCallCapability(parentCall, Connection.CAPABILITY_MERGE_CONFERENCE);
- removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
- when(parentCall.wasConferencePreviouslyMerged()).thenReturn(true);
- when(parentCall.getConferenceLevelActiveCall()).thenReturn(confCall1);
- when(parentCall.isConference()).thenReturn(true);
- when(parentCall.getChildCalls()).thenReturn(new LinkedList<Call>() {{
- add(confCall1);
- add(confCall2);
- }});
- //Add links from child calls to parent
- when(confCall1.getParentCall()).thenReturn(parentCall);
- when(confCall2.getParentCall()).thenReturn(parentCall);
-
- mBluetoothPhoneService.mBinder.listCurrentCalls();
-
- verify(mMockBluetoothHeadset).clccResponse(eq(1), eq(0), eq(CALL_STATE_ACTIVE), eq(0),
- eq(true), eq("5550000"), eq(PhoneNumberUtils.TOA_Unknown));
- verify(mMockBluetoothHeadset).clccResponse(eq(2), eq(1), eq(CALL_STATE_ACTIVE), eq(0),
- eq(true), eq("5550001"), eq(PhoneNumberUtils.TOA_Unknown));
- verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
- }
-
- @MediumTest
- @Test
- public void testWaitingCallClccResponse() throws Exception {
- ArrayList<Call> calls = new ArrayList<>();
- when(mMockCallsManager.getCalls()).thenReturn(calls);
- // This test does not define a value for getForegroundCall(), so this ringing call will
- // be treated as if it is a waiting call when listCurrentCalls() is invoked.
- Call waitingCall = createRingingCall();
- calls.add(waitingCall);
- when(waitingCall.isIncoming()).thenReturn(true);
- when(waitingCall.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
- Uri.parse("tel:555-0000")));
- when(waitingCall.getState()).thenReturn(CallState.RINGING);
- when(waitingCall.isConference()).thenReturn(false);
-
- mBluetoothPhoneService.mBinder.listCurrentCalls();
- verify(mMockBluetoothHeadset).clccResponse(1, 1, CALL_STATE_WAITING, 0, false,
- "5550000", PhoneNumberUtils.TOA_Unknown);
- verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
- verify(mMockBluetoothHeadset, times(2)).clccResponse(anyInt(),
- anyInt(), anyInt(), anyInt(), anyBoolean(), nullable(String.class), anyInt());
- }
-
- @MediumTest
- @Test
- public void testNewCallClccResponse() throws Exception {
- ArrayList<Call> calls = new ArrayList<>();
- when(mMockCallsManager.getCalls()).thenReturn(calls);
- Call newCall = createForegroundCall();
- calls.add(newCall);
- when(newCall.getState()).thenReturn(CallState.NEW);
- when(newCall.isConference()).thenReturn(false);
-
- mBluetoothPhoneService.mBinder.listCurrentCalls();
- verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
- verify(mMockBluetoothHeadset, times(1)).clccResponse(anyInt(),
- anyInt(), anyInt(), anyInt(), anyBoolean(), nullable(String.class), anyInt());
- }
-
- @MediumTest
- @Test
- public void testRingingCallClccResponse() throws Exception {
- ArrayList<Call> calls = new ArrayList<>();
- when(mMockCallsManager.getCalls()).thenReturn(calls);
- Call ringingCall = createForegroundCall();
- calls.add(ringingCall);
- when(ringingCall.getState()).thenReturn(CallState.RINGING);
- when(ringingCall.isIncoming()).thenReturn(true);
- when(ringingCall.isConference()).thenReturn(false);
- when(ringingCall.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
- Uri.parse("tel:555-0000")));
-
- mBluetoothPhoneService.mBinder.listCurrentCalls();
- verify(mMockBluetoothHeadset).clccResponse(1, 1, CALL_STATE_INCOMING, 0, false,
- "5550000", PhoneNumberUtils.TOA_Unknown);
- verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
- verify(mMockBluetoothHeadset, times(2)).clccResponse(anyInt(),
- anyInt(), anyInt(), anyInt(), anyBoolean(), nullable(String.class), anyInt());
- }
-
- @MediumTest
- @Test
- public void testCallClccCache() throws Exception {
- ArrayList<Call> calls = new ArrayList<>();
- when(mMockCallsManager.getCalls()).thenReturn(calls);
- Call ringingCall = createForegroundCall();
- calls.add(ringingCall);
- when(ringingCall.getState()).thenReturn(CallState.RINGING);
- when(ringingCall.isIncoming()).thenReturn(true);
- when(ringingCall.isConference()).thenReturn(false);
- when(ringingCall.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
- Uri.parse("tel:5550000")));
-
- mBluetoothPhoneService.mBinder.listCurrentCalls();
- verify(mMockBluetoothHeadset).clccResponse(1, 1, CALL_STATE_INCOMING, 0, false,
- "5550000", PhoneNumberUtils.TOA_Unknown);
-
- // Test Caching of old call indicies in clcc
- when(ringingCall.getState()).thenReturn(CallState.ACTIVE);
- Call newHoldingCall = createHeldCall();
- calls.add(0, newHoldingCall);
- when(newHoldingCall.getState()).thenReturn(CallState.ON_HOLD);
- when(newHoldingCall.isIncoming()).thenReturn(true);
- when(newHoldingCall.isConference()).thenReturn(false);
- when(newHoldingCall.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
- Uri.parse("tel:555-0001")));
-
- mBluetoothPhoneService.mBinder.listCurrentCalls();
- verify(mMockBluetoothHeadset).clccResponse(1, 1, CALL_STATE_ACTIVE, 0, false,
- "5550000", PhoneNumberUtils.TOA_Unknown);
- verify(mMockBluetoothHeadset).clccResponse(2, 1, CALL_STATE_HELD, 0, false,
- "5550001", PhoneNumberUtils.TOA_Unknown);
- verify(mMockBluetoothHeadset, times(2)).clccResponse(0, 0, 0, 0, false, null, 0);
- }
-
- @MediumTest
- @Test
- public void testAlertingCallClccResponse() throws Exception {
- ArrayList<Call> calls = new ArrayList<>();
- when(mMockCallsManager.getCalls()).thenReturn(calls);
- Call dialingCall = createForegroundCall();
- calls.add(dialingCall);
- when(dialingCall.getState()).thenReturn(CallState.DIALING);
- when(dialingCall.isIncoming()).thenReturn(false);
- when(dialingCall.isConference()).thenReturn(false);
- when(dialingCall.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
- Uri.parse("tel:555-0000")));
-
- mBluetoothPhoneService.mBinder.listCurrentCalls();
- verify(mMockBluetoothHeadset).clccResponse(1, 0, CALL_STATE_ALERTING, 0, false,
- "5550000", PhoneNumberUtils.TOA_Unknown);
- verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
- verify(mMockBluetoothHeadset, times(2)).clccResponse(anyInt(),
- anyInt(), anyInt(), anyInt(), anyBoolean(), nullable(String.class), anyInt());
- }
-
- @MediumTest
- @Test
- public void testHoldingCallClccResponse() throws Exception {
- ArrayList<Call> calls = new ArrayList<>();
- when(mMockCallsManager.getCalls()).thenReturn(calls);
- Call dialingCall = createForegroundCall();
- calls.add(dialingCall);
- when(dialingCall.getState()).thenReturn(CallState.DIALING);
- when(dialingCall.isIncoming()).thenReturn(false);
- when(dialingCall.isConference()).thenReturn(false);
- when(dialingCall.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
- Uri.parse("tel:555-0000")));
- Call holdingCall = createHeldCall();
- calls.add(holdingCall);
- when(holdingCall.getState()).thenReturn(CallState.ON_HOLD);
- when(holdingCall.isIncoming()).thenReturn(true);
- when(holdingCall.isConference()).thenReturn(false);
- when(holdingCall.getGatewayInfo()).thenReturn(new GatewayInfo(null, null,
- Uri.parse("tel:555-0001")));
-
- mBluetoothPhoneService.mBinder.listCurrentCalls();
- verify(mMockBluetoothHeadset).clccResponse(1, 0, CALL_STATE_ALERTING, 0, false,
- "5550000", PhoneNumberUtils.TOA_Unknown);
- verify(mMockBluetoothHeadset).clccResponse(2, 1, CALL_STATE_HELD, 0, false,
- "5550001", PhoneNumberUtils.TOA_Unknown);
- verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
- verify(mMockBluetoothHeadset, times(3)).clccResponse(anyInt(),
- anyInt(), anyInt(), anyInt(), anyBoolean(), nullable(String.class), anyInt());
- }
-
- @MediumTest
- @Test
- public void testListCurrentCallsImsConference() throws Exception {
- ArrayList<Call> calls = new ArrayList<>();
- Call parentCall = createActiveCall();
- calls.add(parentCall);
- addCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
- when(parentCall.isConference()).thenReturn(true);
- when(parentCall.getState()).thenReturn(CallState.ACTIVE);
- when(parentCall.isIncoming()).thenReturn(true);
- when(mMockCallsManager.getCalls()).thenReturn(calls);
-
- mBluetoothPhoneService.mBinder.listCurrentCalls();
-
- verify(mMockBluetoothHeadset).clccResponse(eq(1), eq(1), eq(CALL_STATE_ACTIVE), eq(0),
- eq(true), (String) isNull(), eq(-1));
- verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
- }
-
- @MediumTest
- @Test
- public void testListCurrentCallsHeldImsCepConference() throws Exception {
- ArrayList<Call> calls = new ArrayList<>();
- Call parentCall = createHeldCall();
- Call childCall1 = createActiveCall();
- Call childCall2 = createActiveCall();
- calls.add(parentCall);
- calls.add(childCall1);
- calls.add(childCall2);
- addCallCapability(parentCall, Connection.CAPABILITY_MANAGE_CONFERENCE);
- when(childCall1.getParentCall()).thenReturn(parentCall);
- when(childCall2.getParentCall()).thenReturn(parentCall);
-
- when(parentCall.isConference()).thenReturn(true);
- when(parentCall.getState()).thenReturn(CallState.ON_HOLD);
- when(childCall1.getState()).thenReturn(CallState.ACTIVE);
- when(childCall2.getState()).thenReturn(CallState.ACTIVE);
-
- when(parentCall.isIncoming()).thenReturn(true);
- when(mMockCallsManager.getCalls()).thenReturn(calls);
-
- mBluetoothPhoneService.mBinder.listCurrentCalls();
-
- verify(mMockBluetoothHeadset).clccResponse(eq(1), eq(0), eq(CALL_STATE_HELD), eq(0),
- eq(true), (String) isNull(), eq(-1));
- verify(mMockBluetoothHeadset).clccResponse(eq(2), eq(0), eq(CALL_STATE_HELD), eq(0),
- eq(true), (String) isNull(), eq(-1));
- verify(mMockBluetoothHeadset).clccResponse(0, 0, 0, 0, false, null, 0);
- }
-
- @MediumTest
- @Test
- public void testQueryPhoneState() throws Exception {
- Call ringingCall = createRingingCall();
- when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:5550000"));
-
- mBluetoothPhoneService.mBinder.queryPhoneState();
-
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_INCOMING),
- eq("5550000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testCDMAConferenceQueryState() throws Exception {
- Call parentConfCall = createActiveCall();
- final Call confCall1 = mock(Call.class);
- final Call confCall2 = mock(Call.class);
- when(parentConfCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
- addCallCapability(parentConfCall, Connection.CAPABILITY_SWAP_CONFERENCE);
- removeCallCapability(parentConfCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
- when(parentConfCall.wasConferencePreviouslyMerged()).thenReturn(true);
- when(parentConfCall.isConference()).thenReturn(true);
- when(parentConfCall.getChildCalls()).thenReturn(new LinkedList<Call>() {{
- add(confCall1);
- add(confCall2);
- }});
-
- mBluetoothPhoneService.mBinder.queryPhoneState();
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(0), eq(CALL_STATE_IDLE),
- eq(""), eq(128), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testProcessChldTypeReleaseHeldRinging() throws Exception {
- Call ringingCall = createRingingCall();
-
- boolean didProcess = mBluetoothPhoneService.mBinder.processChld(CHLD_TYPE_RELEASEHELD);
-
- verify(mMockCallsManager).rejectCall(eq(ringingCall), eq(false), nullable(String.class));
- assertEquals(didProcess, true);
- }
-
- @MediumTest
- @Test
- public void testProcessChldTypeReleaseHeldHold() throws Exception {
- Call onHoldCall = createHeldCall();
-
- boolean didProcess = mBluetoothPhoneService.mBinder.processChld(CHLD_TYPE_RELEASEHELD);
-
- verify(mMockCallsManager).disconnectCall(eq(onHoldCall));
- assertEquals(didProcess, true);
- }
-
- @MediumTest
- @Test
- public void testProcessChldReleaseActiveRinging() throws Exception {
- Call activeCall = createActiveCall();
- Call ringingCall = createRingingCall();
-
- boolean didProcess = mBluetoothPhoneService.mBinder.processChld(
- CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD);
-
- verify(mMockCallsManager).disconnectCall(eq(activeCall));
- verify(mMockCallsManager).answerCall(eq(ringingCall), any(int.class));
- assertEquals(didProcess, true);
- }
-
- @MediumTest
- @Test
- public void testProcessChldReleaseActiveHold() throws Exception {
- Call activeCall = createActiveCall();
- Call heldCall = createHeldCall();
-
- boolean didProcess = mBluetoothPhoneService.mBinder.processChld(
- CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD);
-
- verify(mMockCallsManager).disconnectCall(eq(activeCall));
- // Call unhold will occur as part of CallsManager auto-unholding the background call on its
- // own.
- assertEquals(didProcess, true);
- }
-
- @MediumTest
- @Test
- public void testProcessChldHoldActiveRinging() throws Exception {
- Call ringingCall = createRingingCall();
-
- boolean didProcess = mBluetoothPhoneService.mBinder.processChld(
- CHLD_TYPE_HOLDACTIVE_ACCEPTHELD);
-
- verify(mMockCallsManager).answerCall(eq(ringingCall), any(int.class));
- assertEquals(didProcess, true);
- }
-
- @MediumTest
- @Test
- public void testProcessChldHoldActiveUnhold() throws Exception {
- Call heldCall = createHeldCall();
-
- boolean didProcess = mBluetoothPhoneService.mBinder.processChld(
- CHLD_TYPE_HOLDACTIVE_ACCEPTHELD);
-
- verify(mMockCallsManager).unholdCall(eq(heldCall));
- assertEquals(didProcess, true);
- }
-
- @MediumTest
- @Test
- public void testProcessChldHoldActiveHold() throws Exception {
- Call activeCall = createActiveCall();
- addCallCapability(activeCall, Connection.CAPABILITY_HOLD);
-
- boolean didProcess = mBluetoothPhoneService.mBinder.processChld(
- CHLD_TYPE_HOLDACTIVE_ACCEPTHELD);
-
- verify(mMockCallsManager).holdCall(eq(activeCall));
- assertEquals(didProcess, true);
- }
-
- @MediumTest
- @Test
- public void testProcessChldAddHeldToConfHolding() throws Exception {
- Call activeCall = createActiveCall();
- addCallCapability(activeCall, Connection.CAPABILITY_MERGE_CONFERENCE);
-
- boolean didProcess = mBluetoothPhoneService.mBinder.processChld(CHLD_TYPE_ADDHELDTOCONF);
-
- verify(activeCall).mergeConference();
- assertEquals(didProcess, true);
- }
-
- @MediumTest
- @Test
- public void testProcessChldAddHeldToConf() throws Exception {
- Call activeCall = createActiveCall();
- removeCallCapability(activeCall, Connection.CAPABILITY_MERGE_CONFERENCE);
- Call conferenceableCall = mock(Call.class);
- ArrayList<Call> conferenceableCalls = new ArrayList<>();
- conferenceableCalls.add(conferenceableCall);
- when(activeCall.getConferenceableCalls()).thenReturn(conferenceableCalls);
-
- boolean didProcess = mBluetoothPhoneService.mBinder.processChld(CHLD_TYPE_ADDHELDTOCONF);
-
- verify(mMockCallsManager).conference(activeCall, conferenceableCall);
- assertEquals(didProcess, true);
- }
-
- @MediumTest
- @Test
- public void testProcessChldHoldActiveSwapConference() throws Exception {
- // Create an active CDMA Call with a call on hold and simulate a swapConference().
- Call parentCall = createActiveCall();
- final Call foregroundCall = mock(Call.class);
- final Call heldCall = createHeldCall();
- addCallCapability(parentCall, Connection.CAPABILITY_SWAP_CONFERENCE);
- removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
- when(parentCall.isConference()).thenReturn(true);
- when(parentCall.wasConferencePreviouslyMerged()).thenReturn(false);
- when(parentCall.getChildCalls()).thenReturn(new LinkedList<Call>() {{
- add(foregroundCall);
- add(heldCall);
- }});
-
- boolean didProcess = mBluetoothPhoneService.mBinder.processChld(
- CHLD_TYPE_HOLDACTIVE_ACCEPTHELD);
-
- verify(parentCall).swapConference();
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(1), eq(CALL_STATE_IDLE), eq(""),
- eq(128), nullable(String.class));
- assertEquals(didProcess, true);
- }
-
- // Testing the CallsManager Listener Functionality on Bluetooth
- @MediumTest
- @Test
- public void testOnCallAddedRinging() throws Exception {
- Call ringingCall = createRingingCall();
- when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:555000"));
-
- mBluetoothPhoneService.mCallsManagerListener.onCallAdded(ringingCall);
-
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_INCOMING),
- eq("555000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testSilentRingingCallState() throws Exception {
- Call ringingCall = createRingingCall();
- when(ringingCall.isSilentRingingRequested()).thenReturn(true);
- when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:555000"));
-
- mBluetoothPhoneService.mCallsManagerListener.onCallAdded(ringingCall);
-
- verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
- anyString(), anyInt(), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testOnCallAddedCdmaActiveHold() throws Exception {
- // Call has been put into a CDMA "conference" with one call on hold.
- Call parentCall = createActiveCall();
- final Call foregroundCall = mock(Call.class);
- final Call heldCall = createHeldCall();
- addCallCapability(parentCall, Connection.CAPABILITY_MERGE_CONFERENCE);
- removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
- when(parentCall.isConference()).thenReturn(true);
- when(parentCall.getChildCalls()).thenReturn(new LinkedList<Call>() {{
- add(foregroundCall);
- add(heldCall);
- }});
-
- mBluetoothPhoneService.mCallsManagerListener.onCallAdded(parentCall);
-
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(1), eq(CALL_STATE_IDLE),
- eq(""), eq(128), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testOnCallRemoved() throws Exception {
- Call activeCall = createActiveCall();
- mBluetoothPhoneService.mCallsManagerListener.onCallAdded(activeCall);
- doReturn(null).when(mMockCallsManager).getActiveCall();
- mBluetoothPhoneService.mCallsManagerListener.onCallRemoved(activeCall);
-
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_IDLE),
- eq(""), eq(128), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testOnCallStateChangedConnectingCall() throws Exception {
- Call activeCall = mock(Call.class);
- Call connectingCall = mock(Call.class);
- when(connectingCall.getState()).thenReturn(CallState.CONNECTING);
- ArrayList<Call> calls = new ArrayList<>();
- calls.add(connectingCall);
- calls.add(activeCall);
- when(mMockCallsManager.getCalls()).thenReturn(calls);
-
- mBluetoothPhoneService.mCallsManagerListener.onCallStateChanged(activeCall,
- CallState.ACTIVE, CallState.ON_HOLD);
-
- verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
- anyString(), anyInt(), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testOnCallAddedAudioProcessing() throws Exception {
- Call call = mock(Call.class);
- when(call.getState()).thenReturn(CallState.AUDIO_PROCESSING);
- mBluetoothPhoneService.mCallsManagerListener.onCallAdded(call);
-
- verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
- anyString(), anyInt(), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testOnCallStateChangedRingingToAudioProcessing() throws Exception {
- Call ringingCall = createRingingCall();
- when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:555000"));
-
- mBluetoothPhoneService.mCallsManagerListener.onCallAdded(ringingCall);
-
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_INCOMING),
- eq("555000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
-
- when(ringingCall.getState()).thenReturn(CallState.AUDIO_PROCESSING);
- when(mMockCallsManager.getRingingOrSimulatedRingingCall()).thenReturn(null);
-
- mBluetoothPhoneService.mCallsManagerListener.onCallStateChanged(ringingCall,
- CallState.RINGING, CallState.AUDIO_PROCESSING);
-
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_IDLE),
- eq(""), eq(128), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testOnCallStateChangedAudioProcessingToSimulatedRinging() throws Exception {
- Call ringingCall = createRingingCall();
- when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
-
- mBluetoothPhoneService.mCallsManagerListener.onCallStateChanged(ringingCall,
- CallState.AUDIO_PROCESSING, CallState.SIMULATED_RINGING);
-
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_INCOMING),
- eq("555-0000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testOnCallStateChangedAudioProcessingToActive() throws Exception {
- Call activeCall = createActiveCall();
- when(activeCall.getState()).thenReturn(CallState.ACTIVE);
-
- mBluetoothPhoneService.mCallsManagerListener.onCallStateChanged(activeCall,
- CallState.AUDIO_PROCESSING, CallState.ACTIVE);
-
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(0), eq(CALL_STATE_IDLE),
- eq(""), eq(128), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testOnCallStateChangedDialing() throws Exception {
- Call activeCall = createActiveCall();
-
- mBluetoothPhoneService.mCallsManagerListener.onCallStateChanged(activeCall,
- CallState.CONNECTING, CallState.DIALING);
-
- verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
- anyString(), anyInt(), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testOnCallStateChangedAlerting() throws Exception {
- Call outgoingCall = createOutgoingCall();
-
- mBluetoothPhoneService.mCallsManagerListener.onCallStateChanged(outgoingCall,
- CallState.NEW, CallState.DIALING);
-
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_DIALING),
- eq(""), eq(128), nullable(String.class));
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_ALERTING),
- eq(""), eq(128), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testOnCallStateChangedDisconnected() throws Exception {
- Call disconnectedCall = createDisconnectedCall();
- doReturn(true).when(mMockCallsManager).hasOnlyDisconnectedCalls();
- mBluetoothPhoneService.mCallsManagerListener.onCallStateChanged(disconnectedCall,
- CallState.DISCONNECTING, CallState.DISCONNECTED);
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_DISCONNECTED),
- eq(""), eq(128), nullable(String.class));
-
- doReturn(false).when(mMockCallsManager).hasOnlyDisconnectedCalls();
- mBluetoothPhoneService.mCallsManagerListener.onDisconnectedTonePlaying(true);
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_DISCONNECTED),
- eq(""), eq(128), nullable(String.class));
-
- mBluetoothPhoneService.mCallsManagerListener.onDisconnectedTonePlaying(false);
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_IDLE),
- eq(""), eq(128), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testOnCallStateChanged() throws Exception {
- Call ringingCall = createRingingCall();
- when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
- mBluetoothPhoneService.mCallsManagerListener.onCallAdded(ringingCall);
-
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_INCOMING),
- eq("555-0000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
-
- //Switch to active
- doReturn(null).when(mMockCallsManager).getRingingOrSimulatedRingingCall();
- when(mMockCallsManager.getActiveCall()).thenReturn(ringingCall);
-
- mBluetoothPhoneService.mCallsManagerListener.onCallStateChanged(ringingCall,
- CallState.RINGING, CallState.ACTIVE);
-
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(0), eq(CALL_STATE_IDLE),
- eq(""), eq(128), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testOnCallStateChangedGSMSwap() throws Exception {
- Call heldCall = createHeldCall();
- when(heldCall.getHandle()).thenReturn(Uri.parse("tel:555-0000"));
- doReturn(2).when(mMockCallsManager).getNumHeldCalls();
- mBluetoothPhoneService.mCallsManagerListener.onCallStateChanged(heldCall,
- CallState.ACTIVE, CallState.ON_HOLD);
-
- verify(mMockBluetoothHeadset, never()).phoneStateChanged(eq(0), eq(2), eq(CALL_STATE_HELD),
- eq("5550000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testOnIsConferencedChanged() throws Exception {
- // Start with two calls that are being merged into a CDMA conference call. The
- // onIsConferencedChanged method will be called multiple times during the call. Make sure
- // that the bluetooth phone state is updated properly.
- Call parentCall = createActiveCall();
- Call activeCall = mock(Call.class);
- Call heldCall = createHeldCall();
- when(activeCall.getParentCall()).thenReturn(parentCall);
- when(heldCall.getParentCall()).thenReturn(parentCall);
- ArrayList<Call> calls = new ArrayList<>();
- calls.add(activeCall);
- when(parentCall.getChildCalls()).thenReturn(calls);
- when(parentCall.isConference()).thenReturn(true);
- removeCallCapability(parentCall, Connection.CAPABILITY_CONFERENCE_HAS_NO_CHILDREN);
- addCallCapability(parentCall, Connection.CAPABILITY_SWAP_CONFERENCE);
- when(parentCall.wasConferencePreviouslyMerged()).thenReturn(false);
-
- // Be sure that onIsConferencedChanged rejects spurious changes during set up of
- // CDMA "conference"
- mBluetoothPhoneService.mCallsManagerListener.onIsConferencedChanged(activeCall);
- verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
- anyString(), anyInt(), nullable(String.class));
- mBluetoothPhoneService.mCallsManagerListener.onIsConferencedChanged(heldCall);
- verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
- anyString(), anyInt(), nullable(String.class));
- mBluetoothPhoneService.mCallsManagerListener.onIsConferencedChanged(parentCall);
- verify(mMockBluetoothHeadset, never()).phoneStateChanged(anyInt(), anyInt(), anyInt(),
- anyString(), anyInt(), nullable(String.class));
-
- calls.add(heldCall);
- mBluetoothPhoneService.mCallsManagerListener.onIsConferencedChanged(parentCall);
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(1), eq(1), eq(CALL_STATE_IDLE),
- eq(""), eq(128), nullable(String.class));
- }
-
- @MediumTest
- @Test
- public void testBluetoothAdapterReceiver() throws Exception {
- Call ringingCall = createRingingCall();
- when(ringingCall.getHandle()).thenReturn(Uri.parse("tel:5550000"));
-
- Intent intent = new Intent();
- intent.putExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_ON);
- mBluetoothPhoneService.mBluetoothAdapterReceiver.onReceive(mContext, intent);
-
- verify(mMockBluetoothHeadset).phoneStateChanged(eq(0), eq(0), eq(CALL_STATE_INCOMING),
- eq("5550000"), eq(PhoneNumberUtils.TOA_Unknown), nullable(String.class));
- }
-
- private void addCallCapability(Call call, int capability) {
- when(call.can(capability)).thenReturn(true);
- }
-
- private void removeCallCapability(Call call, int capability) {
- when(call.can(capability)).thenReturn(false);
- }
-
- private Call createActiveCall() {
- Call call = mock(Call.class);
- when(mMockCallsManager.getActiveCall()).thenReturn(call);
- return call;
- }
-
- private Call createRingingCall() {
- Call call = mock(Call.class);
- when(mMockCallsManager.getRingingOrSimulatedRingingCall()).thenReturn(call);
- return call;
- }
-
- private Call createHeldCall() {
- Call call = mock(Call.class);
- when(mMockCallsManager.getHeldCall()).thenReturn(call);
- return call;
- }
-
- private Call createOutgoingCall() {
- Call call = mock(Call.class);
- when(mMockCallsManager.getOutgoingCall()).thenReturn(call);
- return call;
- }
-
- private Call createDisconnectedCall() {
- Call call = mock(Call.class);
- when(mMockCallsManager.getFirstCallWithState(CallState.DISCONNECTED)).thenReturn(call);
- return call;
- }
-
- private Call createForegroundCall() {
- Call call = mock(Call.class);
- when(mMockCallsManager.getForegroundCall()).thenReturn(call);
- return call;
- }
-
- private static ComponentName makeQuickConnectionServiceComponentName() {
- return new ComponentName("com.android.server.telecom.tests",
- "com.android.server.telecom.tests.MockConnectionService");
- }
-
- private static PhoneAccountHandle makeQuickAccountHandle(String id) {
- return new PhoneAccountHandle(makeQuickConnectionServiceComponentName(), id,
- Binder.getCallingUserHandle());
- }
-
- private PhoneAccount.Builder makeQuickAccountBuilder(String id, int idx) {
- return new PhoneAccount.Builder(makeQuickAccountHandle(id), "label" + idx);
- }
-
- private PhoneAccount makeQuickAccount(String id, int idx) {
- return makeQuickAccountBuilder(id, idx)
- .setAddress(Uri.parse(TEST_ACCOUNT_ADDRESS + idx))
- .setSubscriptionAddress(Uri.parse("tel:555-000" + idx))
- .setCapabilities(idx)
- .setIcon(Icon.createWithResource(
- "com.android.server.telecom.tests", R.drawable.stat_sys_phone_call))
- .setShortDescription("desc" + idx)
- .setIsEnabled(true)
- .build();
- }
-}
diff --git a/tests/src/com/android/server/telecom/tests/InCallControllerTests.java b/tests/src/com/android/server/telecom/tests/InCallControllerTests.java
index 5eecfae..6a6b9f3 100644
--- a/tests/src/com/android/server/telecom/tests/InCallControllerTests.java
+++ b/tests/src/com/android/server/telecom/tests/InCallControllerTests.java
@@ -62,6 +62,7 @@
import android.os.IBinder;
import android.os.Looper;
import android.os.UserHandle;
+import android.telecom.CallAudioState;
import android.telecom.InCallService;
import android.telecom.ParcelableCall;
import android.telecom.PhoneAccountHandle;
@@ -175,6 +176,8 @@
mEmergencyCallHelper = new EmergencyCallHelper(mMockContext, mDefaultDialerCache,
mTimeoutsAdapter);
when(mMockCallsManager.getRoleManagerAdapter()).thenReturn(mMockRoleManagerAdapter);
+ when(mMockContext.getSystemService(eq(Context.NOTIFICATION_SERVICE)))
+ .thenReturn(mNotificationManager);
when(mMockPackageManager.getPermissionInfo(anyString(), anyInt())).thenReturn(
mMockPermissionInfo);
mInCallController = new InCallController(mMockContext, mLock, mMockCallsManager,
@@ -186,8 +189,6 @@
verify(mMockSystemStateHelper).addListener(systemStateListenerArgumentCaptor.capture());
mSystemStateListener = systemStateListenerArgumentCaptor.getValue();
- when(mMockContext.getSystemService(eq(Context.NOTIFICATION_SERVICE)))
- .thenReturn(mNotificationManager);
// Companion Apps don't have CONTROL_INCALL_EXPERIENCE permission.
doAnswer(invocation -> {
int uid = invocation.getArgument(0);
@@ -224,6 +225,7 @@
when(mMockPackageManager.checkPermission(
matches(Manifest.permission.CONTROL_INCALL_EXPERIENCE),
matches(APPOP_NONUI_PKG))).thenReturn(PackageManager.PERMISSION_DENIED);
+ when(mMockCallsManager.getAudioState()).thenReturn(new CallAudioState(false, 0, 0));
}
@Override
@@ -638,6 +640,7 @@
any(Intent.class), any(ServiceConnection.class), anyInt(), any(UserHandle.class)))
.thenReturn(true);
when(mMockContext.getApplicationInfo()).thenReturn(applicationInfo);
+ when(mDefaultDialerCache.getDefaultDialerApplication(CURRENT_USER_ID)).thenReturn(DEF_PKG);
setupMockPackageManager(true /* default */, true /* system */, false /* external calls */);
mInCallController.bindToServices(mMockCall);
@@ -664,7 +667,7 @@
verify(mNotificationManager).notify(eq(NOTIFICATION_TAG),
eq(IN_CALL_SERVICE_NOTIFICATION_ID), any(Notification.class));
- verify(mCallInfo).addInCallService(eq(sysDialerComponentName.flattenToShortString()),
+ verify(mCallInfo).addInCallService(eq(defDialerComponentName.flattenToShortString()),
anyInt(), anyLong(), eq(true));
ArgumentCaptor<Intent> bindIntentCaptor2 = ArgumentCaptor.forClass(Intent.class);
@@ -674,6 +677,7 @@
eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE
| Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS),
eq(UserHandle.CURRENT));
+ assertEquals(sysDialerComponentName, bindIntentCaptor2.getValue().getComponent());
}
/**
diff --git a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
index e8234fc..5c1cdc4 100644
--- a/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
+++ b/tests/src/com/android/server/telecom/tests/TelecomSystemTest.java
@@ -69,7 +69,6 @@
import com.android.internal.telecom.IInCallAdapter;
import com.android.server.telecom.AsyncRingtonePlayer;
-import com.android.server.telecom.BluetoothPhoneServiceImpl;
import com.android.server.telecom.CallAudioManager;
import com.android.server.telecom.CallAudioModeStateMachine;
import com.android.server.telecom.CallAudioRouteStateMachine;
@@ -201,7 +200,6 @@
@Mock HeadsetMediaButton mHeadsetMediaButton;
@Mock ProximitySensorManager mProximitySensorManager;
@Mock InCallWakeLockController mInCallWakeLockController;
- @Mock BluetoothPhoneServiceImpl mBluetoothPhoneServiceImpl;
@Mock AsyncRingtonePlayer mAsyncRingtonePlayer;
@Mock IncomingCallNotifier mIncomingCallNotifier;
@Mock ClockProxy mClockProxy;
@@ -485,7 +483,6 @@
proximitySensorManagerFactory,
inCallWakeLockControllerFactory,
() -> mAudioService,
- (context, lock, callsManager, phoneAccountRegistrar) -> mBluetoothPhoneServiceImpl,
mConnServFMFactory,
mTimeoutsAdapter,
mAsyncRingtonePlayer,