Snap for 4448085 from b29da02e4b48bae69bf74f6174cdf6815786cb94 to oc-m3-release
Change-Id: I8dfe5e1f89de28aed65b3fb3e363a7dc50648f1f
diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml
index 56b24d6..7dfd8e9 100644
--- a/res/values-bn/strings.xml
+++ b/res/values-bn/strings.xml
@@ -30,7 +30,7 @@
<string name="bt_enable_line2" msgid="4341936569415937994">"এখন ব্লুটুথ চালু করবেন?"</string>
<string name="bt_enable_cancel" msgid="1988832367505151727">"বাতিল করুন"</string>
<string name="bt_enable_ok" msgid="3432462749994538265">"চালু করুন"</string>
- <string name="incoming_file_confirm_title" msgid="8139874248612182627">"ফাইল স্থানান্তর"</string>
+ <string name="incoming_file_confirm_title" msgid="8139874248612182627">"ফাইল ট্রান্সফার"</string>
<string name="incoming_file_confirm_content" msgid="2752605552743148036">"আগত ফাইল স্বীকার করবেন?"</string>
<string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"অস্বীকার করুন"</string>
<string name="incoming_file_confirm_ok" msgid="281462442932231475">"স্বীকার করুন"</string>
@@ -45,7 +45,7 @@
<string name="notification_sent" msgid="9218710861333027778">"ব্লুটুথ share: <xliff:g id="FILE">%1$s</xliff:g> পাঠানো হয়েছে"</string>
<string name="notification_sent_complete" msgid="302943281067557969">"১০০% সম্পূর্ণ"</string>
<string name="notification_sent_fail" msgid="6696082233774569445">"ব্লুটুথ share: <xliff:g id="FILE">%1$s</xliff:g> ফাইল পাঠানো হয়নি"</string>
- <string name="download_title" msgid="3353228219772092586">"ফাইল স্থানান্তর"</string>
+ <string name="download_title" msgid="3353228219772092586">"ফাইল ট্রান্সফার"</string>
<string name="download_line1" msgid="4926604799202134144">"প্রেরক: \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
<string name="download_line2" msgid="5876973543019417712">"ফাইল: <xliff:g id="FILE">%1$s</xliff:g>"</string>
<string name="download_line3" msgid="4384821622908676061">"ফাইল আকার: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
@@ -88,14 +88,14 @@
<string name="bt_sm_2_1" product="default" msgid="1989018443456803630">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" এর থেকে ফাইল সংরক্ষণ করার জন্য SD কার্ডে পর্যাপ্ত জায়গা নেই।"</string>
<string name="bt_sm_2_2" msgid="2965243265852680543">"জায়গা প্রয়োজন: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
<string name="ErrorTooManyRequests" msgid="8578277541472944529">"অনেকগুলি অনুরোধ প্রক্রিয়া করা হচ্ছে৷ পরে আবার চেষ্টা করুন৷"</string>
- <string name="status_pending" msgid="2503691772030877944">"ফাইল স্থানান্তর করা এখনো শুরু হয়নি।"</string>
- <string name="status_running" msgid="6562808920311008696">"ফাইল স্থানান্তর করা চলছে।"</string>
- <string name="status_success" msgid="239573225847565868">"ফাইল স্থানান্তর করা সফলভাবে সম্পন্ন হয়েছে।"</string>
- <string name="status_not_accept" msgid="1695082417193780738">"সামগ্রী সমর্থিত নয়।"</string>
- <string name="status_forbidden" msgid="613956401054050725">"স্থানান্তর করা টার্গেট ডিভাইস দ্বারা নিষিদ্ধ করা হয়েছে।"</string>
- <string name="status_canceled" msgid="6664490318773098285">"ব্যবহারকারী দ্বারা ট্রান্সফার করা বাতিল করা হয়েছে।"</string>
- <string name="status_file_error" msgid="3671917770630165299">"সঞ্চয়স্থান সমস্যা।"</string>
- <string name="status_no_sd_card" product="nosdcard" msgid="1112125377088421469">"কোনো USB সঞ্চয়স্থান নেই।"</string>
+ <string name="status_pending" msgid="2503691772030877944">"ফাইল ট্রান্সফার করা এখনও শুরু হয়নি।"</string>
+ <string name="status_running" msgid="6562808920311008696">"ফাইল ট্রান্সফার করা চলছে।"</string>
+ <string name="status_success" msgid="239573225847565868">"ফাইল ট্রান্সফার সফলভাবে সম্পন্ন হয়েছে।"</string>
+ <string name="status_not_accept" msgid="1695082417193780738">"কন্টেন্ট সমর্থিত নয়।"</string>
+ <string name="status_forbidden" msgid="613956401054050725">"টার্গেট ডিভাইস দ্বারা ট্রান্সফার নিষিদ্ধ করা হয়েছে।"</string>
+ <string name="status_canceled" msgid="6664490318773098285">"ব্যবহারকারী দ্বারা ট্রান্সফার বাতিল করা হয়েছে।"</string>
+ <string name="status_file_error" msgid="3671917770630165299">"স্টোরেজ সমস্যা।"</string>
+ <string name="status_no_sd_card" product="nosdcard" msgid="1112125377088421469">"কোনও USB স্টোরেজ নেই।"</string>
<string name="status_no_sd_card" product="default" msgid="5760944071743325592">"কোনো SD কার্ড নেই। স্থানান্তর করা ফাইলগুলি সংরক্ষণ করতে SD কার্ড ঢোকান।"</string>
<string name="status_connection_error" msgid="947681831523219891">"সংযোগ অসফল।"</string>
<string name="status_protocol_error" msgid="3245444473429269539">"অনুরোধ সঠিকভাবে পরিচালনা করা যাবে না।"</string>
@@ -122,12 +122,12 @@
<string name="transfer_menu_open" msgid="3368984869083107200">"খুলুন"</string>
<string name="transfer_menu_clear" msgid="5854038118831427492">"তালিকা থেকে সাফ করুন"</string>
<string name="transfer_clear_dlg_title" msgid="2953444575556460386">"সাফ করুন"</string>
- <string name="bluetooth_map_settings_save" msgid="7635491847388074606">"সংরক্ষণ করুন"</string>
+ <string name="bluetooth_map_settings_save" msgid="7635491847388074606">"সেভ করুন"</string>
<string name="bluetooth_map_settings_cancel" msgid="9205350798049865699">"বাতিল করুন"</string>
- <string name="bluetooth_map_settings_intro" msgid="6482369468223987562">"আপনি ব্লুটুথ এর মাধ্যমে যে অ্যাকাউন্টগুলি শেয়ার করতে চান সেগুলি নির্বাচন করুন। সংযোগের সময়ে আপনাকে এখনো অ্যাকাউন্টের যে কোনো অ্যাক্সেস গ্রহণ করতে হবে।"</string>
+ <string name="bluetooth_map_settings_intro" msgid="6482369468223987562">"আপনি ব্লুটুথ এর মাধ্যমে যে অ্যাকাউন্টগুলি শেয়ার করতে চান সেগুলি বেছে নিন। সংযোগের সময়ে আপনাকে এখনো অ্যাকাউন্টের যে কোনো অ্যাক্সেস গ্রহণ করতে হবে।"</string>
<string name="bluetooth_map_settings_count" msgid="4557473074937024833">"যে স্লটগুলি বাকি আছে:"</string>
<string name="bluetooth_map_settings_app_icon" msgid="7105805610929114707">"অ্যাপ্লিকেশান আইকন"</string>
- <string name="bluetooth_map_settings_title" msgid="7420332483392851321">"ব্লুটুথ মারফত বার্তা শেয়ার করার সেটিংস"</string>
+ <string name="bluetooth_map_settings_title" msgid="7420332483392851321">"ব্লুটুথ মারফত মেসেজ শেয়ার করার সেটিংস"</string>
<string name="bluetooth_map_settings_no_account_slots_left" msgid="1796029082612965251">"অ্যাকাউন্ট নির্বাচন করা যাচ্ছে না। ০টি স্লট বাকি আছে"</string>
<string name="bluetooth_connected" msgid="6718623220072656906">"ব্লুটুথ অডিও সংযুক্ত হয়েছে"</string>
<string name="bluetooth_disconnected" msgid="3318303728981478873">"ব্লুটুথ অডিওর সংযোগ বিচ্ছিন্ন হয়েছে"</string>
diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml
index 834e1e0..fc0a224 100644
--- a/res/values-gu/strings.xml
+++ b/res/values-gu/strings.xml
@@ -17,7 +17,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="permlab_bluetoothShareManager" msgid="311492132450338925">"ઍક્સેસ ડાઉનલોડ મેનેજર."</string>
- <string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"એપ્લિકેશનને BluetoothShare મેનેજર અૅક્સેસ કરવાની અને ફાઇલો સ્થાનાંતરિત કરવા માટે તેનો ઉપયોગ કરવાની મંજૂરી આપે છે."</string>
+ <string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"એપ્લિકેશનને BluetoothShare મેનેજર અૅક્સેસ કરવાની અને ફાઇલો ટ્રાન્સફર કરવા માટે તેનો ઉપયોગ કરવાની મંજૂરી આપે છે."</string>
<string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"વ્હાઇટલિસ્ટ બ્લૂટૂથ ઉપકરણ ઍક્સેસ."</string>
<string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"એપ્લિકેશનને અસ્થાયી ધોરણે બ્લૂટૂથ ઉપકરણને વ્હાઇટલિસ્ટ કરવાની મંજૂરી આપે છે, તે ઉપકરણને આ ઉપકરણ પર વપરાશકર્તા પુષ્ટિ વિના ફાઇલો મોકલવાની મંજૂરી આપીને."</string>
<string name="bt_share_picker_label" msgid="6268100924487046932">"બ્લૂટૂથ"</string>
@@ -96,7 +96,7 @@
<string name="status_canceled" msgid="6664490318773098285">"વપરાશકર્તા દ્વારા સ્થાનાંતરણ રદ."</string>
<string name="status_file_error" msgid="3671917770630165299">"સંગ્રહ સમસ્યા."</string>
<string name="status_no_sd_card" product="nosdcard" msgid="1112125377088421469">"કોઈ USB સ્ટોરેજ નથી."</string>
- <string name="status_no_sd_card" product="default" msgid="5760944071743325592">"SD કાર્ડ નથી. સ્થાનાંતરિત ફાઇલો સાચવવા માટે એક SD કાર્ડ શામેલ કરો."</string>
+ <string name="status_no_sd_card" product="default" msgid="5760944071743325592">"SD કાર્ડ નથી. ટ્રાન્સફર ફાઇલો સાચવવા માટે એક SD કાર્ડ શામેલ કરો."</string>
<string name="status_connection_error" msgid="947681831523219891">"કનેક્શન અસફળ."</string>
<string name="status_protocol_error" msgid="3245444473429269539">"વિનંતી યોગ્ય રીતે હેન્ડલ કરી શકાતી નથી."</string>
<string name="status_unknown_error" msgid="8156660554237824912">"અજાણી ભૂલ."</string>
diff --git a/res/values-gu/strings_sap.xml b/res/values-gu/strings_sap.xml
index 5deaa98..b42c689 100644
--- a/res/values-gu/strings_sap.xml
+++ b/res/values-gu/strings_sap.xml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="bluetooth_sap_notif_title" msgid="6877860822993195074">"બ્લૂટૂથ SIM ઍક્સેસ"</string>
- <string name="bluetooth_sap_notif_ticker" msgid="6807778527893726699">"બ્લૂટૂથ SIM ઍક્સેસ"</string>
+ <string name="bluetooth_sap_notif_title" msgid="6877860822993195074">"બ્લૂટૂથ સિમ ઍક્સેસ"</string>
+ <string name="bluetooth_sap_notif_ticker" msgid="6807778527893726699">"બ્લૂટૂથ સિમ ઍક્સેસ"</string>
<string name="bluetooth_sap_notif_message" msgid="7138657801087500690">"ક્લાઇન્ટને ડિસ્કનેક્ટ કરવાની વિનંતી કરીએ?"</string>
<string name="bluetooth_sap_notif_disconnecting" msgid="819150843490233288">"ડિસ્કનેક્ટ કરવા માટે ક્લાઇન્ટની રાહ જોઈ રહ્યાં છે"</string>
<string name="bluetooth_sap_notif_disconnect_button" msgid="3678476872583356919">"ડિસ્કનેક્ટ કરો"</string>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 19977fc..01b0c18 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -23,14 +23,14 @@
<string name="bt_share_picker_label" msgid="6268100924487046932">"ब्लूटूथ"</string>
<string name="unknown_device" msgid="9221903979877041009">"अज्ञात डिवाइस"</string>
<string name="unknownNumber" msgid="4994750948072751566">"अज्ञात"</string>
- <string name="airplane_error_title" msgid="2683839635115739939">"हवाई जहाज मोड"</string>
+ <string name="airplane_error_title" msgid="2683839635115739939">"हवाई जहाज़ मोड"</string>
<string name="airplane_error_msg" msgid="8698965595254137230">"आप हवाई जहाज मोड में ब्लूटूथ का उपयोग नहीं कर सकते हैं."</string>
<string name="bt_enable_title" msgid="8657832550503456572"></string>
<string name="bt_enable_line1" msgid="7203551583048149">"ब्लूटूथ सेवाओं के उपयोग के लिए, आपको पहले ब्लूटूथ चालू करना चाहिए."</string>
<string name="bt_enable_line2" msgid="4341936569415937994">"अभी ब्लूटूथ चालू करें?"</string>
<string name="bt_enable_cancel" msgid="1988832367505151727">"रद्द करें"</string>
<string name="bt_enable_ok" msgid="3432462749994538265">"चालू करें"</string>
- <string name="incoming_file_confirm_title" msgid="8139874248612182627">"फ़ाइल स्थानांतरण"</string>
+ <string name="incoming_file_confirm_title" msgid="8139874248612182627">"फ़ाइल ट्रांसफ़र करें"</string>
<string name="incoming_file_confirm_content" msgid="2752605552743148036">"आवक फ़ाइल स्वीकार करें?"</string>
<string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"अस्वीकारें"</string>
<string name="incoming_file_confirm_ok" msgid="281462442932231475">"स्वीकारें"</string>
@@ -45,7 +45,7 @@
<string name="notification_sent" msgid="9218710861333027778">"ब्लूटूथ शेयर: <xliff:g id="FILE">%1$s</xliff:g> भेजा गया"</string>
<string name="notification_sent_complete" msgid="302943281067557969">"100% पूर्ण"</string>
<string name="notification_sent_fail" msgid="6696082233774569445">"ब्लूटूथ शेयर: फ़ाइल <xliff:g id="FILE">%1$s</xliff:g> भेजी नहीं गई"</string>
- <string name="download_title" msgid="3353228219772092586">"फ़ाइल स्थानांतरण"</string>
+ <string name="download_title" msgid="3353228219772092586">"फ़ाइल ट्रांसफ़र करें"</string>
<string name="download_line1" msgid="4926604799202134144">"प्रेषक: \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
<string name="download_line2" msgid="5876973543019417712">"फ़ाइल: <xliff:g id="FILE">%1$s</xliff:g>"</string>
<string name="download_line3" msgid="4384821622908676061">"फ़ाइल आकार: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
@@ -84,9 +84,9 @@
<string name="bt_toast_4" msgid="4678812947604395649">"\"<xliff:g id="RECIPIENT">%1$s</xliff:g>\" को फ़ाइल भेज रहा है"</string>
<string name="bt_toast_5" msgid="2846870992823019494">"\"<xliff:g id="RECIPIENT">%2$s</xliff:g>\" को <xliff:g id="NUMBER">%1$s</xliff:g> फ़ाइलें भेज रहा है"</string>
<string name="bt_toast_6" msgid="1855266596936622458">"\"<xliff:g id="RECIPIENT">%1$s</xliff:g>\" को फ़ाइल भेजना रोका गया"</string>
- <string name="bt_sm_2_1" product="nosdcard" msgid="352165168004521000">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" की फ़ाइल सहेजने के लिए USB मेमोरी में पर्याप्त स्थान नहीं है"</string>
- <string name="bt_sm_2_1" product="default" msgid="1989018443456803630">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" की फ़ाइल सहेजने के लिए SD कार्ड पर पर्याप्त स्थान नहीं है"</string>
- <string name="bt_sm_2_2" msgid="2965243265852680543">"आवश्यक स्थान: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
+ <string name="bt_sm_2_1" product="nosdcard" msgid="352165168004521000">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" की फ़ाइल सेव करने के लिए USB मेमोरी में ज़रुरत के मुताबिक जगह नहीं है"</string>
+ <string name="bt_sm_2_1" product="default" msgid="1989018443456803630">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" की फ़ाइल सेव करने के लिए SD कार्ड पर ज़रुरत के मुताबिक जगह नहीं है"</string>
+ <string name="bt_sm_2_2" msgid="2965243265852680543">"जगह चाहिए: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
<string name="ErrorTooManyRequests" msgid="8578277541472944529">"बहुत सारे अनुरोधों पर कार्रवाई चल रही है. बाद में पुन: प्रयास करें."</string>
<string name="status_pending" msgid="2503691772030877944">"फ़ाइल स्थानांतरण अभी तक प्रारंभ नहीं हुआ."</string>
<string name="status_running" msgid="6562808920311008696">"फ़ाइल स्थानांतरण जारी है."</string>
@@ -122,9 +122,9 @@
<string name="transfer_menu_open" msgid="3368984869083107200">"खोलें"</string>
<string name="transfer_menu_clear" msgid="5854038118831427492">"सूची से साफ़ करें"</string>
<string name="transfer_clear_dlg_title" msgid="2953444575556460386">"साफ़ करें"</string>
- <string name="bluetooth_map_settings_save" msgid="7635491847388074606">"सहेजें"</string>
+ <string name="bluetooth_map_settings_save" msgid="7635491847388074606">"सेव करें"</string>
<string name="bluetooth_map_settings_cancel" msgid="9205350798049865699">"रद्द करें"</string>
- <string name="bluetooth_map_settings_intro" msgid="6482369468223987562">"वे खाते चुनें जिन्हें आप ब्लूटूथ के माध्यम से साझा करना चाहते हैं. आपको अभी भी कनेक्ट करते समय खातों के किसी भी एक्सेस को स्वीकार करना होगा."</string>
+ <string name="bluetooth_map_settings_intro" msgid="6482369468223987562">"वे खाते चुनें जिन्हें आप ब्लूटूथ के ज़रिये शेयर करना चाहते हैं. आपको अभी भी कनेक्ट करते समय खातों के किसी भी एक्सेस को स्वीकार करना होगा."</string>
<string name="bluetooth_map_settings_count" msgid="4557473074937024833">"शेष स्लॉट:"</string>
<string name="bluetooth_map_settings_app_icon" msgid="7105805610929114707">"ऐप्लिकेशन आइकॉन"</string>
<string name="bluetooth_map_settings_title" msgid="7420332483392851321">"ब्लूटूथ संदेश साझाकरण सेटिंग"</string>
diff --git a/res/values-hi/test_strings.xml b/res/values-hi/test_strings.xml
index 8426b5f..f8379b8 100644
--- a/res/values-hi/test_strings.xml
+++ b/res/values-hi/test_strings.xml
@@ -5,9 +5,9 @@
<string name="insert_record" msgid="1450997173838378132">"रिकॉर्ड सम्मिलित करें"</string>
<string name="update_record" msgid="2480425402384910635">"रिकॉर्ड की दुबारा पूछें"</string>
<string name="ack_record" msgid="6716152390978472184">"रिकॉर्ड अभिस्वीकृत करें"</string>
- <string name="deleteAll_record" msgid="4383349788485210582">"सभी रिकॉर्ड हटाएं"</string>
+ <string name="deleteAll_record" msgid="4383349788485210582">"सभी रिकॉर्ड मिटाएं"</string>
<string name="ok_button" msgid="6519033415223065454">"ठीक है"</string>
- <string name="delete_record" msgid="4645040331967533724">"रिकॉर्ड हटाएं"</string>
+ <string name="delete_record" msgid="4645040331967533724">"रिकॉर्ड मिटाएं"</string>
<string name="start_server" msgid="9034821924409165795">"TCP सर्वर शरू करें"</string>
<string name="notify_server" msgid="4369106744022969655">"TCP सर्वर को सूचित करें"</string>
</resources>
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
index eb66c39..5e13084 100644
--- a/res/values-ml/strings.xml
+++ b/res/values-ml/strings.xml
@@ -16,7 +16,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="permlab_bluetoothShareManager" msgid="311492132450338925">"ഡൗൺലോഡ് മാനേജർ ആക്സസ്സുചെയ്യുക."</string>
+ <string name="permlab_bluetoothShareManager" msgid="311492132450338925">"ഡൗൺലോഡ് മാനേജർ ആക്സസ്സ് ചെയ്യുക."</string>
<string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"BluetoothShare മാനേജർ ആക്സസ്സുചെയ്യാനും ഫയലുകൾ കൈമാറാൻ അത് ഉപയോഗിക്കാനും അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
<string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"വൈറ്റ്ലിസ്റ്റ് ബ്ലൂടൂത്ത് ഉപകരണ ആക്സസ്സ്."</string>
<string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"ഒരു ബ്ലൂടൂത്ത് ഉപകരണം താൽക്കാലികമായി വൈറ്റ്ലിസ്റ്റുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു, അത് ഉപയോക്താവിന്റെ സ്ഥിരീകരണമില്ലാതെ ഈ ഉപകരണത്തിലേക്ക് ഫയലുകൾ അയയ്ക്കാൻ ആ ഉപകരണത്തെ അനുവദിക്കുന്നു."</string>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index 35cb15f..d1122e0 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -18,10 +18,10 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="permlab_bluetoothShareManager" msgid="311492132450338925">"डाउनलोड व्यवस्थापक अॅक्सेस करा."</string>
<string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"अॅपला BluetoothShare व्यवस्थापकामध्ये प्रवेश करण्याची आणि फायली स्थानांतरित करण्यासाठी त्याचा वापर करण्याची अनुमती देते."</string>
- <string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"व्हाइटलिस्ट ब्लूटूथ डीव्हाइस अॅक्सेस."</string>
+ <string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"व्हाइटलिस्ट ब्लूटूथ डिव्हाइस अॅक्सेस."</string>
<string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"डीव्हाइसला वापरकर्ता पुष्टीशिवाय या डीव्हाइसवर फायली पाठविण्याची अनुमती देऊन ब्लूटूथ डीव्हाइसला तात्पुरते व्हाइटलिस्ट करण्याची अॅपला अनुमती देते."</string>
<string name="bt_share_picker_label" msgid="6268100924487046932">"ब्लूटूथ"</string>
- <string name="unknown_device" msgid="9221903979877041009">"अज्ञात डीव्हाइस"</string>
+ <string name="unknown_device" msgid="9221903979877041009">"अज्ञात डिव्हाइस"</string>
<string name="unknownNumber" msgid="4994750948072751566">"अज्ञात"</string>
<string name="airplane_error_title" msgid="2683839635115739939">"विमान मोड"</string>
<string name="airplane_error_msg" msgid="8698965595254137230">"तुम्ही विमान मोड मध्ये ब्लूटूथ वापरू शकत नाही."</string>
diff --git a/res/values-ne/test_strings.xml b/res/values-ne/test_strings.xml
index 0dfa84b..ce2bc40 100644
--- a/res/values-ne/test_strings.xml
+++ b/res/values-ne/test_strings.xml
@@ -8,6 +8,6 @@
<string name="deleteAll_record" msgid="4383349788485210582">"सबै रेकर्ड मेटाउनुहोस्"</string>
<string name="ok_button" msgid="6519033415223065454">"ठीक छ"</string>
<string name="delete_record" msgid="4645040331967533724">"रेकर्ड मेटाउनुहोस्"</string>
- <string name="start_server" msgid="9034821924409165795">"TCP सर्भर सुरू गर्नुहोस्"</string>
+ <string name="start_server" msgid="9034821924409165795">"TCP सर्भर सुरु गर्नुहोस्"</string>
<string name="notify_server" msgid="4369106744022969655">"TCP सर्भर सूचित गर्नुहोस्"</string>
</resources>
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
index 8f16eef..73bcaa6 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -17,10 +17,10 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="permlab_bluetoothShareManager" msgid="311492132450338925">"ਡਾਊਨਲੋਡ ਪ੍ਰਬੰਧਕ ਤੱਕ ਪਹੁੰਚ।"</string>
- <string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"ਐਪ ਨੂੰ BluetoothShare ਪ੍ਰਬੰਧਕ ਤੱਕ ਪਹੁੰਚ ਅਤੇ ਫ਼ਾਈਲਾਂ ਟ੍ਰਾਂਸਫਰ ਕਰਨ ਲਈ ਇਸਦੀ ਵਰਤੋਂ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+ <string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"ਐਪ ਨੂੰ ਬਲੂਟੁੱਥShare ਪ੍ਰਬੰਧਕ ਤੱਕ ਪਹੁੰਚ ਅਤੇ ਫ਼ਾਈਲਾਂ ਟ੍ਰਾਂਸਫਰ ਕਰਨ ਲਈ ਇਸਦੀ ਵਰਤੋਂ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
<string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"ਵਾਈਟਲਿਸਟ ਬਲੂਟੱਥ ਡੀਵਾਈਸ ਪਹੁੰਚ।"</string>
<string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"ਐਪ ਨੂੰ ਇਹ ਆਗਿਆ ਦਿੰਦੇ ਹੋਏ ਕਿ ਡੀਵਾਈਸ ਵਰਤੋਂਕਾਰ ਦੀ ਪੁਸ਼ਟੀ ਤੋਂ ਬਿਨਾਂ ਇਸ ਡੀਵਾਈਸ ਨੂੰ ਫ਼ਾਈਲਾਂ ਭੇਜੇ, ਇੱਕ ਬਲੂਟੁੱਥ ਡੀਵਾਈਸ ਨੂੰ ਅਸਥਾਈ ਤੌਰ ਤੇ ਵਾਈਟਲਿਸਟ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
- <string name="bt_share_picker_label" msgid="6268100924487046932">"Bluetooth"</string>
+ <string name="bt_share_picker_label" msgid="6268100924487046932">"ਬਲੂਟੁੱਥ"</string>
<string name="unknown_device" msgid="9221903979877041009">"ਅਗਿਆਤ ਡੀਵਾਈਸ"</string>
<string name="unknownNumber" msgid="4994750948072751566">"ਅਗਿਆਤ"</string>
<string name="airplane_error_title" msgid="2683839635115739939">"ਏਅਰਪਲੇਨ ਮੋਡ"</string>
@@ -63,7 +63,7 @@
<string name="download_succ_line5" msgid="4509944688281573595">"ਫਾਈਲ ਪ੍ਰਾਪਤ ਕੀਤੀ"</string>
<string name="download_succ_ok" msgid="7053688246357050216">"ਖੋਲ੍ਹੋ"</string>
<string name="upload_line1" msgid="2055952074059709052">"ਨੂੰ: \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\""</string>
- <string name="upload_line3" msgid="4920689672457037437">"ਫਾਈਲ ਪ੍ਰਕਾਰ: <xliff:g id="TYPE">%1$s</xliff:g> (<xliff:g id="SIZE">%2$s</xliff:g>)"</string>
+ <string name="upload_line3" msgid="4920689672457037437">"ਫ਼ਾਈਲ ਦੀ ਕਿਸਮ: <xliff:g id="TYPE">%1$s</xliff:g> (<xliff:g id="SIZE">%2$s</xliff:g>)"</string>
<string name="upload_line5" msgid="7759322537674229752">"ਫਾਈਲ ਭੇਜ ਰਿਹਾ ਹੈ…"</string>
<string name="upload_succ_line5" msgid="5687317197463383601">"ਫਾਈਲ ਭੇਜੀ ਗਈ"</string>
<string name="upload_succ_ok" msgid="7705428476405478828">"ਠੀਕ"</string>
@@ -73,19 +73,19 @@
<string name="upload_fail_cancel" msgid="9118496285835687125">"ਬੰਦ ਕਰੋ"</string>
<string name="bt_error_btn_ok" msgid="5965151173011534240">"ਠੀਕ"</string>
<string name="unknown_file" msgid="6092727753965095366">"ਅਗਿਆਤ ਫਾਈਲ"</string>
- <string name="unknown_file_desc" msgid="480434281415453287">"ਇਸ ਪ੍ਰਕਾਰ ਦੀ ਫਾਈਲ ਨੂੰ ਸੰਭਾਲਣ ਲਈ ਕੋਈ ਐਪ ਨਹੀਂ ਹੈ। \n"</string>
+ <string name="unknown_file_desc" msgid="480434281415453287">"ਇਸ ਕਿਸਮ ਦੀ ਫ਼ਾਈਲ ਨੂੰ ਸੰਭਾਲਣ ਲਈ ਕੋਈ ਐਪ ਨਹੀਂ ਹੈ। \n"</string>
<string name="not_exist_file" msgid="3489434189599716133">"ਕੋਈ ਫਾਈਲ ਨਹੀਂ"</string>
<string name="not_exist_file_desc" msgid="4059531573790529229">"ਫਾਈਲ ਮੌਜੂਦ ਨਹੀਂ ਹੈ। \n"</string>
<string name="enabling_progress_title" msgid="436157952334723406">"ਕਿਰਪਾ ਕਰਕੇ ਠਹਿਰੋ..."</string>
<string name="enabling_progress_content" msgid="4601542238119927904">"Bluetooth ਚਾਲੂ ਕਰ ਰਿਹਾ ਹੈ…"</string>
- <string name="bt_toast_1" msgid="972182708034353383">"ਫਾਈਲ ਪ੍ਰਾਪਤ ਕੀਤੀ ਜਾਏਗੀ। ਸੂਚਨਾਵਾਂ ਪੈਨਲ ਵਿੱਚ ਪ੍ਰਗਤੀ ਦੀ ਜਾਂਚ ਕਰੋ।"</string>
+ <string name="bt_toast_1" msgid="972182708034353383">"ਫ਼ਾਈਲ ਪ੍ਰਾਪਤ ਕੀਤੀ ਜਾਵੇਗੀ। ਸੂਚਨਾਵਾਂ ਪੈਨਲ ਵਿੱਚ ਪ੍ਰਗਤੀ ਦੀ ਜਾਂਚ ਕਰੋ।"</string>
<string name="bt_toast_2" msgid="8602553334099066582">"ਫਾਈਲ ਪ੍ਰਾਪਤ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕਦੀ।"</string>
<string name="bt_toast_3" msgid="6707884165086862518">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" ਤੋਂ ਫਾਈਲ ਪ੍ਰਾਪਤ ਕਰਨਾ ਰੋਕਿਆ ਗਿਆ"</string>
<string name="bt_toast_4" msgid="4678812947604395649">"\"<xliff:g id="RECIPIENT">%1$s</xliff:g>\" ਨੂੰ ਫਾਈਲ ਭੇਜ ਰਿਹਾ ਹੈ"</string>
<string name="bt_toast_5" msgid="2846870992823019494">"\"<xliff:g id="RECIPIENT">%2$s</xliff:g>\" ਨੂੰ <xliff:g id="NUMBER">%1$s</xliff:g> ਫਾਈਲਾਂ ਭੇਜ ਰਿਹਾ ਹੈ"</string>
<string name="bt_toast_6" msgid="1855266596936622458">"\"<xliff:g id="RECIPIENT">%1$s</xliff:g>\" ਨੂੰ ਫਾਈਲ ਭੇਜਣਾ ਰੋਕਿਆ ਗਿਆ"</string>
- <string name="bt_sm_2_1" product="nosdcard" msgid="352165168004521000">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" ਦੀ ਫਾਈਲ ਸੁਰੱਖਿਅਤ ਕਰਨ ਲਈ USB ਸਟੋਰੇਜ ਵਿੱਚ ਪੂਰਾ ਸਪੇਸ ਨਹੀਂ ਹੈ।"</string>
- <string name="bt_sm_2_1" product="default" msgid="1989018443456803630">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" ਦੀ ਫਾਈਲ ਸੁਰੱਖਿਅਤ ਕਰਨ ਲਈ SD ਕਾਰਡ ਵਿੱਚ ਪੂਰਾ ਸਪੇਸ ਨਹੀਂ ਹੈ।"</string>
+ <string name="bt_sm_2_1" product="nosdcard" msgid="352165168004521000">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" ਦੀ ਫ਼ਾਈਲ ਰੱਖਿਅਤ ਕਰਨ ਲਈ USB ਸਟੋਰੇਜ ਵਿੱਚ ਪੂਰੀ ਜਗ੍ਹਾ ਨਹੀਂ ਹੈ।"</string>
+ <string name="bt_sm_2_1" product="default" msgid="1989018443456803630">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" ਦੀ ਫ਼ਾਈਲ ਰੱਖਿਅਤ ਕਰਨ ਲਈ SD ਕਾਰਡ ਵਿੱਚ ਪੂਰੀ ਜਗ੍ਹਾ ਨਹੀਂ ਹੈ।"</string>
<string name="bt_sm_2_2" msgid="2965243265852680543">"ਲੁੜੀਂਦਾ ਸਪੇਸ: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
<string name="ErrorTooManyRequests" msgid="8578277541472944529">"ਬਹੁਤ ਜ਼ਿਆਦਾ ਬੇਨਤੀਆਂ ਦੀ ਪ੍ਰਕਿਰਿਆ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ। ਬਾਅਦ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
<string name="status_pending" msgid="2503691772030877944">"ਫਾਈਲ ਟ੍ਰਾਂਸਫਰ ਅਜੇ ਚਾਲੂ ਨਹੀਂ ਹੋਈ।"</string>
@@ -95,8 +95,8 @@
<string name="status_forbidden" msgid="613956401054050725">"ਟੀਚਾ ਡੀਵਾਈਸ ਵੱਲੋਂ ਟ੍ਰਾਂਸਫਰ ਵਰਜਿਤ।"</string>
<string name="status_canceled" msgid="6664490318773098285">"ਉਪਭੋਗਤਾ ਵੱਲੋਂ ਟ੍ਰਾਂਸਫਰ ਰੱਦ ਕੀਤਾ ਗਿਆ।"</string>
<string name="status_file_error" msgid="3671917770630165299">"ਸਟੋਰੇਜ ਸਮੱਸਿਆ।"</string>
- <string name="status_no_sd_card" product="nosdcard" msgid="1112125377088421469">"ਕੋਈ USB ਸਟੋਰੇਜ ਨਹੀਂ।"</string>
- <string name="status_no_sd_card" product="default" msgid="5760944071743325592">"ਕੋਈ SD ਕਾਰਡ ਨਹੀਂ। ਟ੍ਰਾਂਸਫਰ ਕੀਤੀਆਂ ਫਾਈਲਾਂ ਨੂੰ ਸੁਰੱਖਿਅਤ ਕਰਨ ਲਈ ਇੱਕ SD ਕਾਰਡ ਪਾਓ।"</string>
+ <string name="status_no_sd_card" product="nosdcard" msgid="1112125377088421469">"ਕੋਈ USB ਸਟੋਰੇਜ ਨਹੀਂ ਹੈ।"</string>
+ <string name="status_no_sd_card" product="default" msgid="5760944071743325592">"ਕੋਈ SD ਕਾਰਡ ਨਹੀਂ। ਟ੍ਰਾਂਸਫ਼ਰ ਕੀਤੀਆਂ ਫਾਈਲਾਂ ਨੂੰ ਰੱਖਿਅਤ ਕਰਨ ਲਈ ਇੱਕ SD ਕਾਰਡ ਪਾਓ।"</string>
<string name="status_connection_error" msgid="947681831523219891">"ਕਨੈਕਸ਼ਨ ਅਸਫਲ।"</string>
<string name="status_protocol_error" msgid="3245444473429269539">"ਬੇਨਤੀ ਨੂੰ ਸਹੀ ਢੰਗ ਨਾਲ ਸੰਭਾਲਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ।"</string>
<string name="status_unknown_error" msgid="8156660554237824912">"ਅਗਿਆਤ ਅਸ਼ੁੱਧੀ।"</string>
@@ -126,10 +126,10 @@
<string name="bluetooth_map_settings_cancel" msgid="9205350798049865699">"ਰੱਦ ਕਰੋ"</string>
<string name="bluetooth_map_settings_intro" msgid="6482369468223987562">"ਉਹਨਾਂ ਖਾਤਿਆਂ ਨੂੰ ਚੁਣੋ ਜਿਨ੍ਹਾਂ ਨੂੰ ਤੁਸੀਂ ਬਲੂਟੁੱਥ ਦੇ ਰਾਹੀਂ ਸਾਂਝਾ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ। ਤੁਹਾਨੂੰ ਹਾਲੇ ਵੀ ਕਨੈਕਟ ਕਰਨ ਦੌਰਾਨ ਖਾਤਿਆਂ \'ਤੇ ਕਿਸੇ ਵੀ ਪਹੁੰਚ ਨੂੰ ਸਵੀਕਾਰ ਕਰਨਾ ਹੋਵੇਗਾ।"</string>
<string name="bluetooth_map_settings_count" msgid="4557473074937024833">"ਸਲੌਟ ਬਾਕੀ:"</string>
- <string name="bluetooth_map_settings_app_icon" msgid="7105805610929114707">"ਐਪਲੀਕੇਸ਼ਨ ਆਈਕਨ"</string>
- <string name="bluetooth_map_settings_title" msgid="7420332483392851321">"ਬਲੂਟੁੱਥ ਸੁਨੇਹਾ ਸ਼ੇਅਰਿੰਗ ਸੈੱਟਿੰਗਜ਼"</string>
+ <string name="bluetooth_map_settings_app_icon" msgid="7105805610929114707">"ਐਪਲੀਕੇਸ਼ਨ ਪ੍ਰਤੀਕ"</string>
+ <string name="bluetooth_map_settings_title" msgid="7420332483392851321">"ਬਲੂਟੁੱਥ ਸੁਨੇਹਾ ਸਾਂਝਾਕਰਨ ਸੈਟਿੰਗਾਂ"</string>
<string name="bluetooth_map_settings_no_account_slots_left" msgid="1796029082612965251">"ਖਾਤਾ ਨਹੀਂ ਚੁਣ ਸਕਦਾ। 0 ਸਲੌਟ ਬਾਕੀ"</string>
- <string name="bluetooth_connected" msgid="6718623220072656906">"ਬਲੂਟੁੱਥ ਔਡੀਓ ਕਨੈਕਟ ਕੀਤੀ ਗਈ"</string>
- <string name="bluetooth_disconnected" msgid="3318303728981478873">"ਬਲੂਟੁੱਥ ਔਡੀਓ ਡਿਸਕਨੈਕਟ ਕੀਤੀ ਗਈ"</string>
- <string name="a2dp_sink_mbs_label" msgid="7566075853395412558">"ਬਲੂਟੁੱਥ ਔਡੀਓ"</string>
+ <string name="bluetooth_connected" msgid="6718623220072656906">"ਬਲੂਟੁੱਥ ਆਡੀਓ ਕਨੈਕਟ ਕੀਤੀ ਗਈ"</string>
+ <string name="bluetooth_disconnected" msgid="3318303728981478873">"ਬਲੂਟੁੱਥ ਆਡੀਓ ਡਿਸਕਨੈਕਟ ਕੀਤੀ ਗਈ"</string>
+ <string name="a2dp_sink_mbs_label" msgid="7566075853395412558">"ਬਲੂਟੁੱਥ ਆਡੀਓ"</string>
</resources>
diff --git a/res/values-pa/strings_pbap.xml b/res/values-pa/strings_pbap.xml
index 617332c..1d86e8f 100644
--- a/res/values-pa/strings_pbap.xml
+++ b/res/values-pa/strings_pbap.xml
@@ -2,9 +2,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="pbap_session_key_dialog_title" msgid="3580996574333882561">"%1$s ਲਈ ਸੈਸ਼ਨ ਕੁੰਜੀ ਟਾਈਪ ਕਰੋ"</string>
- <string name="pbap_session_key_dialog_header" msgid="2772472422782758981">"Bluetooth ਸੈਸ਼ਨ ਕੁੰਜੀ ਲੁੜੀਂਦੀ"</string>
+ <string name="pbap_session_key_dialog_header" msgid="2772472422782758981">"ਬਲੂਟੁੱਥ ਸੈਸ਼ਨ ਕੁੰਜੀ ਲੋੜੀਂਦੀ"</string>
<string name="pbap_acceptance_timeout_message" msgid="1107401415099814293">"%1$s ਨਾਲ ਕਨੈਕਸ਼ਨ ਸਵੀਕਾਰ ਕਰਨ ਲਈ ਟਾਈਮ ਆਊਟ ਹੋਇਆ ਸੀ।"</string>
- <string name="pbap_authentication_timeout_message" msgid="4166979525521902687">"%1$s ਨਾਲ ਸੈਸ਼ਨ ਕੁੰਜੀ ਇਨਪੁਟ ਕਰਨ ਲਈ ਟਾਈਮ ਆਊਟ ਹੋਇਆ ਸੀ।"</string>
+ <string name="pbap_authentication_timeout_message" msgid="4166979525521902687">"%1$s ਨਾਲ ਸੈਸ਼ਨ ਕੁੰਜੀ ਇਨਪੁੱਟ ਕਰਨ ਲਈ ਟਾਈਮ ਆਊਟ ਹੋਇਆ ਸੀ।"</string>
<string name="auth_notif_ticker" msgid="1575825798053163744">"Obex ਪ੍ਰਮਾਣੀਕਰਨ ਬੇਨਤੀ"</string>
<string name="auth_notif_title" msgid="7599854855681573258">"ਸੈਸ਼ਨ ਕੁੰਜੀ"</string>
<string name="auth_notif_message" msgid="6667218116427605038">"%1$s ਲਈ ਸੈਸ਼ਨ ਕੁੰਜੀ ਟਾਈਪ ਕਰੋ"</string>
diff --git a/res/values-pa/strings_sap.xml b/res/values-pa/strings_sap.xml
index 60141ce..b2440a8 100644
--- a/res/values-pa/strings_sap.xml
+++ b/res/values-pa/strings_sap.xml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="bluetooth_sap_notif_title" msgid="6877860822993195074">"ਬਲੂਟੁੱਥ ਸਿਮ ਐਕਸੈਸ"</string>
- <string name="bluetooth_sap_notif_ticker" msgid="6807778527893726699">"ਬਲੂਟੁੱਥ ਸਿਮ ਐਕਸੈਸ"</string>
+ <string name="bluetooth_sap_notif_title" msgid="6877860822993195074">"ਬਲੂਟੁੱਥ ਸਿਮ ਪਹੁੰਚ"</string>
+ <string name="bluetooth_sap_notif_ticker" msgid="6807778527893726699">"ਬਲੂਟੁੱਥ ਸਿਮ ਪਹੁੰਚ"</string>
<string name="bluetooth_sap_notif_message" msgid="7138657801087500690">"ਕੀ ਡਿਸਕਨੈਕਟ ਕਰਨ ਲਈ ਕਲਾਇੰਟ ਨੂੰ ਬੇਨਤੀ ਕਰਨੀ ਹੈ?"</string>
<string name="bluetooth_sap_notif_disconnecting" msgid="819150843490233288">"ਡਿਸਕਨੈਕਟ ਕਰਨ ਲਈ ਕਲਾਇੰਟ ਦੀ ਉਡੀਕ ਹੋਰ ਰਹੀ ਹੈ"</string>
<string name="bluetooth_sap_notif_disconnect_button" msgid="3678476872583356919">"ਡਿਸਕਨੈਕਟ ਕਰੋ"</string>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
index a484d94..8163e92 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -23,8 +23,8 @@
<string name="bt_share_picker_label" msgid="6268100924487046932">"బ్లూటూత్"</string>
<string name="unknown_device" msgid="9221903979877041009">"తెలియని పరికరం"</string>
<string name="unknownNumber" msgid="4994750948072751566">"తెలియదు"</string>
- <string name="airplane_error_title" msgid="2683839635115739939">"ఎయిర్ప్లైన్ మోడ్"</string>
- <string name="airplane_error_msg" msgid="8698965595254137230">"మీరు ఎయిర్ప్లైన్ మోడ్లో బ్లూటూత్ను ఉపయోగించలేరు."</string>
+ <string name="airplane_error_title" msgid="2683839635115739939">"ఎయిర్ప్లేన్ మోడ్"</string>
+ <string name="airplane_error_msg" msgid="8698965595254137230">"మీరు ఎయిర్ప్లేన్ మోడ్లో బ్లూటూత్ను ఉపయోగించలేరు."</string>
<string name="bt_enable_title" msgid="8657832550503456572"></string>
<string name="bt_enable_line1" msgid="7203551583048149">"బ్లూటూత్ సేవలను ఉపయోగించడానికి, మీరు తప్పనిసరిగా ముందుగా బ్లూటూత్ను ప్రారంభించాలి."</string>
<string name="bt_enable_line2" msgid="4341936569415937994">"ఇప్పుడే బ్లూటూత్ను ప్రారంభించాలా?"</string>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index c5f5bb7..402cb73 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -30,7 +30,7 @@
<string name="bt_enable_line2" msgid="4341936569415937994">"Bluetooth hozir yoqilsinmi?"</string>
<string name="bt_enable_cancel" msgid="1988832367505151727">"Bekor qilish"</string>
<string name="bt_enable_ok" msgid="3432462749994538265">"Yoqish"</string>
- <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Fayl o‘tkazish"</string>
+ <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Fayl uzatish"</string>
<string name="incoming_file_confirm_content" msgid="2752605552743148036">"Fayl qabul qilinsinmi?"</string>
<string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Rad etish"</string>
<string name="incoming_file_confirm_ok" msgid="281462442932231475">"Qabul qilish"</string>
@@ -45,7 +45,7 @@
<string name="notification_sent" msgid="9218710861333027778">"Bluetooth orqali yuborildi: <xliff:g id="FILE">%1$s</xliff:g>"</string>
<string name="notification_sent_complete" msgid="302943281067557969">"100% tugadi"</string>
<string name="notification_sent_fail" msgid="6696082233774569445">"Fayl yuborilmadi: <xliff:g id="FILE">%1$s</xliff:g>"</string>
- <string name="download_title" msgid="3353228219772092586">"Fayl o‘tkazish"</string>
+ <string name="download_title" msgid="3353228219772092586">"Fayl uzatish"</string>
<string name="download_line1" msgid="4926604799202134144">"Yuboruvchi: \"<xliff:g id="SENDER">%1$s</xliff:g>\""</string>
<string name="download_line2" msgid="5876973543019417712">"Fayl: <xliff:g id="FILE">%1$s</xliff:g>"</string>
<string name="download_line3" msgid="4384821622908676061">"Fayl hajmi: <xliff:g id="SIZE">%1$s</xliff:g>"</string>
diff --git a/res/values/config.xml b/res/values/config.xml
index b95417b..05448c5 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -58,11 +58,15 @@
<bool name="headset_client_initial_audio_route_allowed">true</bool>
- <!-- For AVRCP absolute volume feature. If the threshold is non-zero,
- restrict the initial volume to the threshold.
- Valid value is 1-14, and recommended value is 8 -->
+ <!-- @deprecated: use a2dp_absolute_volume_initial_threshold_percent
+ instead. -->
<integer name="a2dp_absolute_volume_initial_threshold">8</integer>
+ <!-- AVRCP absolute volume initial value as percent of the maximum value.
+ Valid values are in the interval [0, 100].
+ Recommended value is 50. -->
+ <integer name="a2dp_absolute_volume_initial_threshold_percent">50</integer>
+
<!-- For A2DP sink ducking volume feature. -->
<integer name="a2dp_sink_duck_percent">25</integer>
diff --git a/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandler.java b/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandler.java
index bf5ca22..dae6df5 100644
--- a/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandler.java
+++ b/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandler.java
@@ -19,6 +19,7 @@
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.media.AudioAttributes;
+import android.media.AudioFocusRequest;
import android.media.AudioManager;
import android.media.AudioManager.OnAudioFocusChangeListener;
import android.os.Handler;
@@ -212,8 +213,22 @@
* Utility functions.
*/
private int requestAudioFocus() {
- int focusRequestStatus = mAudioManager.requestAudioFocus(
- mAudioFocusListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
+ // Bluetooth A2DP may carry Music, Audio Books, Navigation, or other sounds so mark content
+ // type unknown.
+ AudioAttributes streamAttributes =
+ new AudioAttributes.Builder()
+ .setUsage(AudioAttributes.USAGE_MEDIA)
+ .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
+ .build();
+ // Bluetooth ducking is handled at the native layer so tell the Audio Manger to notify the
+ // focus change listener via .setWillPauseWhenDucked().
+ AudioFocusRequest focusRequest =
+ new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
+ .setAudioAttributes(streamAttributes)
+ .setWillPauseWhenDucked(true)
+ .setOnAudioFocusChangeListener(mAudioFocusListener, this)
+ .build();
+ int focusRequestStatus = mAudioManager.requestAudioFocus(focusRequest);
// If the request is granted begin streaming immediately and schedule an upgrade.
if (focusRequestStatus == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
startAvrcpUpdates();
diff --git a/src/com/android/bluetooth/avrcp/Avrcp.java b/src/com/android/bluetooth/avrcp/Avrcp.java
index 274c10b..a00502c 100644
--- a/src/com/android/bluetooth/avrcp/Avrcp.java
+++ b/src/com/android/bluetooth/avrcp/Avrcp.java
@@ -33,6 +33,7 @@
import android.content.res.Resources;
import android.content.SharedPreferences;
import android.media.AudioManager;
+import android.media.AudioPlaybackConfiguration;
import android.media.MediaDescription;
import android.media.MediaMetadata;
import android.media.browse.MediaBrowser;
@@ -78,6 +79,8 @@
private Context mContext;
private final AudioManager mAudioManager;
private AvrcpMessageHandler mHandler;
+ private Handler mAudioManagerPlaybackHandler;
+ private AudioManagerPlaybackListener mAudioManagerPlaybackCb;
private MediaSessionManager mMediaSessionManager;
private @Nullable MediaController mMediaController;
private MediaControllerListener mMediaControllerCb;
@@ -87,6 +90,7 @@
private int mTransportControlFlags;
private @NonNull PlaybackState mCurrentPlayState;
private int mA2dpState;
+ private boolean mAudioManagerIsPlaying;
private int mPlayStatusChangedNT;
private byte mReportedPlayStatus;
private int mTrackChangedNT;
@@ -240,6 +244,7 @@
mCurrentPlayState = new PlaybackState.Builder().setState(PlaybackState.STATE_NONE, -1L, 0.0f).build();
mReportedPlayStatus = PLAYSTATUS_ERROR;
mA2dpState = BluetoothA2dp.STATE_NOT_PLAYING;
+ mAudioManagerIsPlaying = false;
mPlayStatusChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED;
mTrackChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED;
mPlayPosChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED;
@@ -279,6 +284,13 @@
Resources resources = context.getResources();
if (resources != null) {
mAbsVolThreshold = resources.getInteger(R.integer.a2dp_absolute_volume_initial_threshold);
+
+ // Update the threshold if the threshold_percent is valid
+ int threshold_percent =
+ resources.getInteger(R.integer.a2dp_absolute_volume_initial_threshold_percent);
+ if (threshold_percent >= 0 && threshold_percent <= 100) {
+ mAbsVolThreshold = (threshold_percent * mAudioStreamMax) / 100;
+ }
}
// Register for package removal intent broadcasts for media button receiver persistence
@@ -300,6 +312,8 @@
thread.start();
Looper looper = thread.getLooper();
mHandler = new AvrcpMessageHandler(looper);
+ mAudioManagerPlaybackHandler = new Handler(looper);
+ mAudioManagerPlaybackCb = new AudioManagerPlaybackListener();
mMediaControllerCb = new MediaControllerListener();
mAvrcpMediaRsp = new AvrcpMediaRsp();
mMediaPlayerInfoList = new TreeMap<Integer, MediaPlayerInfo>();
@@ -329,6 +343,9 @@
// initialize browsable player list and build media player list
buildBrowsablePlayerList();
}
+
+ mAudioManager.registerAudioPlaybackCallback(
+ mAudioManagerPlaybackCb, mAudioManagerPlaybackHandler);
}
public static Avrcp make(Context context) {
@@ -340,18 +357,23 @@
public synchronized void doQuit() {
if (DEBUG) Log.d(TAG, "doQuit");
+ if (mAudioManager != null) {
+ mAudioManager.unregisterAudioPlaybackCallback(mAudioManagerPlaybackCb);
+ }
if (mMediaController != null) mMediaController.unregisterCallback(mMediaControllerCb);
if (mMediaSessionManager != null) {
mMediaSessionManager.setCallback(null, null);
mMediaSessionManager.removeOnActiveSessionsChangedListener(mActiveSessionListener);
}
+ mAudioManagerPlaybackHandler.removeCallbacksAndMessages(null);
mHandler.removeCallbacksAndMessages(null);
Looper looper = mHandler.getLooper();
if (looper != null) {
looper.quit();
}
+ mAudioManagerPlaybackHandler = null;
mHandler = null;
mContext.unregisterReceiver(mAvrcpReceiver);
mContext.unregisterReceiver(mBootReceiver);
@@ -367,6 +389,30 @@
mVolumeMapping.clear();
}
+ private class AudioManagerPlaybackListener extends AudioManager.AudioPlaybackCallback {
+ @Override
+ public void onPlaybackConfigChanged(List<AudioPlaybackConfiguration> configs) {
+ super.onPlaybackConfigChanged(configs);
+ boolean isPlaying = false;
+ for (AudioPlaybackConfiguration config : configs) {
+ if (DEBUG) {
+ Log.d(TAG,
+ "AudioManager Player: "
+ + AudioPlaybackConfiguration.toLogFriendlyString(config));
+ }
+ if (config.getPlayerState() == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) {
+ isPlaying = true;
+ break;
+ }
+ }
+ if (DEBUG) Log.d(TAG, "AudioManager isPlaying: " + isPlaying);
+ if (mAudioManagerIsPlaying != isPlaying) {
+ mAudioManagerIsPlaying = isPlaying;
+ updateCurrentMediaState();
+ }
+ }
+ }
+
private class MediaControllerListener extends MediaController.Callback {
@Override
public void onMetadataChanged(MediaMetadata metadata) {
@@ -413,10 +459,13 @@
case MSG_NATIVE_REQ_GET_RC_FEATURES:
{
String address = (String) msg.obj;
- if (DEBUG) Log.v(TAG, "MSG_NATIVE_REQ_GET_RC_FEATURES: address="+address+
- ", features="+msg.arg1);
mFeatures = msg.arg1;
mFeatures = modifyRcFeatureFromBlacklist(mFeatures, address);
+ if (DEBUG) {
+ Log.v(TAG,
+ "MSG_NATIVE_REQ_GET_RC_FEATURES: address=" + address
+ + ", features=" + msg.arg1 + ", mFeatures=" + mFeatures);
+ }
mAudioManager.avrcpSupportsAbsoluteVolume(address, isAbsoluteVolumeSupported());
mLastLocalVolume = -1;
mRemoteVolume = -1;
@@ -797,10 +846,22 @@
if (controllerState != null) {
newState = controllerState;
- } else if (mAudioManager != null && mAudioManager.isMusicActive()) {
- // Use A2DP state if we don't have a state from MediaControlller
+ }
+ // Use the AudioManager to update the playback state.
+ // NOTE: We cannot use the
+ // (mA2dpState == BluetoothA2dp.STATE_PLAYING)
+ // check, because after Pause, the A2DP state remains in
+ // STATE_PLAYING for 3 more seconds.
+ // As a result of that, if we pause the music, on carkits the
+ // Play status indicator will continue to display "Playing"
+ // for 3 more seconds which can be confusing.
+ if ((mAudioManagerIsPlaying && newState.getState() != PlaybackState.STATE_PLAYING)
+ || (controllerState == null && mAudioManager != null
+ && mAudioManager.isMusicActive())) {
+ // Use AudioManager playback state if we don't have the state
+ // from MediaControlller
PlaybackState.Builder builder = new PlaybackState.Builder();
- if (mA2dpState == BluetoothA2dp.STATE_PLAYING) {
+ if (mAudioManagerIsPlaying) {
builder.setState(PlaybackState.STATE_PLAYING,
PlaybackState.PLAYBACK_POSITION_UNKNOWN, 1.0f);
} else {
@@ -1016,22 +1077,6 @@
mAddressedMediaPlayer.updateNowPlayingList(mMediaController);
}
- if ((newQueueId == -1 || newQueueId != mLastQueueId)
- && currentAttributes.equals(mMediaAttributes)
- && newPlayStatus == PLAYSTATUS_PLAYING
- && mReportedPlayStatus == PLAYSTATUS_STOPPED) {
- // Most carkits like seeing the track changed before the
- // playback state changed, but some controllers are slow
- // to update their metadata. Hold of on sending the playback state
- // update until after we know the current metadata is up to date
- // and track changed has been sent. This was seen on BMW carkits
- Log.i(TAG,
- "Waiting for metadata update to send track changed: " + newQueueId + " : "
- + currentAttributes + " : " + mMediaAttributes);
-
- return;
- }
-
// Notify track changed if:
// - The CT is registered for the notification
// - Queue ID is UNKNOWN and MediaMetadata is different
@@ -1050,9 +1095,11 @@
}
// still send the updated play state if the playback state is none or buffering
- Log.e(TAG, "play status change " + mReportedPlayStatus + "➡" + newPlayStatus);
+ Log.e(TAG,
+ "play status change " + mReportedPlayStatus + "➡" + newPlayStatus
+ + " mPlayStatusChangedNT: " + mPlayStatusChangedNT);
if (mPlayStatusChangedNT == AvrcpConstants.NOTIFICATION_TYPE_INTERIM
- && (mReportedPlayStatus != newPlayStatus)) {
+ || (mReportedPlayStatus != newPlayStatus)) {
sendPlaybackStatus(AvrcpConstants.NOTIFICATION_TYPE_CHANGED, newPlayStatus);
}
@@ -2364,6 +2411,20 @@
ProfileService.println(sb, " " + log);
}
}
+
+ // Print the blacklisted devices (for absolute volume control)
+ SharedPreferences pref =
+ mContext.getSharedPreferences(ABSOLUTE_VOLUME_BLACKLIST, Context.MODE_PRIVATE);
+ Map<String, ?> allKeys = pref.getAll();
+ ProfileService.println(sb, "");
+ ProfileService.println(sb, "Runtime Blacklisted Devices (absolute volume):");
+ if (allKeys.isEmpty()) {
+ ProfileService.println(sb, " None");
+ } else {
+ for (String key : allKeys.keySet()) {
+ ProfileService.println(sb, " " + key);
+ }
+ }
}
public class AvrcpBrowseManager {
diff --git a/src/com/android/bluetooth/btservice/AdapterProperties.java b/src/com/android/bluetooth/btservice/AdapterProperties.java
index 788074b..07b7bfe 100644
--- a/src/com/android/bluetooth/btservice/AdapterProperties.java
+++ b/src/com/android/bluetooth/btservice/AdapterProperties.java
@@ -65,8 +65,8 @@
private CopyOnWriteArrayList<BluetoothDevice> mBondedDevices = new CopyOnWriteArrayList<BluetoothDevice>();
private int mProfilesConnecting, mProfilesConnected, mProfilesDisconnecting;
- private HashMap<Integer, Pair<Integer, Integer>> mProfileConnectionState;
-
+ private final HashMap<Integer, Pair<Integer, Integer>> mProfileConnectionState =
+ new HashMap<>();
private volatile int mConnectionState = BluetoothAdapter.STATE_DISCONNECTED;
private volatile int mState = BluetoothAdapter.STATE_OFF;
@@ -97,32 +97,51 @@
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- Log.d(TAG, "Received intent " + intent);
String action = intent.getAction();
- if (BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
- sendConnectionStateChange(BluetoothProfile.HEADSET, intent);
- } else if (BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
- sendConnectionStateChange(BluetoothProfile.A2DP, intent);
- } else if (BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
- sendConnectionStateChange(BluetoothProfile.HEADSET_CLIENT, intent);
- } else if (BluetoothA2dpSink.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
- sendConnectionStateChange(BluetoothProfile.A2DP_SINK, intent);
- } else if (BluetoothInputHost.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
- sendConnectionStateChange(BluetoothProfile.INPUT_HOST, intent);
- } else if (BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
- sendConnectionStateChange(BluetoothProfile.INPUT_DEVICE, intent);
- } else if (BluetoothAvrcpController.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
- sendConnectionStateChange(BluetoothProfile.AVRCP_CONTROLLER, intent);
- } else if (BluetoothPan.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
- sendConnectionStateChange(BluetoothProfile.PAN, intent);
- } else if (BluetoothMap.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
- sendConnectionStateChange(BluetoothProfile.MAP, intent);
- } else if (BluetoothMapClient.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
- sendConnectionStateChange(BluetoothProfile.MAP_CLIENT, intent);
- } else if (BluetoothSap.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
- sendConnectionStateChange(BluetoothProfile.SAP, intent);
- } else if (BluetoothPbapClient.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
- sendConnectionStateChange(BluetoothProfile.PBAP_CLIENT, intent);
+ if (action == null) {
+ Log.w(TAG, "Received intent with null action");
+ return;
+ }
+ switch (action) {
+ case BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED:
+ sendConnectionStateChange(BluetoothProfile.HEADSET, intent);
+ break;
+ case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED:
+ sendConnectionStateChange(BluetoothProfile.A2DP, intent);
+ break;
+ case BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED:
+ sendConnectionStateChange(BluetoothProfile.HEADSET_CLIENT, intent);
+ break;
+ case BluetoothA2dpSink.ACTION_CONNECTION_STATE_CHANGED:
+ sendConnectionStateChange(BluetoothProfile.A2DP_SINK, intent);
+ break;
+ case BluetoothInputHost.ACTION_CONNECTION_STATE_CHANGED:
+ sendConnectionStateChange(BluetoothProfile.INPUT_HOST, intent);
+ break;
+ case BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED:
+ sendConnectionStateChange(BluetoothProfile.INPUT_DEVICE, intent);
+ break;
+ case BluetoothAvrcpController.ACTION_CONNECTION_STATE_CHANGED:
+ sendConnectionStateChange(BluetoothProfile.AVRCP_CONTROLLER, intent);
+ break;
+ case BluetoothPan.ACTION_CONNECTION_STATE_CHANGED:
+ sendConnectionStateChange(BluetoothProfile.PAN, intent);
+ break;
+ case BluetoothMap.ACTION_CONNECTION_STATE_CHANGED:
+ sendConnectionStateChange(BluetoothProfile.MAP, intent);
+ break;
+ case BluetoothMapClient.ACTION_CONNECTION_STATE_CHANGED:
+ sendConnectionStateChange(BluetoothProfile.MAP_CLIENT, intent);
+ break;
+ case BluetoothSap.ACTION_CONNECTION_STATE_CHANGED:
+ sendConnectionStateChange(BluetoothProfile.SAP, intent);
+ break;
+ case BluetoothPbapClient.ACTION_CONNECTION_STATE_CHANGED:
+ sendConnectionStateChange(BluetoothProfile.PBAP_CLIENT, intent);
+ break;
+ default:
+ Log.w(TAG, "Received unknown intent " + intent);
+ break;
}
}
};
@@ -130,18 +149,14 @@
// Lock for all getters and setters.
// If finer grained locking is needer, more locks
// can be added here.
- private Object mObject = new Object();
+ private final Object mObject = new Object();
public AdapterProperties(AdapterService service) {
mService = service;
mAdapter = BluetoothAdapter.getDefaultAdapter();
}
public void init(RemoteDevices remoteDevices) {
- if (mProfileConnectionState ==null) {
- mProfileConnectionState = new HashMap<Integer, Pair<Integer, Integer>>();
- } else {
- mProfileConnectionState.clear();
- }
+ mProfileConnectionState.clear();
mRemoteDevices = remoteDevices;
IntentFilter filter = new IntentFilter();
@@ -157,17 +172,13 @@
filter.addAction(BluetoothMapClient.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothSap.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothPbapClient.ACTION_CONNECTION_STATE_CHANGED);
- filter.addAction(BluetoothDevice.ACTION_UUID);
mService.registerReceiver(mReceiver, filter);
mReceiverRegistered = true;
}
public void cleanup() {
mRemoteDevices = null;
- if (mProfileConnectionState != null) {
- mProfileConnectionState.clear();
- mProfileConnectionState = null;
- }
+ mProfileConnectionState.clear();
if (mReceiverRegistered) {
mService.unregisterReceiver(mReceiver);
mReceiverRegistered = false;
@@ -233,18 +244,6 @@
}
/**
- * Set local adapter UUIDs.
- *
- * @param uuids the uuids to be set.
- */
- boolean setUuids(ParcelUuid[] uuids) {
- synchronized (mObject) {
- return mService.setAdapterPropertyNative(
- AbstractionLayer.BT_PROPERTY_UUIDS, Utils.uuidsToByteArray(uuids));
- }
- }
-
- /**
* @return the mAddress
*/
byte[] getAddress() {
@@ -382,8 +381,10 @@
// state changes.
void onBondStateChanged(BluetoothDevice device, int state)
{
- if(device == null)
+ if (device == null) {
+ Log.w(TAG, "onBondStateChanged, device is null");
return;
+ }
try {
byte[] addrByte = Utils.getByteAddress(device);
DeviceProperties prop = mRemoteDevices.getDeviceProperties(device);
@@ -406,7 +407,7 @@
}
}
catch(Exception ee) {
- Log.e(TAG, "Exception in onBondStateChanged : ", ee);
+ Log.w(TAG, "onBondStateChanged: Exception ", ee);
}
}
@@ -442,6 +443,14 @@
BluetoothDevice device = connIntent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
int prevState = connIntent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, -1);
int state = connIntent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);
+ Log.d(TAG,
+ "PROFILE_CONNECTION_STATE_CHANGE: profile=" + profile + ", device=" + device + ", "
+ + prevState + " -> " + state);
+ if (!isNormalStateTransition(prevState, state)) {
+ Log.w(TAG,
+ "PROFILE_CONNECTION_STATE_CHANGE: unexpected transition for profile=" + profile
+ + ", device=" + device + ", " + prevState + " -> " + state);
+ }
sendConnectionStateChange(device, profile, state, prevState);
}
void sendConnectionStateChange(BluetoothDevice device, int profile, int state, int prevState) {
@@ -451,8 +460,8 @@
// with the invalid state converted to -1 in the intent.
// Better to log an error and not send an intent with
// invalid contents or set mAdapterConnectionState to -1.
- errorLog("Error in sendConnectionStateChange: "
- + "prevState " + prevState + " state " + state);
+ errorLog("sendConnectionStateChange: invalid state transition " + prevState + " -> "
+ + state);
return;
}
@@ -460,19 +469,25 @@
updateProfileConnectionState(profile, state, prevState);
if (updateCountersAndCheckForConnectionStateChange(state, prevState)) {
- setConnectionState(state);
+ int newAdapterState = convertToAdapterState(state);
+ int prevAdapterState = convertToAdapterState(prevState);
+ setConnectionState(newAdapterState);
Intent intent = new Intent(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
- intent.putExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE,
- convertToAdapterState(state));
- intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_CONNECTION_STATE,
- convertToAdapterState(prevState));
+ intent.putExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, newAdapterState);
+ intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_CONNECTION_STATE, prevAdapterState);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- mService.sendBroadcastAsUser(intent, UserHandle.ALL,
- mService.BLUETOOTH_PERM);
- Log.d(TAG, "CONNECTION_STATE_CHANGE: " + device + ": "
- + prevState + " -> " + state);
+ Log.d(TAG,
+ "ADAPTER_CONNECTION_STATE_CHANGE: " + device + ": " + prevAdapterState
+ + " -> " + newAdapterState);
+ if (!isNormalStateTransition(prevState, state)) {
+ Log.w(TAG,
+ "ADAPTER_CONNECTION_STATE_CHANGE: unexpected transition for profile="
+ + profile + ", device=" + device + ", " + prevState + " -> "
+ + state);
+ }
+ mService.sendBroadcastAsUser(intent, UserHandle.ALL, AdapterService.BLUETOOTH_PERM);
}
}
}
@@ -484,8 +499,7 @@
state == BluetoothProfile.STATE_DISCONNECTING);
}
-
- private int convertToAdapterState(int state) {
+ private static int convertToAdapterState(int state) {
switch (state) {
case BluetoothProfile.STATE_DISCONNECTED:
return BluetoothAdapter.STATE_DISCONNECTED;
@@ -496,10 +510,25 @@
case BluetoothProfile.STATE_CONNECTING:
return BluetoothAdapter.STATE_CONNECTING;
}
- Log.e(TAG, "Error in convertToAdapterState");
+ Log.e(TAG, "convertToAdapterState, unknow state " + state);
return -1;
}
+ private static boolean isNormalStateTransition(int prevState, int nextState) {
+ switch (prevState) {
+ case BluetoothProfile.STATE_DISCONNECTED:
+ return nextState == BluetoothProfile.STATE_CONNECTING;
+ case BluetoothProfile.STATE_CONNECTED:
+ return nextState == BluetoothProfile.STATE_DISCONNECTING;
+ case BluetoothProfile.STATE_DISCONNECTING:
+ case BluetoothProfile.STATE_CONNECTING:
+ return (nextState == BluetoothProfile.STATE_DISCONNECTED)
+ || (nextState == BluetoothProfile.STATE_CONNECTED);
+ default:
+ return false;
+ }
+ }
+
private boolean updateCountersAndCheckForConnectionStateChange(int state, int prevState) {
switch (prevState) {
case BluetoothProfile.STATE_CONNECTING:
@@ -611,8 +640,8 @@
intent = new Intent(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
intent.putExtra(BluetoothAdapter.EXTRA_LOCAL_NAME, mName);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- mService.sendBroadcastAsUser(intent, UserHandle.ALL,
- mService.BLUETOOTH_PERM);
+ mService.sendBroadcastAsUser(
+ intent, UserHandle.ALL, AdapterService.BLUETOOTH_PERM);
debugLog("Name is: " + mName);
break;
case AbstractionLayer.BT_PROPERTY_BDADDR:
@@ -623,7 +652,7 @@
intent.putExtra(BluetoothAdapter.EXTRA_BLUETOOTH_ADDRESS, address);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
mService.sendBroadcastAsUser(
- intent, UserHandle.ALL, mService.BLUETOOTH_PERM);
+ intent, UserHandle.ALL, AdapterService.BLUETOOTH_PERM);
break;
case AbstractionLayer.BT_PROPERTY_CLASS_OF_DEVICE:
mBluetoothClass = Utils.byteArrayToInt(val, 0);
@@ -631,11 +660,11 @@
break;
case AbstractionLayer.BT_PROPERTY_ADAPTER_SCAN_MODE:
int mode = Utils.byteArrayToInt(val, 0);
- mScanMode = mService.convertScanModeFromHal(mode);
+ mScanMode = AdapterService.convertScanModeFromHal(mode);
intent = new Intent(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
intent.putExtra(BluetoothAdapter.EXTRA_SCAN_MODE, mScanMode);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- mService.sendBroadcast(intent, mService.BLUETOOTH_PERM);
+ mService.sendBroadcast(intent, AdapterService.BLUETOOTH_PERM);
debugLog("Scan Mode:" + mScanMode);
if (mBluetoothDisabling) {
mBluetoothDisabling=false;
@@ -671,7 +700,7 @@
}
}
- void updateFeatureSupport(byte[] val) {
+ private void updateFeatureSupport(byte[] val) {
mVersSupported = ((0xFF & ((int)val[1])) << 8)
+ (0xFF & ((int)val[0]));
mNumOfAdvertisementInstancesSupported = (0xFF & ((int)val[3]));
@@ -726,12 +755,17 @@
}
void onBluetoothReady() {
- Log.d(TAG, "ScanMode = " + mScanMode );
- Log.d(TAG, "State = " + getState() );
+ debugLog("onBluetoothReady, state=" + getState() + ", ScanMode=" + mScanMode);
- // When BT is being turned on, all adapter properties will be sent in 1
- // callback. At this stage, set the scan mode.
synchronized (mObject) {
+ // Reset adapter and profile connection states
+ setConnectionState(BluetoothAdapter.STATE_DISCONNECTED);
+ mProfileConnectionState.clear();
+ mProfilesConnected = 0;
+ mProfilesConnecting = 0;
+ mProfilesDisconnecting = 0;
+ // When BT is being turned on, all adapter properties will be sent in 1
+ // callback. At this stage, set the scan mode.
if (getState() == BluetoothAdapter.STATE_TURNING_ON &&
mScanMode == BluetoothAdapter.SCAN_MODE_NONE) {
/* mDiscoverableTimeout is part of the
@@ -783,25 +817,25 @@
mDiscovering = false;
mDiscoveryEndMs = System.currentTimeMillis();
intent = new Intent(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
- mService.sendBroadcast(intent, mService.BLUETOOTH_PERM);
+ mService.sendBroadcast(intent, AdapterService.BLUETOOTH_PERM);
} else if (state == AbstractionLayer.BT_DISCOVERY_STARTED) {
mDiscovering = true;
mDiscoveryEndMs = System.currentTimeMillis() + DEFAULT_DISCOVERY_TIMEOUT_MS;
intent = new Intent(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
- mService.sendBroadcast(intent, mService.BLUETOOTH_PERM);
+ mService.sendBroadcast(intent, AdapterService.BLUETOOTH_PERM);
}
}
}
- private void infoLog(String msg) {
+ private static void infoLog(String msg) {
if (VDBG) Log.i(TAG, msg);
}
- private void debugLog(String msg) {
+ private static void debugLog(String msg) {
if (DBG) Log.d(TAG, msg);
}
- private void errorLog(String msg) {
+ private static void errorLog(String msg) {
Log.e(TAG, msg);
}
}
diff --git a/src/com/android/bluetooth/btservice/AdapterService.java b/src/com/android/bluetooth/btservice/AdapterService.java
index 7c404d9..e04ca8b 100644
--- a/src/com/android/bluetooth/btservice/AdapterService.java
+++ b/src/com/android/bluetooth/btservice/AdapterService.java
@@ -1499,6 +1499,7 @@
}
boolean startDiscovery() {
+ debugLog("startDiscovery");
enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH ADMIN permission");
@@ -1506,6 +1507,7 @@
}
boolean cancelDiscovery() {
+ debugLog("cancelDiscovery");
enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH ADMIN permission");
diff --git a/src/com/android/bluetooth/btservice/PhonePolicy.java b/src/com/android/bluetooth/btservice/PhonePolicy.java
index 19817bf..b3ef04b 100644
--- a/src/com/android/bluetooth/btservice/PhonePolicy.java
+++ b/src/com/android/bluetooth/btservice/PhonePolicy.java
@@ -41,6 +41,7 @@
import com.android.bluetooth.pan.PanService;
import com.android.internal.R;
+import java.util.HashSet;
import java.util.List;
// Describes the phone policy
@@ -78,41 +79,53 @@
final private static int MESSAGE_CONNECT_OTHER_PROFILES = 3;
final private static int MESSAGE_ADAPTER_STATE_TURNED_ON = 4;
- public static final int PROFILE_CONN_CONNECTED = 1;
-
// Timeouts
final private static int CONNECT_OTHER_PROFILES_TIMEOUT = 6000; // 6s
final private AdapterService mAdapterService;
final private ServiceFactory mFactory;
final private Handler mHandler;
+ final private HashSet<BluetoothDevice> mHeadsetRetrySet = new HashSet<>();
+ final private HashSet<BluetoothDevice> mA2dpRetrySet = new HashSet<>();
// Broadcast receiver for all changes to states of various profiles
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- Log.d(TAG, "Received intent " + intent);
- if (BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED.equals(intent.getAction())) {
- mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED,
- BluetoothProfile.HEADSET,
- -1, // No-op argument
- intent)
- .sendToTarget();
- } else if (BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED.equals(intent.getAction())) {
- mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED,
- BluetoothProfile.A2DP,
- -1, // No-op argument
- intent)
- .sendToTarget();
- } else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())) {
- // Only pass the message on if the adapter has actually changed state from
- // non-ON to ON. NOTE: ON is the state depicting BREDR ON and not just BLE ON.
- int newState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
- if (newState == BluetoothAdapter.STATE_ON) {
- mHandler.obtainMessage(MESSAGE_ADAPTER_STATE_TURNED_ON).sendToTarget();
- }
- } else if (BluetoothDevice.ACTION_UUID.equals(intent.getAction())) {
- mHandler.obtainMessage(MESSAGE_PROFILE_INIT_PRIORITIES, intent).sendToTarget();
+ String action = intent.getAction();
+ if (action == null) {
+ errorLog("Received intent with null action");
+ return;
+ }
+ switch (action) {
+ case BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED:
+ mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED,
+ BluetoothProfile.HEADSET,
+ -1, // No-op argument
+ intent)
+ .sendToTarget();
+ break;
+ case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED:
+ mHandler.obtainMessage(MESSAGE_PROFILE_CONNECTION_STATE_CHANGED,
+ BluetoothProfile.A2DP,
+ -1, // No-op argument
+ intent)
+ .sendToTarget();
+ break;
+ case BluetoothAdapter.ACTION_STATE_CHANGED:
+ // Only pass the message on if the adapter has actually changed state from
+ // non-ON to ON. NOTE: ON is the state depicting BREDR ON and not just BLE ON.
+ int newState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
+ if (newState == BluetoothAdapter.STATE_ON) {
+ mHandler.obtainMessage(MESSAGE_ADAPTER_STATE_TURNED_ON).sendToTarget();
+ }
+ break;
+ case BluetoothDevice.ACTION_UUID:
+ mHandler.obtainMessage(MESSAGE_PROFILE_INIT_PRIORITIES, intent).sendToTarget();
+ break;
+ default:
+ Log.e(TAG, "Received unexpected intent, action=" + action);
+ break;
}
}
};
@@ -132,17 +145,16 @@
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_PROFILE_INIT_PRIORITIES: {
+ Intent intent = (Intent) msg.obj;
BluetoothDevice device =
- (BluetoothDevice) ((Intent) msg.obj)
- .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
- Parcelable[] uuids =
- ((Intent) msg.obj).getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID);
-
- Log.d(TAG, "UUIDs on ACTION_UUID: " + uuids + " for device " + device);
+ intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+ Parcelable[] uuids = intent.getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID);
+ debugLog("Received ACTION_UUID for device " + device);
if (uuids != null) {
ParcelUuid[] uuidsToSend = new ParcelUuid[uuids.length];
for (int i = 0; i < uuidsToSend.length; i++) {
uuidsToSend[i] = (ParcelUuid) uuids[i];
+ debugLog("index=" + i + "uuid=" + uuidsToSend[i]);
}
processInitProfilePriorities(device, uuidsToSend);
}
@@ -165,6 +177,7 @@
case MESSAGE_ADAPTER_STATE_TURNED_ON:
// Call auto connect when adapter switches state to ON
+ resetStates();
autoConnect();
break;
}
@@ -182,6 +195,7 @@
}
protected void cleanup() {
mAdapterService.unregisterReceiver(mReceiver);
+ resetStates();
}
PhonePolicy(AdapterService service, ServiceFactory factory) {
@@ -192,7 +206,7 @@
// Policy implementation, all functions MUST be private
private void processInitProfilePriorities(BluetoothDevice device, ParcelUuid[] uuids) {
- debugLog("processInitProfilePriorities() - device " + device + " UUIDs " + uuids);
+ debugLog("processInitProfilePriorities() - device " + device);
HidService hidService = mFactory.getHidService();
A2dpService a2dpService = mFactory.getA2dpService();
HeadsetService headsetService = mFactory.getHeadsetService();
@@ -235,23 +249,35 @@
private void processProfileStateChanged(
BluetoothDevice device, int profileId, int nextState, int prevState) {
- // Profiles relevant to phones.
+ debugLog("processProfileStateChanged, device=" + device + ", profile=" + profileId + ", "
+ + prevState + " -> " + nextState);
if (((profileId == BluetoothProfile.A2DP) || (profileId == BluetoothProfile.HEADSET))
&& (nextState == BluetoothProfile.STATE_CONNECTED)) {
- debugLog("Profile connected id: " + profileId
- + " Schedule missing profile connection if any");
+ switch (profileId) {
+ case BluetoothProfile.A2DP:
+ mA2dpRetrySet.remove(device);
+ break;
+ case BluetoothProfile.HEADSET:
+ mHeadsetRetrySet.remove(device);
+ break;
+ }
connectOtherProfile(device);
setProfileAutoConnectionPriority(device, profileId);
}
}
+ private void resetStates() {
+ mHeadsetRetrySet.clear();
+ mA2dpRetrySet.clear();
+ }
+
private void autoConnect() {
if (mAdapterService.getState() != BluetoothAdapter.STATE_ON) {
errorLog("autoConnect() - BT is not ON. Exiting autoConnect");
return;
}
- if (mAdapterService.isQuietModeEnabled() == false) {
+ if (!mAdapterService.isQuietModeEnabled()) {
debugLog("autoConnect() - Initiate auto connection on BT on...");
// Phone profiles.
autoConnectHeadset();
@@ -262,45 +288,48 @@
}
private void autoConnectHeadset() {
- HeadsetService hsService = mFactory.getHeadsetService();
+ final HeadsetService hsService = mFactory.getHeadsetService();
if (hsService == null) {
- errorLog("autoConnectHeadset() - service is null");
+ errorLog("autoConnectHeadset, service is null");
return;
}
-
- BluetoothDevice bondedDevices[] = mAdapterService.getBondedDevices();
+ final BluetoothDevice bondedDevices[] = mAdapterService.getBondedDevices();
if (bondedDevices == null) {
- errorLog("autoConnectHeadset() - devices are null");
+ errorLog("autoConnectHeadset, bondedDevices are null");
return;
}
-
- debugLog("autoConnectHeadset() - bondedDevices: " + bondedDevices);
for (BluetoothDevice device : bondedDevices) {
- debugLog("autoConnectHeadset() - attempt autoconnect with device " + device);
+ debugLog("autoConnectHeadset, attempt auto-connect with device " + device);
if (hsService.getPriority(device) == BluetoothProfile.PRIORITY_AUTO_CONNECT) {
- debugLog("autoConnectHeadset() - Connecting HFP with " + device.toString());
+ debugLog("autoConnectHeadset, Connecting HFP with " + device);
hsService.connect(device);
}
}
}
private void autoConnectA2dp() {
- A2dpService a2dpSservice = mFactory.getA2dpService();
- BluetoothDevice bondedDevices[] = mAdapterService.getBondedDevices();
- if ((bondedDevices == null) || (a2dpSservice == null)) {
+ final A2dpService a2dpService = mFactory.getA2dpService();
+ if (a2dpService == null) {
+ errorLog("autoConnectA2dp, service is null");
+ return;
+ }
+ final BluetoothDevice bondedDevices[] = mAdapterService.getBondedDevices();
+ if (bondedDevices == null) {
+ errorLog("autoConnectA2dp, bondedDevices are null");
return;
}
for (BluetoothDevice device : bondedDevices) {
- if (a2dpSservice.getPriority(device) == BluetoothProfile.PRIORITY_AUTO_CONNECT) {
- debugLog("autoConnectA2dp() - Connecting A2DP with " + device.toString());
- a2dpSservice.connect(device);
+ debugLog("autoConnectA2dp, attempt auto-connect with device " + device);
+ if (a2dpService.getPriority(device) == BluetoothProfile.PRIORITY_AUTO_CONNECT) {
+ debugLog("autoConnectA2dp, connecting A2DP with " + device);
+ a2dpService.connect(device);
}
}
}
- public void connectOtherProfile(BluetoothDevice device) {
- if ((mHandler.hasMessages(MESSAGE_CONNECT_OTHER_PROFILES) == false)
- && (mAdapterService.isQuietModeEnabled() == false)) {
+ private void connectOtherProfile(BluetoothDevice device) {
+ if ((!mHandler.hasMessages(MESSAGE_CONNECT_OTHER_PROFILES))
+ && (!mAdapterService.isQuietModeEnabled())) {
Message m = mHandler.obtainMessage(MESSAGE_CONNECT_OTHER_PROFILES);
m.obj = device;
mHandler.sendMessageDelayed(m, CONNECT_OTHER_PROFILES_TIMEOUT);
@@ -312,8 +341,9 @@
// connect to the device that initiated the connection. In the event that this function is
// invoked and there are no current bluetooth connections no new profiles will be connected.
private void processConnectOtherProfiles(BluetoothDevice device) {
- debugLog("processConnectOtherProfiles() - device " + device);
+ debugLog("processConnectOtherProfiles, device=" + device);
if (mAdapterService.getState() != BluetoothAdapter.STATE_ON) {
+ warnLog("processConnectOtherProfiles, adapter is not ON " + mAdapterService.getState());
return;
}
HeadsetService hsService = mFactory.getHeadsetService();
@@ -338,29 +368,31 @@
allProfilesEmpty = allProfilesEmpty && panConnDevList.isEmpty();
}
- debugLog("processConnectOtherProfiles() - allProfilesEmpty " + allProfilesEmpty + " device "
- + device);
-
if (allProfilesEmpty) {
- // must have connected then disconnected, don't bother connecting others.
+ // considered as fully disconnected, don't bother connecting others.
+ debugLog("processConnectOtherProfiles, all profiles disconnected for " + device);
+ // reset retry status so that in the next round we can start retrying connections again
+ resetStates();
return;
}
if (hsService != null) {
- if (hsConnDevList.isEmpty()
+ if (hsConnDevList.isEmpty() && !mHeadsetRetrySet.contains(device)
&& (hsService.getPriority(device) >= BluetoothProfile.PRIORITY_ON)
&& (hsService.getConnectionState(device)
== BluetoothProfile.STATE_DISCONNECTED)) {
- debugLog("Retrying connection to HS with device " + device);
+ debugLog("Retrying connection to Headset with device " + device);
+ mHeadsetRetrySet.add(device);
hsService.connect(device);
}
}
if (a2dpService != null) {
- if (a2dpConnDevList.isEmpty()
+ if (a2dpConnDevList.isEmpty() && !mA2dpRetrySet.contains(device)
&& (a2dpService.getPriority(device) >= BluetoothProfile.PRIORITY_ON)
&& (a2dpService.getConnectionState(device)
== BluetoothProfile.STATE_DISCONNECTED)) {
debugLog("Retrying connection to A2DP with device " + device);
+ mA2dpRetrySet.add(device);
a2dpService.connect(device);
}
}
@@ -369,27 +401,20 @@
&& (panService.getPriority(device) >= BluetoothProfile.PRIORITY_ON)
&& (panService.getConnectionState(device)
== BluetoothProfile.STATE_DISCONNECTED)) {
- debugLog("Retrying connection to HF with device " + device);
+ debugLog("Retrying connection to PAN with device " + device);
panService.connect(device);
}
}
}
- private void debugLog(String msg) {
- if (DBG) Log.d(TAG, msg);
- }
-
- private void errorLog(String msg) {
- Log.e(TAG, msg);
- }
-
- void setProfileAutoConnectionPriority(BluetoothDevice device, int profileId) {
+ private void setProfileAutoConnectionPriority(BluetoothDevice device, int profileId) {
switch (profileId) {
case BluetoothProfile.HEADSET:
HeadsetService hsService = mFactory.getHeadsetService();
- List<BluetoothDevice> deviceList = hsService.getConnectedDevices();
- if ((hsService != null) && (BluetoothProfile.PRIORITY_AUTO_CONNECT
- != hsService.getPriority(device))) {
+ if ((hsService != null)
+ && (BluetoothProfile.PRIORITY_AUTO_CONNECT
+ != hsService.getPriority(device))) {
+ List<BluetoothDevice> deviceList = hsService.getConnectedDevices();
adjustOtherHeadsetPriorities(hsService, deviceList);
hsService.setPriority(device, BluetoothProfile.PRIORITY_AUTO_CONNECT);
}
@@ -405,7 +430,7 @@
break;
default:
- Log.w(TAG, "Attempting to set Auto Connect priority on invalid profile");
+ Log.w(TAG, "Tried to set AutoConnect priority on invalid profile " + profileId);
break;
}
}
@@ -429,4 +454,16 @@
}
}
}
+
+ private static void debugLog(String msg) {
+ if (DBG) Log.d(TAG, msg);
+ }
+
+ private static void warnLog(String msg) {
+ Log.w(TAG, msg);
+ }
+
+ private static void errorLog(String msg) {
+ Log.e(TAG, msg);
+ }
}
diff --git a/src/com/android/bluetooth/gatt/ContextMap.java b/src/com/android/bluetooth/gatt/ContextMap.java
index a9965db..13c46a8 100644
--- a/src/com/android/bluetooth/gatt/ContextMap.java
+++ b/src/com/android/bluetooth/gatt/ContextMap.java
@@ -86,6 +86,12 @@
/** Flag to signal that transport is congested */
Boolean isCongested = false;
+ /** Whether the calling app has location permission */
+ boolean hasLocationPermisson;
+
+ /** Whether the calling app has peers mac address permission */
+ boolean hasPeersMacAddressPermission;
+
/** Internal callback info queue, waiting to be send on congestion clear */
private List<CallbackInfo> congestionQueue = new ArrayList<CallbackInfo>();
@@ -151,7 +157,7 @@
/**
* Add an entry to the application context list.
*/
- void add(UUID uuid, WorkSource workSource, C callback, T info, GattService service) {
+ App add(UUID uuid, WorkSource workSource, C callback, T info, GattService service) {
int appUid = Binder.getCallingUid();
String appName = service.getPackageManager().getNameForUid(appUid);
if (appName == null) {
@@ -164,8 +170,10 @@
appScanStats = new AppScanStats(appName, workSource, this, service);
mAppScanStats.put(appUid, appScanStats);
}
- mApps.add(new App(uuid, callback, info, appName, appScanStats));
+ App app = new App(uuid, callback, info, appName, appScanStats);
+ mApps.add(app);
appScanStats.isRegistered = true;
+ return app;
}
}
diff --git a/src/com/android/bluetooth/gatt/GattService.java b/src/com/android/bluetooth/gatt/GattService.java
index 8529134..9a99bcd 100644
--- a/src/com/android/bluetooth/gatt/GattService.java
+++ b/src/com/android/bluetooth/gatt/GattService.java
@@ -60,6 +60,7 @@
import com.android.bluetooth.util.NumberUtils;
import com.android.internal.annotations.VisibleForTesting;
+import java.security.Security;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -846,7 +847,7 @@
if (cbApp.callback != null) {
cbApp.linkToDeath(new ScannerDeathRecipient(scannerId));
} else {
- continuePiStartScan(scannerId, cbApp.info);
+ continuePiStartScan(scannerId, cbApp);
}
} else {
mScannerMap.remove(scannerId);
@@ -1629,26 +1630,36 @@
piInfo.settings = settings;
piInfo.filters = filters;
piInfo.callingPackage = callingPackage;
- mScannerMap.add(uuid, null, null, piInfo, this);
+ ScannerMap.App app = mScannerMap.add(uuid, null, null, piInfo, this);
+ try {
+ app.hasLocationPermisson =
+ Utils.checkCallerHasLocationPermission(this, mAppOps, callingPackage);
+ } catch (SecurityException se) {
+ // No need to throw here. Just mark as not granted.
+ app.hasLocationPermisson = false;
+ }
+ try {
+ app.hasPeersMacAddressPermission = Utils.checkCallerHasPeersMacAddressPermission(this);
+ } catch (SecurityException se) {
+ // No need to throw here. Just mark as not granted.
+ app.hasPeersMacAddressPermission = false;
+ }
mScanManager.registerScanner(uuid);
}
- void continuePiStartScan(int scannerId, PendingIntentInfo piInfo) {
+ void continuePiStartScan(int scannerId, ScannerMap.App app) {
+ final PendingIntentInfo piInfo = app.info;
final ScanClient scanClient =
new ScanClient(scannerId, piInfo.settings, piInfo.filters, null);
- scanClient.hasLocationPermission =
- true; // Utils.checkCallerHasLocationPermission(this, mAppOps,
- // piInfo.callingPackage);
- scanClient.hasPeersMacAddressPermission =
- true; // Utils.checkCallerHasPeersMacAddressPermission(
- // this);
+ scanClient.hasLocationPermission = app.hasLocationPermisson;
+ scanClient.hasPeersMacAddressPermission = app.hasPeersMacAddressPermission;
scanClient.legacyForegroundApp = Utils.isLegacyForegroundApp(this, piInfo.callingPackage);
- AppScanStats app = mScannerMap.getAppScanStatsById(scannerId);
- if (app != null) {
- scanClient.stats = app;
+ AppScanStats scanStats = mScannerMap.getAppScanStatsById(scannerId);
+ if (scanStats != null) {
+ scanClient.stats = scanStats;
boolean isFilteredScan = (piInfo.filters != null) && !piInfo.filters.isEmpty();
- app.recordScanStart(piInfo.settings, isFilteredScan, scannerId);
+ scanStats.recordScanStart(piInfo.settings, isFilteredScan, scannerId);
}
mScanManager.startScan(scanClient);
diff --git a/src/com/android/bluetooth/hfp/HeadsetStateMachine.java b/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
index bbac49e..e865f66 100644
--- a/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
+++ b/src/com/android/bluetooth/hfp/HeadsetStateMachine.java
@@ -435,6 +435,9 @@
+ device.getBondState() + ", device=" + device);
// reject the connection and stay in Disconnected state itself
disconnectHfpNative(getByteAddress(device));
+ // the other profile connection should be initiated
+ broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED,
+ BluetoothProfile.STATE_DISCONNECTED);
}
break;
case HeadsetHalConstants.CONNECTION_STATE_DISCONNECTING:
@@ -518,6 +521,60 @@
case EVENT_TYPE_BIND:
processAtBind(event.valueString, event.device);
break;
+ // Unexpected AT commands, we only handle them for comparability reasons
+ case EVENT_TYPE_VR_STATE_CHANGED:
+ Log.w(TAG,
+ "Pending: Unexpected VR event, device=" + event.device
+ + ", state=" + event.valueInt);
+ processVrEvent(event.valueInt, event.device);
+ break;
+ case EVENT_TYPE_DIAL_CALL:
+ Log.w(TAG, "Pending: Unexpected dial event, device=" + event.device);
+ processDialCall(event.valueString, event.device);
+ break;
+ case EVENT_TYPE_SUBSCRIBER_NUMBER_REQUEST:
+ Log.w(TAG,
+ "Pending: Unexpected subscriber number event for" + event.device
+ + ", state=" + event.valueInt);
+ processSubscriberNumberRequest(event.device);
+ break;
+ case EVENT_TYPE_AT_COPS:
+ Log.w(TAG, "Pending: Unexpected COPS event for " + event.device);
+ processAtCops(event.device);
+ break;
+ case EVENT_TYPE_AT_CLCC:
+ Log.w(TAG, "Pending: Unexpected CLCC event for" + event.device);
+ processAtClcc(event.device);
+ break;
+ case EVENT_TYPE_UNKNOWN_AT:
+ Log.w(TAG,
+ "Pending: Unexpected unknown AT event for" + event.device
+ + ", cmd=" + event.valueString);
+ processUnknownAt(event.valueString, event.device);
+ break;
+ case EVENT_TYPE_KEY_PRESSED:
+ Log.w(TAG, "Pending: Unexpected key-press event for " + event.device);
+ processKeyPressed(event.device);
+ break;
+ case EVENT_TYPE_BIEV:
+ Log.w(TAG,
+ "Pending: Unexpected BIEV event for " + event.device
+ + ", indId=" + event.valueInt
+ + ", indVal=" + event.valueInt2);
+ processAtBiev(event.valueInt, event.valueInt2, event.device);
+ break;
+ case EVENT_TYPE_VOLUME_CHANGED:
+ Log.w(TAG, "Pending: Unexpected volume event for " + event.device);
+ processVolumeEvent(event.valueInt, event.valueInt2, event.device);
+ break;
+ case EVENT_TYPE_ANSWER_CALL:
+ Log.w(TAG, "Pending: Unexpected answer event for " + event.device);
+ processAnswerCall(event.device);
+ break;
+ case EVENT_TYPE_HANGUP_CALL:
+ Log.w(TAG, "Pending: Unexpected hangup event for " + event.device);
+ processHangupCall(event.device);
+ break;
default:
Log.e(TAG, "Pending: Unexpected event: " + event.type);
break;
@@ -753,37 +810,28 @@
if (mConnectedDevicesList.contains(device)) {
Log.w(TAG, "Connected: CONNECT, device " + device + " is connected");
break;
- } else {
- broadcastConnectionState(mCurrentDevice,
- BluetoothProfile.STATE_DISCONNECTING,
- BluetoothProfile.STATE_CONNECTED);
}
if (mConnectedDevicesList.size() >= max_hf_connections) {
- BluetoothDevice DisconnectConnectedDevice = null;
- IState CurrentAudioState = getCurrentState();
- Log.d(TAG, "Reach to max size, disconnect one of them first");
- /* TODO: Disconnect based on CoD */
- DisconnectConnectedDevice = mConnectedDevicesList.get(0);
-
+ BluetoothDevice disconnectDevice = mConnectedDevicesList.get(0);
+ Log.d(TAG, "Connected: Reach to max size, disconnect " + disconnectDevice);
broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTING,
BluetoothProfile.STATE_DISCONNECTED);
-
- if (!disconnectHfpNative(getByteAddress(DisconnectConnectedDevice))) {
+ if (disconnectHfpNative(getByteAddress(disconnectDevice))) {
+ broadcastConnectionState(disconnectDevice,
+ BluetoothProfile.STATE_DISCONNECTING,
+ BluetoothProfile.STATE_CONNECTED);
+ } else {
+ Log.w(TAG, "Connected: failed to disconnect " + disconnectDevice);
broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED,
BluetoothProfile.STATE_CONNECTING);
break;
- } else {
- broadcastConnectionState(DisconnectConnectedDevice,
- BluetoothProfile.STATE_DISCONNECTING,
- BluetoothProfile.STATE_CONNECTED);
}
-
synchronized (HeadsetStateMachine.this) {
mTargetDevice = device;
if (max_hf_connections == 1) {
transitionTo(mPending);
} else {
- mMultiDisconnectDevice = DisconnectConnectedDevice;
+ mMultiDisconnectDevice = disconnectDevice;
transitionTo(mMultiHFPending);
}
}
@@ -924,11 +972,9 @@
processVrEvent(event.valueInt, event.device);
break;
case EVENT_TYPE_ANSWER_CALL:
- // TODO(BT) could answer call happen on Connected state?
processAnswerCall(event.device);
break;
case EVENT_TYPE_HANGUP_CALL:
- // TODO(BT) could hangup call happen on Connected state?
processHangupCall(event.device);
break;
case EVENT_TYPE_VOLUME_CHANGED:
@@ -1072,9 +1118,9 @@
mAudioState = BluetoothHeadset.STATE_AUDIO_CONNECTED;
setAudioParameters(device); /*Set proper Audio Paramters.*/
mAudioManager.setBluetoothScoOn(true);
+ mActiveScoDevice = device;
broadcastAudioState(device, BluetoothHeadset.STATE_AUDIO_CONNECTED,
BluetoothHeadset.STATE_AUDIO_CONNECTING);
- mActiveScoDevice = device;
transitionTo(mAudioOn);
break;
case HeadsetHalConstants.AUDIO_STATE_CONNECTING:
@@ -1137,42 +1183,39 @@
deferMessage(obtainMessage(DISCONNECT, mCurrentDevice));
deferMessage(obtainMessage(CONNECT, device));
if (disconnectAudioNative(getByteAddress(mCurrentDevice))) {
- Log.d(TAG, "Disconnecting SCO audio for device=" + mCurrentDevice);
+ Log.d(TAG, "AudioOn: disconnecting SCO, device=" + mCurrentDevice);
} else {
- Log.e(TAG, "disconnectAudioNative failed");
+ Log.e(TAG, "AudioOn: disconnect SCO failed, device=" + mCurrentDevice);
}
break;
}
if (mConnectedDevicesList.size() >= max_hf_connections) {
- BluetoothDevice DisconnectConnectedDevice = null;
- IState CurrentAudioState = getCurrentState();
- Log.d(TAG, "Reach to max size, disconnect "
- + "one of them first");
- DisconnectConnectedDevice = mConnectedDevicesList.get(0);
+ BluetoothDevice disconnectDevice = mConnectedDevicesList.get(0);
+ Log.d(TAG, "AudioOn: Reach to max size, disconnect " + disconnectDevice);
- if (mActiveScoDevice.equals(DisconnectConnectedDevice)) {
- DisconnectConnectedDevice = mConnectedDevicesList.get(1);
+ if (mActiveScoDevice.equals(disconnectDevice)) {
+ disconnectDevice = mConnectedDevicesList.get(1);
}
broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTING,
BluetoothProfile.STATE_DISCONNECTED);
- if (!disconnectHfpNative(getByteAddress(DisconnectConnectedDevice))) {
+ if (disconnectHfpNative(getByteAddress(disconnectDevice))) {
+ broadcastConnectionState(disconnectDevice,
+ BluetoothProfile.STATE_DISCONNECTING,
+ BluetoothProfile.STATE_CONNECTED);
+ } else {
+ Log.e(TAG, "AudioOn: Failed to disconnect " + disconnectDevice);
broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED,
BluetoothProfile.STATE_CONNECTING);
break;
- } else {
- broadcastConnectionState(DisconnectConnectedDevice,
- BluetoothProfile.STATE_DISCONNECTING,
- BluetoothProfile.STATE_CONNECTED);
}
synchronized (HeadsetStateMachine.this) {
mTargetDevice = device;
- mMultiDisconnectDevice = DisconnectConnectedDevice;
+ mMultiDisconnectDevice = disconnectDevice;
transitionTo(mMultiHFPending);
- DisconnectConnectedDevice = null;
}
} else if (mConnectedDevicesList.size() < max_hf_connections) {
broadcastConnectionState(device, BluetoothProfile.STATE_CONNECTING,
@@ -2049,7 +2092,7 @@
sco disconnect issued in AudioOn state. This was causing a mismatch in the
Incall screen UI. */
- if (getCurrentState() == mAudioOn && mCurrentDevice.equals(device)
+ if (mActiveScoDevice != null && mActiveScoDevice.equals(device)
&& mAudioState != BluetoothHeadset.STATE_AUDIO_DISCONNECTED) {
return true;
}
diff --git a/src/com/android/bluetooth/mapclient/MnsService.java b/src/com/android/bluetooth/mapclient/MnsService.java
index 7b3419e..1078cf1 100644
--- a/src/com/android/bluetooth/mapclient/MnsService.java
+++ b/src/com/android/bluetooth/mapclient/MnsService.java
@@ -50,26 +50,49 @@
static private MapClientService mContext;
private volatile boolean mShutdown = false; // Used to interrupt socket accept thread
+ private int mSdpHandle = -1;
MnsService(MapClientService context) {
if (VDBG) Log.v(TAG, "MnsService()");
mContext = context;
mAcceptThread = new SocketAcceptor();
mServerSockets = ObexServerSockets.create(mAcceptThread);
- SdpManager.getDefaultManager().createMapMnsRecord(
- "MAP Message Notification Service", mServerSockets.getRfcommChannel(), -1,
- MNS_VERSION, MNS_FEATURE_BITS);
+ SdpManager sdpManager = SdpManager.getDefaultManager();
+ if (sdpManager == null) {
+ Log.e(TAG, "SdpManager is null");
+ return;
+ }
+ mSdpHandle = sdpManager.createMapMnsRecord("MAP Message Notification Service",
+ mServerSockets.getRfcommChannel(), -1, MNS_VERSION, MNS_FEATURE_BITS);
}
void stop() {
if (VDBG) Log.v(TAG, "stop()");
mShutdown = true;
+ cleanUpSdpRecord();
if (mServerSockets != null) {
mServerSockets.shutdown(false);
mServerSockets = null;
}
}
+ private void cleanUpSdpRecord() {
+ if (mSdpHandle < 0) {
+ Log.e(TAG, "cleanUpSdpRecord, SDP record never created");
+ return;
+ }
+ int sdpHandle = mSdpHandle;
+ mSdpHandle = -1;
+ SdpManager sdpManager = SdpManager.getDefaultManager();
+ if (sdpManager == null) {
+ Log.e(TAG, "cleanUpSdpRecord failed, sdpManager is null, sdpHandle=" + sdpHandle);
+ return;
+ }
+ Log.i(TAG, "cleanUpSdpRecord, mSdpHandle=" + sdpHandle);
+ if (!sdpManager.removeSdpRecord(sdpHandle)) {
+ Log.e(TAG, "cleanUpSdpRecord, removeSdpRecord failed, sdpHandle=" + sdpHandle);
+ }
+ }
private class SocketAcceptor implements IObexConnectionHandler {
diff --git a/src/com/android/bluetooth/opp/BluetoothOppService.java b/src/com/android/bluetooth/opp/BluetoothOppService.java
index b68936a..7f94820 100644
--- a/src/com/android/bluetooth/opp/BluetoothOppService.java
+++ b/src/com/android/bluetooth/opp/BluetoothOppService.java
@@ -226,14 +226,6 @@
public void handleMessage(Message msg) {
switch (msg.what) {
case STOP_LISTENER:
- if (mAdapter != null && mOppSdpHandle >= 0
- && SdpManager.getDefaultManager() != null) {
- if (D) Log.d(TAG, "Removing SDP record mOppSdpHandle :" + mOppSdpHandle);
- boolean status =
- SdpManager.getDefaultManager().removeSdpRecord(mOppSdpHandle);
- Log.d(TAG, "RemoveSDPrecord returns " + status);
- mOppSdpHandle = -1;
- }
stopListeners();
mListenStarted = false;
//Stop Active INBOUND Transfer
@@ -365,8 +357,10 @@
+ " mServerSocket:" + mServerSocket);
return;
}
- sdpManager.createOppOpsRecord("OBEX Object Push", mServerSocket.getRfcommChannel(),
- mServerSocket.getL2capPsm(), 0x0102, SUPPORTED_OPP_FORMAT);
+ mOppSdpHandle =
+ sdpManager.createOppOpsRecord("OBEX Object Push", mServerSocket.getRfcommChannel(),
+ mServerSocket.getL2capPsm(), 0x0102, SUPPORTED_OPP_FORMAT);
+ if (D) Log.d(TAG, "mOppSdpHandle :" + mOppSdpHandle);
}
@Override
@@ -1063,6 +1057,12 @@
}
private void stopListeners() {
+ if (mAdapter != null && mOppSdpHandle >= 0 && SdpManager.getDefaultManager() != null) {
+ if (D) Log.d(TAG, "Removing SDP record mOppSdpHandle :" + mOppSdpHandle);
+ boolean status = SdpManager.getDefaultManager().removeSdpRecord(mOppSdpHandle);
+ Log.d(TAG, "RemoveSDPrecord returns " + status);
+ mOppSdpHandle = -1;
+ }
if (mServerSocket != null) {
mServerSocket.shutdown(false);
mServerSocket = null;
diff --git a/src/com/android/bluetooth/opp/BluetoothOppTransferHistory.java b/src/com/android/bluetooth/opp/BluetoothOppTransferHistory.java
index 21fad6b..fd47318 100644
--- a/src/com/android/bluetooth/opp/BluetoothOppTransferHistory.java
+++ b/src/com/android/bluetooth/opp/BluetoothOppTransferHistory.java
@@ -39,6 +39,7 @@
import android.bluetooth.BluetoothAdapter;
import android.content.DialogInterface;
import android.content.Intent;
+import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
@@ -118,11 +119,12 @@
final String sortOrder = BluetoothShare.TIMESTAMP + " DESC";
- mTransferCursor = managedQuery(BluetoothShare.CONTENT_URI, new String[] {
- "_id", BluetoothShare.FILENAME_HINT, BluetoothShare.STATUS,
- BluetoothShare.TOTAL_BYTES, BluetoothShare._DATA, BluetoothShare.TIMESTAMP,
- BluetoothShare.VISIBILITY, BluetoothShare.DESTINATION, BluetoothShare.DIRECTION
- }, selection, sortOrder);
+ mTransferCursor = getContentResolver().query(BluetoothShare.CONTENT_URI,
+ new String[] {"_id", BluetoothShare.FILENAME_HINT, BluetoothShare.STATUS,
+ BluetoothShare.TOTAL_BYTES, BluetoothShare._DATA, BluetoothShare.TIMESTAMP,
+ BluetoothShare.VISIBILITY, BluetoothShare.DESTINATION,
+ BluetoothShare.DIRECTION},
+ selection, null, sortOrder);
// only attach everything to the listbox if we can access
// the transfer database. Otherwise, just show it empty
@@ -193,6 +195,14 @@
}
@Override
+ protected void onDestroy() {
+ if (mTransferCursor != null) {
+ mTransferCursor.close();
+ }
+ super.onDestroy();
+ }
+
+ @Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
if (mTransferCursor != null) {
mContextMenu = true;
diff --git a/src/com/android/bluetooth/pan/PanService.java b/src/com/android/bluetooth/pan/PanService.java
index 391ea3a..a978693 100755
--- a/src/com/android/bluetooth/pan/PanService.java
+++ b/src/com/android/bluetooth/pan/PanService.java
@@ -472,6 +472,7 @@
// will fail until the caller explicitly calls BluetoothPan#disconnect.
if (prevState == BluetoothProfile.STATE_DISCONNECTED && state == BluetoothProfile.STATE_DISCONNECTING) {
Log.d(TAG, "Ignoring state change from " + prevState + " to " + state);
+ mPanDevices.remove(device);
return;
}
diff --git a/src/com/android/bluetooth/pbap/BluetoothPbapService.java b/src/com/android/bluetooth/pbap/BluetoothPbapService.java
index 7743d9b..7e1164e 100644
--- a/src/com/android/bluetooth/pbap/BluetoothPbapService.java
+++ b/src/com/android/bluetooth/pbap/BluetoothPbapService.java
@@ -437,17 +437,43 @@
mWakeLock = null;
}
+ // Step 1: clean up active server session
if (mServerSession != null) {
mServerSession.close();
mServerSession = null;
}
-
+ // Step 2: clean up existing connection socket
closeConnectionSocket();
+ // Step 3: clean up SDP record
+ cleanUpSdpRecord();
+ // Step 4: clean up existing server socket(s)
closeServerSocket();
+ if (mServerSockets != null) {
+ mServerSockets.shutdown(false);
+ mServerSockets = null;
+ }
if (mSessionStatusHandler != null) mSessionStatusHandler.removeCallbacksAndMessages(null);
if (VERBOSE) Log.v(TAG, "Pbap Service closeService out");
}
+ private void cleanUpSdpRecord() {
+ if (mSdpHandle < 0) {
+ if (VERBOSE) Log.v(TAG, "cleanUpSdpRecord, SDP record never created");
+ return;
+ }
+ int sdpHandle = mSdpHandle;
+ mSdpHandle = -1;
+ SdpManager sdpManager = SdpManager.getDefaultManager();
+ if (sdpManager == null) {
+ Log.e(TAG, "cleanUpSdpRecord failed, sdpManager is null, sdpHandle=" + sdpHandle);
+ return;
+ }
+ Log.i(TAG, "cleanUpSdpRecord, mSdpHandle=" + sdpHandle);
+ if (!sdpManager.removeSdpRecord(sdpHandle)) {
+ Log.e(TAG, "cleanUpSdpRecord, removeSdpRecord failed, sdpHandle=" + sdpHandle);
+ }
+ }
+
private final void startObexServerSession() throws IOException {
if (VERBOSE) Log.v(TAG, "Pbap Service startObexServerSession");
@@ -935,6 +961,10 @@
}
}
+ /**
+ * Start server side socket listeners. Caller should make sure that adapter is in a ready state
+ * and SDP record is cleaned up. Otherwise, this method will fail.
+ */
synchronized private void startSocketListeners() {
if (DEBUG) Log.d(TAG, "startsocketListener");
if (mServerSession != null) {
@@ -952,17 +982,10 @@
Log.e(TAG, "Failed to start the listeners");
return;
}
- SdpManager sdpManager = SdpManager.getDefaultManager();
- if (sdpManager == null) {
- Log.e(TAG, "Failed to start the listeners sdp null ");
+ if (mSdpHandle >= 0) {
+ Log.e(TAG, "SDP handle was not cleaned up, mSdpHandle=" + mSdpHandle);
return;
}
- if (mAdapter != null && mSdpHandle >= 0) {
- Log.d(TAG, "Removing SDP record for PBAP with SDP handle:" + mSdpHandle);
- boolean status = sdpManager.removeSdpRecord(mSdpHandle);
- Log.d(TAG, "RemoveSDPrecord returns " + status);
- mSdpHandle = -1;
- }
mSdpHandle = SdpManager.getDefaultManager().createPbapPseRecord(
"OBEX Phonebook Access Server", mServerSockets.getRfcommChannel(),
mServerSockets.getL2capPsm(), SDP_PBAP_SERVER_VERSION,
@@ -1053,8 +1076,13 @@
*/
@Override
public synchronized void onAcceptFailed() {
+ // Clean up SDP record first
+ cleanUpSdpRecord();
// Force socket listener to restart
- mServerSockets = null;
+ if (mServerSockets != null) {
+ mServerSockets.shutdown(false);
+ mServerSockets = null;
+ }
if (!mInterrupted && mAdapter != null && mAdapter.isEnabled()) {
startSocketListeners();
}
diff --git a/src/com/android/bluetooth/sap/SapServer.java b/src/com/android/bluetooth/sap/SapServer.java
index a66fc46..8f8da2d 100644
--- a/src/com/android/bluetooth/sap/SapServer.java
+++ b/src/com/android/bluetooth/sap/SapServer.java
@@ -115,13 +115,15 @@
IntentFilter filter = new IntentFilter();
filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
filter.addAction(SAP_DISCONNECT_ACTION);
+ mIntentReceiver = new SapServerBroadcastReceiver();
mContext.registerReceiver(mIntentReceiver, filter);
}
/**
* This handles the response from RIL.
*/
- BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+ private BroadcastReceiver mIntentReceiver;
+ private class SapServerBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) {
@@ -148,8 +150,7 @@
if(disconnectType == SapMessage.DISC_RFCOMM) {
// At timeout we need to close the RFCOMM socket to complete shutdown
shutdown();
- } else if( mState != SAP_STATE.DISCONNECTED
- && mState != SAP_STATE.DISCONNECTING ) {
+ } else if (mState != SAP_STATE.DISCONNECTED && mState != SAP_STATE.DISCONNECTING) {
// The user pressed disconnect - initiate disconnect sequence.
sendDisconnectInd(disconnectType);
}
@@ -157,7 +158,7 @@
Log.w(TAG, "RIL-BT received unexpected Intent: " + intent.getAction());
}
}
- };
+ }
/**
* Set RIL driver in test mode - only possible if SapMessage is build with TEST == true