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