Merge branch 'dev/11/fp3/security-aosp-rvc-release' into int/11/fp3

* dev/11/fp3/security-aosp-rvc-release:
  Fix URI check in BluetoothOppUtility.java

Change-Id: I0126c5cc1e8fa6e5fe8867a96ce091d6ab0795a1
diff --git a/jni/com_android_bluetooth_gatt.cpp b/jni/com_android_bluetooth_gatt.cpp
index 64db277..5788819 100644
--- a/jni/com_android_bluetooth_gatt.cpp
+++ b/jni/com_android_bluetooth_gatt.cpp
@@ -183,7 +183,7 @@
 static jmethodID method_onSyncLost;
 static jmethodID method_onSyncReport;
 static jmethodID method_onSyncStarted;
-
+static jmethodID method_onSyncTransferedCallback;
 /**
  * Static variables
  */
@@ -942,10 +942,11 @@
 
 static void gattClientRegisterAppNative(JNIEnv* env, jobject object,
                                         jlong app_uuid_lsb,
-                                        jlong app_uuid_msb) {
+                                        jlong app_uuid_msb,
+                                        jboolean eatt_support) {
   if (!sGattIf) return;
   Uuid uuid = from_java_uuid(app_uuid_msb, app_uuid_lsb);
-  sGattIf->client->register_client(uuid);
+  sGattIf->client->register_client(uuid, eatt_support);
 }
 
 static void gattClientUnregisterAppNative(JNIEnv* env, jobject object,
@@ -1168,8 +1169,9 @@
                                         jint client_if, jint scan_interval_unit,
                                         jint scan_window_unit) {
   if (!sGattIf) return;
+  // TODO(b/140404592): Fix this call to SetScanParameters().
   sGattIf->scanner->SetScanParameters(
-      scan_interval_unit, scan_window_unit,
+      0, {0,0}, {0,0},
       base::Bind(&set_scan_params_cmpl_cb, client_if));
 }
 
@@ -1463,10 +1465,11 @@
  */
 static void gattServerRegisterAppNative(JNIEnv* env, jobject object,
                                         jlong app_uuid_lsb,
-                                        jlong app_uuid_msb) {
+                                        jlong app_uuid_msb,
+                                        jboolean eatt_support) {
   if (!sGattIf) return;
   Uuid uuid = from_java_uuid(app_uuid_msb, app_uuid_lsb);
-  sGattIf->server->register_server(uuid);
+  sGattIf->server->register_server(uuid, eatt_support);
 }
 
 static void gattServerUnregisterAppNative(JNIEnv* env, jobject object,
@@ -1969,6 +1972,8 @@
       env->GetMethodID(clazz, "onSyncStarted", "(IIIILjava/lang/String;III)V");
   method_onSyncReport = env->GetMethodID(clazz, "onSyncReport", "(IIII[B)V");
   method_onSyncLost = env->GetMethodID(clazz, "onSyncLost", "(I)V");
+  method_onSyncTransferedCallback =
+      env->GetMethodID(clazz, "onSyncTransferedCallback", "(IILjava/lang/String;)V");
 }
 
 static void periodicScanInitializeNative(JNIEnv* env, jobject object) {
@@ -1993,9 +1998,15 @@
                           uint8_t phy, uint16_t interval) {
   CallbackEnv sCallbackEnv(__func__);
   if (!sCallbackEnv.valid()) return;
+  if (!mPeriodicScanCallbacksObj) {
+    ALOGE("mPeriodicScanCallbacksObj is NULL. Return.");
+    return;
+  }
+  ScopedLocalRef<jstring> addr(sCallbackEnv.get(),
+                                 bdaddr2newjstr(sCallbackEnv.get(), &address));
 
   sCallbackEnv->CallVoidMethod(mPeriodicScanCallbacksObj, method_onSyncStarted,
-                               reg_id, sync_handle, sid, address_type, address,
+                               reg_id, sync_handle, sid, address_type, addr.get(),
                                phy, interval, status);
 }
 
@@ -2026,19 +2037,50 @@
                             jstring address, jint skip, jint timeout,
                             jint reg_id) {
   if (!sGattIf) return;
-
   sGattIf->scanner->StartSync(sid, str2addr(env, address), skip, timeout,
                               base::Bind(&onSyncStarted, reg_id),
                               base::Bind(&onSyncReport),
                               base::Bind(&onSyncLost));
 }
 
-static void stopSyncNative(int sync_handle) {
+static void stopSyncNative(JNIEnv* env, jobject object, jint sync_handle) {
   if (!sGattIf) return;
-
   sGattIf->scanner->StopSync(sync_handle);
 }
 
+static void cancelSyncNative(JNIEnv* env, jobject object, jint sid, jstring address) {
+  if (!sGattIf) return;
+  sGattIf->scanner->CancelCreateSync(sid, str2addr(env, address));
+}
+static void onSyncTransferedCb(int pa_source,uint8_t status, RawAddress address) {
+  CallbackEnv sCallbackEnv(__func__);
+  if (!sCallbackEnv.valid()) return;
+  if (!mPeriodicScanCallbacksObj) {
+    ALOGE("mPeriodicScanCallbacksObj is NULL. Return.");
+    return;
+  }
+  ScopedLocalRef<jstring> addr(sCallbackEnv.get(),
+                                 bdaddr2newjstr(sCallbackEnv.get(), &address));
+
+  sCallbackEnv->CallVoidMethod(mPeriodicScanCallbacksObj, method_onSyncTransferedCallback, pa_source,
+                              status, addr.get());
+
+}
+
+static void syncTransferNative(JNIEnv* env, jobject object, jint pa_source,
+                                       jstring addr,jint service_data, jint sync_handle) {
+  if (!sGattIf) return;
+  sGattIf->scanner->TransferSync(str2addr(env,addr), service_data, sync_handle,
+                                 base::Bind(&onSyncTransferedCb, pa_source));
+}
+
+static void TransferSetInfoNative(JNIEnv* env, jobject object, jint pa_source,
+                                       jstring addr,jint service_data, jint adv_handle) {
+  if (!sGattIf) return;
+  sGattIf->scanner->TransferSetInfo(str2addr(env,addr), service_data, adv_handle,
+                                 base::Bind(&onSyncTransferedCb, pa_source));
+}
+
 static void gattTestNative(JNIEnv* env, jobject object, jint command,
                            jlong uuid1_lsb, jlong uuid1_msb, jstring bda1,
                            jint p1, jint p2, jint p3, jint p4, jint p5) {
@@ -2097,6 +2139,11 @@
     {"cleanupNative", "()V", (void*)periodicScanCleanupNative},
     {"startSyncNative", "(ILjava/lang/String;III)V", (void*)startSyncNative},
     {"stopSyncNative", "(I)V", (void*)stopSyncNative},
+    {"cancelSyncNative", "(ILjava/lang/String;)V", (void*)cancelSyncNative},
+    {"syncTransferNative", "(ILjava/lang/String;II)V",
+      (void*)syncTransferNative},
+    {"TransferSetInfoNative", "(ILjava/lang/String;II)V",
+      (void*)TransferSetInfoNative},
 };
 
 // JNI functions defined in ScanManager class.
@@ -2139,7 +2186,7 @@
     {"cleanupNative", "()V", (void*)cleanupNative},
     {"gattClientGetDeviceTypeNative", "(Ljava/lang/String;)I",
      (void*)gattClientGetDeviceTypeNative},
-    {"gattClientRegisterAppNative", "(JJ)V",
+    {"gattClientRegisterAppNative", "(JJZ)V",
      (void*)gattClientRegisterAppNative},
     {"gattClientUnregisterAppNative", "(I)V",
      (void*)gattClientUnregisterAppNative},
@@ -2178,7 +2225,7 @@
      (void*)gattClientConfigureMTUNative},
     {"gattConnectionParameterUpdateNative", "(ILjava/lang/String;IIIIII)V",
      (void*)gattConnectionParameterUpdateNative},
-    {"gattServerRegisterAppNative", "(JJ)V",
+    {"gattServerRegisterAppNative", "(JJZ)V",
      (void*)gattServerRegisterAppNative},
     {"gattServerUnregisterAppNative", "(I)V",
      (void*)gattServerUnregisterAppNative},
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 8c26a6b..72492dd 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/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-de/strings.xml b/res/values-de/strings.xml
index 0b09429..c9c436d 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -18,8 +18,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="permlab_bluetoothShareManager" msgid="311492132450338925">"Auf Download-Manager zugreifen"</string>
     <string name="permdesc_bluetoothShareManager" msgid="8930572979123190223">"Ermöglicht der App, auf den Bluetooth-Weiterleitungs-Manager zuzugreifen und diesen für die Übertragung von Dateien zu verwenden."</string>
-    <string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"Bluetooth-Gerät für Zugriff zur weißen Liste hinzufügen"</string>
-    <string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"Ermöglicht der App, ein Bluetooth-Gerät vorübergehend zur weißen Liste hinzuzufügen, sodass es ohne Bestätigung des Nutzers Dateien an dieses Gerät senden kann"</string>
+    <string name="permlab_bluetoothWhitelist" msgid="7091552898592306386">"Bluetooth-Gerät für Zugriff zur Zulassungsliste hinzufügen"</string>
+    <string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"Ermöglicht der App, ein Bluetooth-Gerät vorübergehend zur Zulassungsliste hinzuzufügen, sodass es ohne Bestätigung des Nutzers Dateien an dieses Gerät senden kann"</string>
     <string name="bt_share_picker_label" msgid="6268100924487046932">"Bluetooth"</string>
     <string name="unknown_device" msgid="9221903979877041009">"Unbekanntes Gerät"</string>
     <string name="unknownNumber" msgid="4994750948072751566">"Unbekannter Anrufer"</string>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index 12298d5..bf4d6b2 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -121,17 +121,17 @@
     <string name="transfer_menu_open" msgid="3368984869083107200">"Open"</string>
     <string name="transfer_menu_clear" msgid="5854038118831427492">"Clear from list"</string>
     <string name="transfer_clear_dlg_title" msgid="2953444575556460386">"Clear"</string>
-    <string name="bluetooth_a2dp_sink_queue_name" msgid="6864149958708669766">"Now Playing"</string>
+    <string name="bluetooth_a2dp_sink_queue_name" msgid="6864149958708669766">"Now playing"</string>
     <string name="bluetooth_map_settings_save" msgid="7635491847388074606">"Save"</string>
     <string name="bluetooth_map_settings_cancel" msgid="9205350798049865699">"Cancel"</string>
     <string name="bluetooth_map_settings_intro" msgid="6482369468223987562">"Select the accounts that you want to share through Bluetooth. You still have to accept any access to the accounts when connecting."</string>
     <string name="bluetooth_map_settings_count" msgid="4557473074937024833">"Slots left:"</string>
-    <string name="bluetooth_map_settings_app_icon" msgid="7105805610929114707">"Application Icon"</string>
-    <string name="bluetooth_map_settings_title" msgid="7420332483392851321">"Bluetooth Message Sharing Settings"</string>
+    <string name="bluetooth_map_settings_app_icon" msgid="7105805610929114707">"Application icon"</string>
+    <string name="bluetooth_map_settings_title" msgid="7420332483392851321">"Bluetooth message sharing settings"</string>
     <string name="bluetooth_map_settings_no_account_slots_left" msgid="1796029082612965251">"Cannot select account. 0 slots left"</string>
     <string name="bluetooth_connected" msgid="6718623220072656906">"Bluetooth audio connected"</string>
     <string name="bluetooth_disconnected" msgid="3318303728981478873">"Bluetooth audio disconnected"</string>
-    <string name="a2dp_sink_mbs_label" msgid="7566075853395412558">"Bluetooth Audio"</string>
+    <string name="a2dp_sink_mbs_label" msgid="7566075853395412558">"Bluetooth audio"</string>
     <string name="bluetooth_opp_file_limit_exceeded" msgid="8894450394309084519">"Files bigger than 4 GB cannot be transferred"</string>
     <string name="bluetooth_connect_action" msgid="4009848433321657090">"Connect to Bluetooth"</string>
 </resources>
diff --git a/res/values-en-rAU/strings_pbap.xml b/res/values-en-rAU/strings_pbap.xml
index c80ccb6..fd4e512 100644
--- a/res/values-en-rAU/strings_pbap.xml
+++ b/res/values-en-rAU/strings_pbap.xml
@@ -4,9 +4,9 @@
     <string name="pbap_session_key_dialog_title" msgid="3580996574333882561">"Type session key for %1$s"</string>
     <string name="pbap_session_key_dialog_header" msgid="2772472422782758981">"Bluetooth session key required"</string>
     <string name="pbap_acceptance_timeout_message" msgid="1107401415099814293">"There was time out to accept connection with %1$s"</string>
-    <string name="pbap_authentication_timeout_message" msgid="4166979525521902687">"There was time out to input session key with %1$s"</string>
+    <string name="pbap_authentication_timeout_message" msgid="4166979525521902687">"There was a timeout to input session key with %1$s"</string>
     <string name="auth_notif_ticker" msgid="1575825798053163744">"Obex authentication request"</string>
-    <string name="auth_notif_title" msgid="7599854855681573258">"Session Key"</string>
+    <string name="auth_notif_title" msgid="7599854855681573258">"Session key"</string>
     <string name="auth_notif_message" msgid="6667218116427605038">"Type session key for %1$s"</string>
     <string name="defaultname" msgid="4821590500649090078">"Car Kit"</string>
     <string name="unknownName" msgid="2841414754740600042">"Unknown name"</string>
diff --git a/res/values-en-rAU/strings_sap.xml b/res/values-en-rAU/strings_sap.xml
index c79b034..2ebae8c 100644
--- a/res/values-en-rAU/strings_sap.xml
+++ b/res/values-en-rAU/strings_sap.xml
@@ -2,7 +2,7 @@
 <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">"Bluetooth SIM access"</string>
-    <string name="bluetooth_sap_notif_ticker" msgid="6807778527893726699">"Bluetooth SIM Access"</string>
+    <string name="bluetooth_sap_notif_ticker" msgid="6807778527893726699">"Bluetooth SIM access"</string>
     <string name="bluetooth_sap_notif_message" msgid="7138657801087500690">"Request client to disconnect?"</string>
     <string name="bluetooth_sap_notif_disconnecting" msgid="819150843490233288">"Waiting for client to disconnect"</string>
     <string name="bluetooth_sap_notif_disconnect_button" msgid="3678476872583356919">"Disconnect"</string>
diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml
index 156c2df..865b307 100644
--- a/res/values-en-rCA/strings.xml
+++ b/res/values-en-rCA/strings.xml
@@ -121,17 +121,17 @@
     <string name="transfer_menu_open" msgid="3368984869083107200">"Open"</string>
     <string name="transfer_menu_clear" msgid="5854038118831427492">"Clear from list"</string>
     <string name="transfer_clear_dlg_title" msgid="2953444575556460386">"Clear"</string>
-    <string name="bluetooth_a2dp_sink_queue_name" msgid="6864149958708669766">"Now Playing"</string>
+    <string name="bluetooth_a2dp_sink_queue_name" msgid="6864149958708669766">"Now playing"</string>
     <string name="bluetooth_map_settings_save" msgid="7635491847388074606">"Save"</string>
     <string name="bluetooth_map_settings_cancel" msgid="9205350798049865699">"Cancel"</string>
     <string name="bluetooth_map_settings_intro" msgid="6482369468223987562">"Select the accounts that you want to share through Bluetooth. You still have to accept any access to the accounts when connecting."</string>
     <string name="bluetooth_map_settings_count" msgid="4557473074937024833">"Slots left:"</string>
-    <string name="bluetooth_map_settings_app_icon" msgid="7105805610929114707">"Application Icon"</string>
-    <string name="bluetooth_map_settings_title" msgid="7420332483392851321">"Bluetooth Message Sharing Settings"</string>
+    <string name="bluetooth_map_settings_app_icon" msgid="7105805610929114707">"Application icon"</string>
+    <string name="bluetooth_map_settings_title" msgid="7420332483392851321">"Bluetooth message sharing settings"</string>
     <string name="bluetooth_map_settings_no_account_slots_left" msgid="1796029082612965251">"Cannot select account. 0 slots left"</string>
     <string name="bluetooth_connected" msgid="6718623220072656906">"Bluetooth audio connected"</string>
     <string name="bluetooth_disconnected" msgid="3318303728981478873">"Bluetooth audio disconnected"</string>
-    <string name="a2dp_sink_mbs_label" msgid="7566075853395412558">"Bluetooth Audio"</string>
+    <string name="a2dp_sink_mbs_label" msgid="7566075853395412558">"Bluetooth audio"</string>
     <string name="bluetooth_opp_file_limit_exceeded" msgid="8894450394309084519">"Files bigger than 4 GB cannot be transferred"</string>
     <string name="bluetooth_connect_action" msgid="4009848433321657090">"Connect to Bluetooth"</string>
 </resources>
diff --git a/res/values-en-rCA/strings_pbap.xml b/res/values-en-rCA/strings_pbap.xml
index c80ccb6..fd4e512 100644
--- a/res/values-en-rCA/strings_pbap.xml
+++ b/res/values-en-rCA/strings_pbap.xml
@@ -4,9 +4,9 @@
     <string name="pbap_session_key_dialog_title" msgid="3580996574333882561">"Type session key for %1$s"</string>
     <string name="pbap_session_key_dialog_header" msgid="2772472422782758981">"Bluetooth session key required"</string>
     <string name="pbap_acceptance_timeout_message" msgid="1107401415099814293">"There was time out to accept connection with %1$s"</string>
-    <string name="pbap_authentication_timeout_message" msgid="4166979525521902687">"There was time out to input session key with %1$s"</string>
+    <string name="pbap_authentication_timeout_message" msgid="4166979525521902687">"There was a timeout to input session key with %1$s"</string>
     <string name="auth_notif_ticker" msgid="1575825798053163744">"Obex authentication request"</string>
-    <string name="auth_notif_title" msgid="7599854855681573258">"Session Key"</string>
+    <string name="auth_notif_title" msgid="7599854855681573258">"Session key"</string>
     <string name="auth_notif_message" msgid="6667218116427605038">"Type session key for %1$s"</string>
     <string name="defaultname" msgid="4821590500649090078">"Car Kit"</string>
     <string name="unknownName" msgid="2841414754740600042">"Unknown name"</string>
diff --git a/res/values-en-rCA/strings_sap.xml b/res/values-en-rCA/strings_sap.xml
index c79b034..2ebae8c 100644
--- a/res/values-en-rCA/strings_sap.xml
+++ b/res/values-en-rCA/strings_sap.xml
@@ -2,7 +2,7 @@
 <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">"Bluetooth SIM access"</string>
-    <string name="bluetooth_sap_notif_ticker" msgid="6807778527893726699">"Bluetooth SIM Access"</string>
+    <string name="bluetooth_sap_notif_ticker" msgid="6807778527893726699">"Bluetooth SIM access"</string>
     <string name="bluetooth_sap_notif_message" msgid="7138657801087500690">"Request client to disconnect?"</string>
     <string name="bluetooth_sap_notif_disconnecting" msgid="819150843490233288">"Waiting for client to disconnect"</string>
     <string name="bluetooth_sap_notif_disconnect_button" msgid="3678476872583356919">"Disconnect"</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 12298d5..bf4d6b2 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -121,17 +121,17 @@
     <string name="transfer_menu_open" msgid="3368984869083107200">"Open"</string>
     <string name="transfer_menu_clear" msgid="5854038118831427492">"Clear from list"</string>
     <string name="transfer_clear_dlg_title" msgid="2953444575556460386">"Clear"</string>
-    <string name="bluetooth_a2dp_sink_queue_name" msgid="6864149958708669766">"Now Playing"</string>
+    <string name="bluetooth_a2dp_sink_queue_name" msgid="6864149958708669766">"Now playing"</string>
     <string name="bluetooth_map_settings_save" msgid="7635491847388074606">"Save"</string>
     <string name="bluetooth_map_settings_cancel" msgid="9205350798049865699">"Cancel"</string>
     <string name="bluetooth_map_settings_intro" msgid="6482369468223987562">"Select the accounts that you want to share through Bluetooth. You still have to accept any access to the accounts when connecting."</string>
     <string name="bluetooth_map_settings_count" msgid="4557473074937024833">"Slots left:"</string>
-    <string name="bluetooth_map_settings_app_icon" msgid="7105805610929114707">"Application Icon"</string>
-    <string name="bluetooth_map_settings_title" msgid="7420332483392851321">"Bluetooth Message Sharing Settings"</string>
+    <string name="bluetooth_map_settings_app_icon" msgid="7105805610929114707">"Application icon"</string>
+    <string name="bluetooth_map_settings_title" msgid="7420332483392851321">"Bluetooth message sharing settings"</string>
     <string name="bluetooth_map_settings_no_account_slots_left" msgid="1796029082612965251">"Cannot select account. 0 slots left"</string>
     <string name="bluetooth_connected" msgid="6718623220072656906">"Bluetooth audio connected"</string>
     <string name="bluetooth_disconnected" msgid="3318303728981478873">"Bluetooth audio disconnected"</string>
-    <string name="a2dp_sink_mbs_label" msgid="7566075853395412558">"Bluetooth Audio"</string>
+    <string name="a2dp_sink_mbs_label" msgid="7566075853395412558">"Bluetooth audio"</string>
     <string name="bluetooth_opp_file_limit_exceeded" msgid="8894450394309084519">"Files bigger than 4 GB cannot be transferred"</string>
     <string name="bluetooth_connect_action" msgid="4009848433321657090">"Connect to Bluetooth"</string>
 </resources>
diff --git a/res/values-en-rGB/strings_pbap.xml b/res/values-en-rGB/strings_pbap.xml
index c80ccb6..fd4e512 100644
--- a/res/values-en-rGB/strings_pbap.xml
+++ b/res/values-en-rGB/strings_pbap.xml
@@ -4,9 +4,9 @@
     <string name="pbap_session_key_dialog_title" msgid="3580996574333882561">"Type session key for %1$s"</string>
     <string name="pbap_session_key_dialog_header" msgid="2772472422782758981">"Bluetooth session key required"</string>
     <string name="pbap_acceptance_timeout_message" msgid="1107401415099814293">"There was time out to accept connection with %1$s"</string>
-    <string name="pbap_authentication_timeout_message" msgid="4166979525521902687">"There was time out to input session key with %1$s"</string>
+    <string name="pbap_authentication_timeout_message" msgid="4166979525521902687">"There was a timeout to input session key with %1$s"</string>
     <string name="auth_notif_ticker" msgid="1575825798053163744">"Obex authentication request"</string>
-    <string name="auth_notif_title" msgid="7599854855681573258">"Session Key"</string>
+    <string name="auth_notif_title" msgid="7599854855681573258">"Session key"</string>
     <string name="auth_notif_message" msgid="6667218116427605038">"Type session key for %1$s"</string>
     <string name="defaultname" msgid="4821590500649090078">"Car Kit"</string>
     <string name="unknownName" msgid="2841414754740600042">"Unknown name"</string>
diff --git a/res/values-en-rGB/strings_sap.xml b/res/values-en-rGB/strings_sap.xml
index c79b034..2ebae8c 100644
--- a/res/values-en-rGB/strings_sap.xml
+++ b/res/values-en-rGB/strings_sap.xml
@@ -2,7 +2,7 @@
 <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">"Bluetooth SIM access"</string>
-    <string name="bluetooth_sap_notif_ticker" msgid="6807778527893726699">"Bluetooth SIM Access"</string>
+    <string name="bluetooth_sap_notif_ticker" msgid="6807778527893726699">"Bluetooth SIM access"</string>
     <string name="bluetooth_sap_notif_message" msgid="7138657801087500690">"Request client to disconnect?"</string>
     <string name="bluetooth_sap_notif_disconnecting" msgid="819150843490233288">"Waiting for client to disconnect"</string>
     <string name="bluetooth_sap_notif_disconnect_button" msgid="3678476872583356919">"Disconnect"</string>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index 12298d5..bf4d6b2 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -121,17 +121,17 @@
     <string name="transfer_menu_open" msgid="3368984869083107200">"Open"</string>
     <string name="transfer_menu_clear" msgid="5854038118831427492">"Clear from list"</string>
     <string name="transfer_clear_dlg_title" msgid="2953444575556460386">"Clear"</string>
-    <string name="bluetooth_a2dp_sink_queue_name" msgid="6864149958708669766">"Now Playing"</string>
+    <string name="bluetooth_a2dp_sink_queue_name" msgid="6864149958708669766">"Now playing"</string>
     <string name="bluetooth_map_settings_save" msgid="7635491847388074606">"Save"</string>
     <string name="bluetooth_map_settings_cancel" msgid="9205350798049865699">"Cancel"</string>
     <string name="bluetooth_map_settings_intro" msgid="6482369468223987562">"Select the accounts that you want to share through Bluetooth. You still have to accept any access to the accounts when connecting."</string>
     <string name="bluetooth_map_settings_count" msgid="4557473074937024833">"Slots left:"</string>
-    <string name="bluetooth_map_settings_app_icon" msgid="7105805610929114707">"Application Icon"</string>
-    <string name="bluetooth_map_settings_title" msgid="7420332483392851321">"Bluetooth Message Sharing Settings"</string>
+    <string name="bluetooth_map_settings_app_icon" msgid="7105805610929114707">"Application icon"</string>
+    <string name="bluetooth_map_settings_title" msgid="7420332483392851321">"Bluetooth message sharing settings"</string>
     <string name="bluetooth_map_settings_no_account_slots_left" msgid="1796029082612965251">"Cannot select account. 0 slots left"</string>
     <string name="bluetooth_connected" msgid="6718623220072656906">"Bluetooth audio connected"</string>
     <string name="bluetooth_disconnected" msgid="3318303728981478873">"Bluetooth audio disconnected"</string>
-    <string name="a2dp_sink_mbs_label" msgid="7566075853395412558">"Bluetooth Audio"</string>
+    <string name="a2dp_sink_mbs_label" msgid="7566075853395412558">"Bluetooth audio"</string>
     <string name="bluetooth_opp_file_limit_exceeded" msgid="8894450394309084519">"Files bigger than 4 GB cannot be transferred"</string>
     <string name="bluetooth_connect_action" msgid="4009848433321657090">"Connect to Bluetooth"</string>
 </resources>
diff --git a/res/values-en-rIN/strings_pbap.xml b/res/values-en-rIN/strings_pbap.xml
index c80ccb6..fd4e512 100644
--- a/res/values-en-rIN/strings_pbap.xml
+++ b/res/values-en-rIN/strings_pbap.xml
@@ -4,9 +4,9 @@
     <string name="pbap_session_key_dialog_title" msgid="3580996574333882561">"Type session key for %1$s"</string>
     <string name="pbap_session_key_dialog_header" msgid="2772472422782758981">"Bluetooth session key required"</string>
     <string name="pbap_acceptance_timeout_message" msgid="1107401415099814293">"There was time out to accept connection with %1$s"</string>
-    <string name="pbap_authentication_timeout_message" msgid="4166979525521902687">"There was time out to input session key with %1$s"</string>
+    <string name="pbap_authentication_timeout_message" msgid="4166979525521902687">"There was a timeout to input session key with %1$s"</string>
     <string name="auth_notif_ticker" msgid="1575825798053163744">"Obex authentication request"</string>
-    <string name="auth_notif_title" msgid="7599854855681573258">"Session Key"</string>
+    <string name="auth_notif_title" msgid="7599854855681573258">"Session key"</string>
     <string name="auth_notif_message" msgid="6667218116427605038">"Type session key for %1$s"</string>
     <string name="defaultname" msgid="4821590500649090078">"Car Kit"</string>
     <string name="unknownName" msgid="2841414754740600042">"Unknown name"</string>
diff --git a/res/values-en-rIN/strings_sap.xml b/res/values-en-rIN/strings_sap.xml
index c79b034..2ebae8c 100644
--- a/res/values-en-rIN/strings_sap.xml
+++ b/res/values-en-rIN/strings_sap.xml
@@ -2,7 +2,7 @@
 <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">"Bluetooth SIM access"</string>
-    <string name="bluetooth_sap_notif_ticker" msgid="6807778527893726699">"Bluetooth SIM Access"</string>
+    <string name="bluetooth_sap_notif_ticker" msgid="6807778527893726699">"Bluetooth SIM access"</string>
     <string name="bluetooth_sap_notif_message" msgid="7138657801087500690">"Request client to disconnect?"</string>
     <string name="bluetooth_sap_notif_disconnecting" msgid="819150843490233288">"Waiting for client to disconnect"</string>
     <string name="bluetooth_sap_notif_disconnect_button" msgid="3678476872583356919">"Disconnect"</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index b2ca012..8a56d61 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -121,7 +121,7 @@
     <string name="transfer_menu_open" msgid="3368984869083107200">"Abrir"</string>
     <string name="transfer_menu_clear" msgid="5854038118831427492">"Eliminar de la lista"</string>
     <string name="transfer_clear_dlg_title" msgid="2953444575556460386">"Eliminar"</string>
-    <string name="bluetooth_a2dp_sink_queue_name" msgid="6864149958708669766">"Está Sonando"</string>
+    <string name="bluetooth_a2dp_sink_queue_name" msgid="6864149958708669766">"Está sonando"</string>
     <string name="bluetooth_map_settings_save" msgid="7635491847388074606">"Guardar"</string>
     <string name="bluetooth_map_settings_cancel" msgid="9205350798049865699">"Cancelar"</string>
     <string name="bluetooth_map_settings_intro" msgid="6482369468223987562">"Selecciona las cuentas que deseas compartir mediante Bluetooth. Al conectarte, tendrás que aceptar cualquier acceso a las cuentas."</string>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index 918852c..47b0c4f 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -62,7 +62,7 @@
     <string name="download_fail_ok" msgid="1521733664438320300">"Ados"</string>
     <string name="download_succ_line5" msgid="4509944688281573595">"Fitxategia jaso da"</string>
     <string name="download_succ_ok" msgid="7053688246357050216">"Ireki"</string>
-    <string name="upload_line1" msgid="2055952074059709052">"Hartzailea: \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\""</string>
+    <string name="upload_line1" msgid="2055952074059709052">"Hartzaileak: \"<xliff:g id="RECIPIENT">%1$s</xliff:g>\""</string>
     <string name="upload_line3" msgid="4920689672457037437">"Fitxategi mota: <xliff:g id="TYPE">%1$s</xliff:g> (<xliff:g id="SIZE">%2$s</xliff:g>)"</string>
     <string name="upload_line5" msgid="7759322537674229752">"Fitxategia bidaltzen…"</string>
     <string name="upload_succ_line5" msgid="5687317197463383601">"Fitxategia bidali da"</string>
diff --git a/res/values-fa/strings_pbap.xml b/res/values-fa/strings_pbap.xml
index 348156a..b73b52d 100644
--- a/res/values-fa/strings_pbap.xml
+++ b/res/values-fa/strings_pbap.xml
@@ -3,9 +3,9 @@
     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">"به کلید جلسه بلوتوث نیاز است"</string>
-    <string name="pbap_acceptance_timeout_message" msgid="1107401415099814293">"‏پذیرش اتصال با %1$s خیلی زمان برد"</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="auth_notif_ticker" msgid="1575825798053163744">"‏درخواست احراز هویت Obex"</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>
     <string name="defaultname" msgid="4821590500649090078">"کیت خودرو"</string>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 66a2f8d..55742a1 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/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">"श्वेतसूची bluetooth डिवाइस पहुंच."</string>
     <string name="permdesc_bluetoothWhitelist" msgid="5494513855192170109">"ऐप को, ब्लूटूथ डिवाइस को उपयोगकर्ता की पुष्टि के बिना इस डिवाइस पर फ़ाइल भेजने की‍ अनुमति देकर, कुछ देर के लिए अनुमति देता है"</string>
     <string name="bt_share_picker_label" msgid="6268100924487046932">"ब्लूटूथ"</string>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index 3c51f64..57a6214 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -59,7 +59,7 @@
     <string name="download_fail_line1" msgid="3846450148862894552">"Ֆայլը չհաջողվեց ստանալ"</string>
     <string name="download_fail_line2" msgid="8950394574689971071">"Ֆայլ՝ <xliff:g id="FILE">%1$s</xliff:g>"</string>
     <string name="download_fail_line3" msgid="3451040656154861722">"Պատճառը՝ <xliff:g id="REASON">%1$s</xliff:g>"</string>
-    <string name="download_fail_ok" msgid="1521733664438320300">"Հաստատել"</string>
+    <string name="download_fail_ok" msgid="1521733664438320300">"Եղավ"</string>
     <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>
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
index 53202bb..2ab2677 100644
--- a/res/values-ml/strings.xml
+++ b/res/values-ml/strings.xml
@@ -113,8 +113,10 @@
       <item quantity="other"><xliff:g id="UNSUCCESSFUL_NUMBER_1">%1$d</xliff:g> പരാജയം.</item>
       <item quantity="one"><xliff:g id="UNSUCCESSFUL_NUMBER_0">%1$d</xliff:g> പരാജയം.</item>
     </plurals>
-    <!-- String.format failed for translation -->
-    <!-- no translation found for noti_caption_success (1572472450257645181) -->
+    <plurals name="noti_caption_success" formatted="false" msgid="1572472450257645181">
+      <item quantity="other"><xliff:g id="SUCCESSFUL_NUMBER_1">%1$d</xliff:g> വിജയകരം, %2$s</item>
+      <item quantity="one"><xliff:g id="SUCCESSFUL_NUMBER_0">%1$d</xliff:g> വിജയകരം, %2$s</item>
+    </plurals>
     <string name="transfer_menu_clear_all" msgid="790017462957873132">"ലിസ്റ്റ് മായ്‌ക്കുക"</string>
     <string name="transfer_menu_open" msgid="3368984869083107200">"തുറക്കുക"</string>
     <string name="transfer_menu_clear" msgid="5854038118831427492">"ലിസ്റ്റിൽ നിന്നും മായ്‌ക്കുക"</string>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index 803a876..7ea9269 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -31,12 +31,12 @@
     <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_content" msgid="2752605552743148036">"येणारी फाईल स्‍वीकारायची?"</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>
     <string name="incoming_file_confirm_timeout_ok" msgid="1414676773249857278">"ठीक"</string>
     <string name="incoming_file_confirm_timeout_content" msgid="172779756093975981">"\"<xliff:g id="SENDER">%1$s</xliff:g>\" कडील फाइल स्‍वीकार करताना वेळ संपली."</string>
-    <string name="incoming_file_confirm_Notification_title" msgid="5573329005298936903">"येणारी फाईल"</string>
+    <string name="incoming_file_confirm_Notification_title" msgid="5573329005298936903">"येणारी फाइल"</string>
     <string name="incoming_file_confirm_Notification_content" msgid="3359694069319644738">"<xliff:g id="FILE">%2$s</xliff:g> पाठविण्‍यासाठी <xliff:g id="SENDER">%1$s</xliff:g> तयार आहे"</string>
     <string name="notification_receiving" msgid="4674648179652543984">"ब्लूटूथ शेअर: <xliff:g id="FILE">%1$s</xliff:g> मिळवत आहे"</string>
     <string name="notification_received" msgid="3324588019186687985">"ब्लूटूथ शेअर: <xliff:g id="FILE">%1$s</xliff:g> प्राप्त केली"</string>
@@ -77,7 +77,7 @@
     <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">"ब्लूटूथ सुरू करत आहे…"</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>
@@ -87,10 +87,10 @@
     <string name="bt_sm_2_1_default" msgid="9115512207909504071">"\"<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_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_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>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index d679c3b..feced5c 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -133,5 +133,5 @@
     <string name="bluetooth_disconnected" msgid="3318303728981478873">"ब्लुटुथ सम्बन्धी अडियो यन्त्रलाई विच्छेद गरियो"</string>
     <string name="a2dp_sink_mbs_label" msgid="7566075853395412558">"ब्लुटुथको अडियो"</string>
     <string name="bluetooth_opp_file_limit_exceeded" msgid="8894450394309084519">"४ जि.बि. भन्दा ठूला फाइलहरूलाई स्थानान्तरण गर्न सकिँदैन"</string>
-    <string name="bluetooth_connect_action" msgid="4009848433321657090">"ब्लुटुथमा जोड्नुहोस्"</string>
+    <string name="bluetooth_connect_action" msgid="4009848433321657090">"ब्लुटुथमा कनेक्ट गर्नुहोस्"</string>
 </resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 2ae11f3..8cfa3bd 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -26,10 +26,10 @@
     <string name="airplane_error_title" msgid="2683839635115739939">"Vliegtuigmodus"</string>
     <string name="airplane_error_msg" msgid="8698965595254137230">"Je kunt Bluetooth niet gebruiken in Vliegtuigmodus."</string>
     <string name="bt_enable_title" msgid="8657832550503456572"></string>
-    <string name="bt_enable_line1" msgid="7203551583048149">"Als je Bluetooth-services wilt gebruiken, moet je eerst Bluetooth inschakelen."</string>
-    <string name="bt_enable_line2" msgid="4341936569415937994">"Bluetooth nu inschakelen?"</string>
+    <string name="bt_enable_line1" msgid="7203551583048149">"Als je Bluetooth-services wilt gebruiken, moet je eerst Bluetooth aanzetten."</string>
+    <string name="bt_enable_line2" msgid="4341936569415937994">"Bluetooth nu aanzetten?"</string>
     <string name="bt_enable_cancel" msgid="1988832367505151727">"Annuleren"</string>
-    <string name="bt_enable_ok" msgid="3432462749994538265">"Inschakelen"</string>
+    <string name="bt_enable_ok" msgid="3432462749994538265">"Aanzetten"</string>
     <string name="incoming_file_confirm_title" msgid="8139874248612182627">"Bestandsoverdracht"</string>
     <string name="incoming_file_confirm_content" msgid="2752605552743148036">"Inkomend bestand accepteren?"</string>
     <string name="incoming_file_confirm_cancel" msgid="2973321832477704805">"Weigeren"</string>
@@ -76,7 +76,7 @@
     <string name="not_exist_file" msgid="3489434189599716133">"Geen bestand"</string>
     <string name="not_exist_file_desc" msgid="4059531573790529229">"Het bestand bestaat niet. \n"</string>
     <string name="enabling_progress_title" msgid="436157952334723406">"Een ogenblik geduld..."</string>
-    <string name="enabling_progress_content" msgid="4601542238119927904">"Bluetooth inschakelen…"</string>
+    <string name="enabling_progress_content" msgid="4601542238119927904">"Bluetooth aanzetten…"</string>
     <string name="bt_toast_1" msgid="972182708034353383">"Het bestand wordt ontvangen. Je kunt de voortgang controleren in het venster \'Meldingen\'."</string>
     <string name="bt_toast_2" msgid="8602553334099066582">"Het bestand kan niet worden opgehaald."</string>
     <string name="bt_toast_3" msgid="6707884165086862518">"Ontvangen van bestand van \'<xliff:g id="SENDER">%1$s</xliff:g>\' is beëindigd"</string>
@@ -126,7 +126,7 @@
     <string name="bluetooth_map_settings_cancel" msgid="9205350798049865699">"Annuleren"</string>
     <string name="bluetooth_map_settings_intro" msgid="6482369468223987562">"Selecteer de accounts die je wilt delen via bluetooth. Je moet nog steeds elke toegang tot de accounts accepteren wanneer er verbinding wordt gemaakt."</string>
     <string name="bluetooth_map_settings_count" msgid="4557473074937024833">"Plaatsen over:"</string>
-    <string name="bluetooth_map_settings_app_icon" msgid="7105805610929114707">"App-pictogram"</string>
+    <string name="bluetooth_map_settings_app_icon" msgid="7105805610929114707">"App-icoon"</string>
     <string name="bluetooth_map_settings_title" msgid="7420332483392851321">"Instellingen voor delen van berichten via bluetooth"</string>
     <string name="bluetooth_map_settings_no_account_slots_left" msgid="1796029082612965251">"Kan account niet selecteren. 0 plaatsen over"</string>
     <string name="bluetooth_connected" msgid="6718623220072656906">"Bluetooth-audio gekoppeld"</string>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index 6d41946..5005bfb 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -121,7 +121,7 @@
     <string name="transfer_menu_open" msgid="3368984869083107200">"Ochish"</string>
     <string name="transfer_menu_clear" msgid="5854038118831427492">"Ro‘yxatdan o‘chirish"</string>
     <string name="transfer_clear_dlg_title" msgid="2953444575556460386">"Tozalash"</string>
-    <string name="bluetooth_a2dp_sink_queue_name" msgid="6864149958708669766">"Ijro qilinmoqda"</string>
+    <string name="bluetooth_a2dp_sink_queue_name" msgid="6864149958708669766">"Bu qaysi musiqa"</string>
     <string name="bluetooth_map_settings_save" msgid="7635491847388074606">"Saqlash"</string>
     <string name="bluetooth_map_settings_cancel" msgid="9205350798049865699">"Bekor qilish"</string>
     <string name="bluetooth_map_settings_intro" msgid="6482369468223987562">"Bluetooth orqali narsa o‘tkazmoqchi bo‘lgan hisoblarni tanlang. Har safar ulanishda so‘rovni tasdiqlash talab qilinadi."</string>
diff --git a/src/com/android/bluetooth/AlertActivity.java b/src/com/android/bluetooth/AlertActivity.java
index 6de2cec..e45c770 100644
--- a/src/com/android/bluetooth/AlertActivity.java
+++ b/src/com/android/bluetooth/AlertActivity.java
@@ -16,6 +16,8 @@
 
 package android.bluetooth;
 
+import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
@@ -46,6 +48,8 @@
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+
+        getWindow().addPrivateFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
         requestWindowFeature(Window.FEATURE_NO_TITLE);
         mAlertBuilder = new AlertDialog.Builder(this);
         mAlertBuilder.setOnDismissListener(this);
diff --git a/src/com/android/bluetooth/a2dp/A2dpService.java b/src/com/android/bluetooth/a2dp/A2dpService.java
index 45a066a..08373c3 100644
--- a/src/com/android/bluetooth/a2dp/A2dpService.java
+++ b/src/com/android/bluetooth/a2dp/A2dpService.java
@@ -1390,6 +1390,10 @@
         if (mA2dpCodecConfig != null) {
             ProfileService.println(sb, "codecConfigPriorities:");
             for (BluetoothCodecConfig codecConfig : mA2dpCodecConfig.codecConfigPriorities()) {
+                if (codecConfig == null) {
+                    ProfileService.println(sb, " WARNING: codecConfig is null");
+                    continue;
+                }
                 ProfileService.println(sb, "  " + codecConfig.getCodecName() + ": "
                         + codecConfig.getCodecPriority());
             }
@@ -1397,6 +1401,10 @@
             if (mA2dpOffloadEnabled) {
                 ProfileService.println(sb, "codecConfigOffloading:");
                 for (BluetoothCodecConfig codecConfig : mA2dpCodecConfig.codecConfigOffloading()) {
+                    if (codecConfig == null) {
+                        ProfileService.println(sb, " WARNING: codecConfig is null");
+                        continue;
+                    }
                     ProfileService.println(sb, "  " + codecConfig);
                 }
             }
diff --git a/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java b/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java
index 367b235..a0fa0b3 100644
--- a/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java
+++ b/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java
@@ -182,6 +182,10 @@
     }
 
     void sendVolumeChanged(@NonNull BluetoothDevice device, int deviceVolume) {
+        if (deviceVolume == getVolume(device, -1)) {
+            d("sendVolumeChanged: Skipping update volume to same as current.");
+            return;
+        }
         int avrcpVolume =
                 (int) Math.floor((double) deviceVolume * AVRCP_MAX_VOL / sDeviceMaxVolume);
         if (avrcpVolume > 127) avrcpVolume = 127;
diff --git a/src/com/android/bluetooth/avrcp/MediaPlayerList.java b/src/com/android/bluetooth/avrcp/MediaPlayerList.java
index bb2baab..4d9b413 100644
--- a/src/com/android/bluetooth/avrcp/MediaPlayerList.java
+++ b/src/com/android/bluetooth/avrcp/MediaPlayerList.java
@@ -260,6 +260,10 @@
         info.id = BLUETOOTH_PLAYER_ID;
         info.name = BLUETOOTH_PLAYER_NAME;
         info.browsable = true;
+        if (mBrowsablePlayers.size() == 0) {
+            // Set Bluetooth Player as non-browable if there is not browsable player exist.
+            info.browsable = false;
+        }
         List<PlayerInfo> ret = new ArrayList<PlayerInfo>();
         ret.add(info);
 
diff --git a/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java b/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java
index b6907ec..9507d90 100755
--- a/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java
+++ b/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java
@@ -390,7 +390,8 @@
         AvrcpControllerStateMachine stateMachine = getStateMachine(device);
         if (stateMachine != null) {
             stateMachine.sendMessage(
-                    AvrcpControllerStateMachine.MESSAGE_PROCESS_REGISTER_ABS_VOL_NOTIFICATION);
+                    AvrcpControllerStateMachine.MESSAGE_PROCESS_REGISTER_ABS_VOL_NOTIFICATION,
+                    (int) label);
         }
     }
 
diff --git a/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtManager.java b/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtManager.java
index 8315a62..c6de62d 100644
--- a/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtManager.java
+++ b/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtManager.java
@@ -18,6 +18,7 @@
 
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothProfile;
+import android.graphics.Bitmap;
 import android.net.Uri;
 import android.os.SystemProperties;
 import android.util.Log;
@@ -77,8 +78,7 @@
          * Notify of a get image download completing
          *
          * @param device The device the image handle belongs to
-         * @param imageHandle The handle of the requested image
-         * @param uri The Uri that the image is available at in storage
+         * @param event The download event, containing the downloaded image's information
          */
         void onImageDownloadComplete(BluetoothDevice device, DownloadEvent event);
     }
@@ -193,7 +193,6 @@
         for (BluetoothDevice device : mClients.keySet()) {
             disconnect(device);
         }
-        mCoverArtStorage.clear();
     }
 
     /**
@@ -310,10 +309,20 @@
     }
 
     /**
-     * Remote a specific downloaded image if it exists
+     * Get a specific downloaded image if it exists
      *
      * @param device The remote Bluetooth device associated with the image
-     * @param imageHandle The handle associated with the image you wish to remove
+     * @param imageUuid The UUID associated with the image you wish to retrieve
+     */
+    public Bitmap getImage(BluetoothDevice device, String imageUuid) {
+        return mCoverArtStorage.getImage(device, imageUuid);
+    }
+
+    /**
+     * Remove a specific downloaded image if it exists
+     *
+     * @param device The remote Bluetooth device associated with the image
+     * @param imageUuid The UUID associated with the image you wish to remove
      */
     public void removeImage(BluetoothDevice device, String imageUuid) {
         mCoverArtStorage.removeImage(device, imageUuid);
diff --git a/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtProvider.java b/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtProvider.java
index 24f93f9..dd59dcb 100644
--- a/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtProvider.java
+++ b/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtProvider.java
@@ -21,12 +21,14 @@
 import android.content.ContentProvider;
 import android.content.ContentValues;
 import android.database.Cursor;
+import android.graphics.Bitmap;
 import android.net.Uri;
 import android.os.ParcelFileDescriptor;
 import android.util.Log;
 
-import java.io.File;
 import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
 
 /**
  * A provider of downloaded cover art images.
@@ -48,7 +50,6 @@
     private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
 
     private BluetoothAdapter mAdapter;
-    private AvrcpCoverArtStorage mStorage;
 
     public AvrcpCoverArtProvider() {
     }
@@ -60,37 +61,69 @@
      * Get the Uri for a cover art image based on the device and image handle
      *
      * @param device The Bluetooth device from which an image originated
-     * @param imageHandle The provided handle of the cover artwork
+     * @param imageUuid The provided UUID of the cover artwork
      * @return The Uri this provider will store the downloaded image at
      */
-    public static Uri getImageUri(BluetoothDevice device, String imageHandle) {
-        if (device == null || imageHandle == null || "".equals(imageHandle)) return null;
+    public static Uri getImageUri(BluetoothDevice device, String imageUuid) {
+        if (device == null || imageUuid == null || "".equals(imageUuid)) return null;
         Uri uri = CONTENT_URI.buildUpon().appendQueryParameter("device", device.getAddress())
-                .appendQueryParameter("handle", imageHandle)
+                .appendQueryParameter("uuid", imageUuid)
                 .build();
         debug("getImageUri -> " + uri.toString());
         return uri;
     }
 
-    private ParcelFileDescriptor getImageDescriptor(BluetoothDevice device, String imageHandle)
-            throws FileNotFoundException {
-        debug("getImageDescriptor(" + device + ", " + imageHandle + ")");
-        File file = mStorage.getImageFile(device, imageHandle);
-        if (file == null) throw new FileNotFoundException();
-        ParcelFileDescriptor pdf = ParcelFileDescriptor.open(file,
-                ParcelFileDescriptor.MODE_READ_ONLY);
-        return pdf;
+    private Bitmap getImage(BluetoothDevice device, String imageUuid) {
+        AvrcpControllerService service = AvrcpControllerService.getAvrcpControllerService();
+        if (service == null) {
+            debug("Failed to get service, cover art not available");
+            return null;
+        }
+
+        AvrcpCoverArtManager manager = service.getCoverArtManager();
+        if (manager == null) {
+            debug("Failed to get cover art manager. Cover art may not be enabled.");
+            return null;
+        }
+        return manager.getImage(device, imageUuid);
+    }
+
+    private ParcelFileDescriptor getImageDescriptor(BluetoothDevice device, String imageUuid)
+            throws FileNotFoundException, IOException {
+        debug("getImageDescriptor(" + device + ", " + imageUuid + ")");
+        Bitmap image = getImage(device, imageUuid);
+        if (image == null) {
+            debug("Could not get requested image");
+            throw new FileNotFoundException();
+        }
+
+        final ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
+        Thread transferThread = new Thread() {
+            public void run() {
+                try {
+                    FileOutputStream fout =
+                            new ParcelFileDescriptor.AutoCloseOutputStream(pipe[1]);
+                    image.compress(Bitmap.CompressFormat.PNG, 100, fout);
+                    fout.flush();
+                    fout.close();
+                } catch (IOException e) {
+                    /* Something bad must have happened writing the image data */
+                }
+            }
+        };
+        transferThread.start();
+        return pipe[0];
     }
 
     @Override
     public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
         debug("openFile(" + uri + ", '" + mode + "')");
         String address = null;
-        String imageHandle = null;
+        String imageUuid = null;
         BluetoothDevice device = null;
         try {
             address = uri.getQueryParameter("device");
-            imageHandle = uri.getQueryParameter("handle");
+            imageUuid = uri.getQueryParameter("uuid");
         } catch (NullPointerException e) {
             throw new FileNotFoundException();
         }
@@ -101,13 +134,19 @@
             throw new FileNotFoundException();
         }
 
-        return getImageDescriptor(device, imageHandle);
+        ParcelFileDescriptor pfd = null;
+        try {
+            pfd = getImageDescriptor(device, imageUuid);
+        } catch (IOException e) {
+            debug("Failed to create inputstream from Bitmap");
+            throw new FileNotFoundException();
+        }
+        return pfd;
     }
 
     @Override
     public boolean onCreate() {
         mAdapter = BluetoothAdapter.getDefaultAdapter();
-        mStorage = new AvrcpCoverArtStorage(getContext());
         return true;
     }
 
diff --git a/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtStorage.java b/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtStorage.java
index 8b6fbf9..5474971 100644
--- a/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtStorage.java
+++ b/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtStorage.java
@@ -20,15 +20,13 @@
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.net.Uri;
-import android.os.Environment;
 import android.util.Log;
 
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
- * An abstraction of the file system storage of the downloaded cover art images.
+ * An abstraction of the cover art image storage mechanism.
  */
 public class AvrcpCoverArtStorage {
     private static final String TAG = "AvrcpCoverArtStorage";
@@ -36,6 +34,15 @@
 
     private final Context mContext;
 
+    /* Each device gets its own place to land images. This makes it easier to clean things up on a
+     * per device basis. This also allows us to be confident that acting on one device will not
+     * impact the images of another.
+     *
+     * The "landing place" is simply a map that will direct a given UUID to the proper bitmap image
+     */
+    private final Map<BluetoothDevice, Map<String, Bitmap>> mDeviceImages =
+            new ConcurrentHashMap<>(1);
+
     /**
      * Create and initialize this Cover Art storage interface
      */
@@ -47,94 +54,81 @@
      * Determine if an image already exists in storage
      *
      * @param device - The device the images was downloaded from
-     * @param imageHandle - The handle that identifies the image
+     * @param imageUuid - The UUID that identifies the image
      */
-    public boolean doesImageExist(BluetoothDevice device, String imageHandle) {
-        if (device == null || imageHandle == null || "".equals(imageHandle)) return false;
-        String path = getImagePath(device, imageHandle);
-        if (path == null) return false;
-        File file = new File(path);
-        return file.exists();
+    public boolean doesImageExist(BluetoothDevice device, String imageUuid) {
+        if (device == null || imageUuid == null || "".equals(imageUuid)) return false;
+        Map<String, Bitmap> images = mDeviceImages.get(device);
+        if (images == null) return false;
+        return images.containsKey(imageUuid);
     }
 
     /**
      * Retrieve an image file from storage
      *
      * @param device - The device the images was downloaded from
-     * @param imageHandle - The handle that identifies the image
-     * @return A file descriptor for the image
+     * @param imageUuid - The UUID that identifies the image
+     * @return A Bitmap object of the image
      */
-    public File getImageFile(BluetoothDevice device, String imageHandle) {
-        if (device == null || imageHandle == null || "".equals(imageHandle)) return null;
-        String path = getImagePath(device, imageHandle);
-        if (path == null) return null;
-        File file = new File(path);
-        return file.exists() ? file : null;
+    public Bitmap getImage(BluetoothDevice device, String imageUuid) {
+        if (device == null || imageUuid == null || "".equals(imageUuid)) return null;
+        Map<String, Bitmap> images = mDeviceImages.get(device);
+        if (images == null) return null;
+        return images.get(imageUuid);
     }
 
     /**
      * Add an image to storage
      *
      * @param device - The device the images was downloaded from
-     * @param imageHandle - The handle that identifies the image
+     * @param imageUuid - The UUID that identifies the image
      * @param image - The image
      */
-    public Uri addImage(BluetoothDevice device, String imageHandle, Bitmap image) {
-        debug("Storing image '" + imageHandle + "' from device " + device);
-        if (device == null || imageHandle == null || "".equals(imageHandle) || image == null) {
+    public Uri addImage(BluetoothDevice device, String imageUuid, Bitmap image) {
+        debug("Storing image '" + imageUuid + "' from device " + device);
+        if (device == null || imageUuid == null || "".equals(imageUuid) || image == null) {
             debug("Cannot store image. Improper aruguments");
             return null;
         }
 
-        String path = getImagePath(device, imageHandle);
-        if (path == null) {
-            error("Cannot store image. Cannot provide a valid path to storage");
-            return null;
+        // A Thread safe way of creating a new UUID->Image set for a device. The putIfAbsent()
+        // function will return the value of the key if it wasn't absent. If it returns null, then
+        // there was no value there and we are to assume the reference we passed in was added.
+        Map<String, Bitmap> newImageSet = new ConcurrentHashMap<String, Bitmap>(1);
+        Map<String, Bitmap> images = mDeviceImages.putIfAbsent(device, newImageSet);
+        if (images == null) {
+            newImageSet.put(imageUuid, image);
+        } else {
+            images.put(imageUuid, image);
         }
 
-        try {
-            String deviceDirectoryPath = getDevicePath(device);
-            if (deviceDirectoryPath == null) {
-                error("Cannot store image. Cannot get a valid path to per-device storage");
-                return null;
-            }
-            File deviceDirectory = new File(deviceDirectoryPath);
-            if (!deviceDirectory.exists()) {
-                deviceDirectory.mkdirs();
-            }
-
-            FileOutputStream outputStream = new FileOutputStream(path);
-            image.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
-            outputStream.flush();
-            outputStream.close();
-        } catch (IOException e) {
-            error("Failed to store '" + imageHandle + "' to '" + path + "'");
-            return null;
-        }
-        Uri uri = AvrcpCoverArtProvider.getImageUri(device, imageHandle);
+        Uri uri = AvrcpCoverArtProvider.getImageUri(device, imageUuid);
         mContext.getContentResolver().notifyChange(uri, null);
-        debug("Image stored at '" + path + "'");
+        debug("Image '" + imageUuid + "' stored for device '" + device.getAddress() + "'");
         return uri;
     }
 
     /**
      * Remove a specific image
      *
-     * @param device The device you wish to have images removed for
-     * @param imageHandle The handle that identifies the image to delete
+     * @param device The device the image belongs to
+     * @param imageUuid - The UUID that identifies the image
      */
-    public void removeImage(BluetoothDevice device, String imageHandle) {
-        debug("Removing image '" + imageHandle + "' from device " + device);
-        if (device == null || imageHandle == null || "".equals(imageHandle)) return;
-        String path = getImagePath(device, imageHandle);
-        if (path == null) {
-            error("Cannot remove image. Cannot get a valid path to storage");
+    public void removeImage(BluetoothDevice device, String imageUuid) {
+        debug("Removing image '" + imageUuid + "' from device " + device);
+        if (device == null || imageUuid == null || "".equals(imageUuid)) return;
+
+        Map<String, Bitmap> images = mDeviceImages.get(device);
+        if (images == null) {
             return;
         }
-        File file = new File(path);
-        if (!file.exists()) return;
-        file.delete();
-        debug("Image deleted at '" + path + "'");
+
+        images.remove(imageUuid);
+        if (images.size() == 0) {
+            mDeviceImages.remove(device);
+        }
+
+        debug("Image '" + imageUuid + "' removed for device '" + device.getAddress() + "'");
     }
 
     /**
@@ -145,91 +139,27 @@
     public void removeImagesForDevice(BluetoothDevice device) {
         if (device == null) return;
         debug("Remove cover art for device " + device.getAddress());
-        String deviceDirectoryPath = getDevicePath(device);
-        if (deviceDirectoryPath == null) {
-            error("Cannot remove images for device. Cannot get a valid path to storage");
-            return;
-        }
-        File deviceDirectory = new File(deviceDirectoryPath);
-        deleteStorageDirectory(deviceDirectory);
+        mDeviceImages.remove(device);
     }
 
     /**
      * Clear the entirety of storage
      */
     public void clear() {
-        String storageDirectoryPath = getStorageDirectory();
-        if (storageDirectoryPath == null) {
-            error("Cannot remove images, cannot get a valid path to storage. Is it mounted?");
-            return;
-        }
-        File storageDirectory = new File(storageDirectoryPath);
-        deleteStorageDirectory(storageDirectory);
-    }
-
-    private String getStorageDirectory() {
-        String dir = null;
-        if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
-            dir = mContext.getExternalFilesDir(null).getAbsolutePath() + "/coverart";
-        } else {
-            error("Cannot get storage directory, state=" + Environment.getExternalStorageState());
-        }
-        return dir;
-    }
-
-    private String getDevicePath(BluetoothDevice device) {
-        String storageDir = getStorageDirectory();
-        if (storageDir == null) return null;
-        return storageDir + "/" + device.getAddress().replace(":", "");
-    }
-
-    private String getImagePath(BluetoothDevice device, String imageHandle) {
-        String deviceDir = getDevicePath(device);
-        if (deviceDir == null) return null;
-        return deviceDir + "/" + imageHandle + ".png";
-    }
-
-    private void deleteStorageDirectory(File directory) {
-        if (directory == null) {
-            error("Cannot delete directory, file is null");
-            return;
-        }
-        if (!directory.exists()) return;
-        File[] files = directory.listFiles();
-        if (files == null) {
-            return;
-        }
-        for (int i = 0; i < files.length; i++) {
-            debug("Deleting " + files[i].getAbsolutePath());
-            if (files[i].isDirectory()) {
-                deleteStorageDirectory(files[i]);
-            } else {
-                files[i].delete();
-            }
-        }
-        directory.delete();
+        debug("Clearing all images");
+        mDeviceImages.clear();
     }
 
     @Override
     public String toString() {
         String s = "CoverArtStorage:\n";
-        String storageDirectory = getStorageDirectory();
-        s += "    Storage Directory: " + storageDirectory + "\n";
-        if (storageDirectory == null) {
-            return s;
-        }
-
-        File storage = new File(storageDirectory);
-        File[] devices = storage.listFiles();
-        if (devices != null) {
-            for (File deviceDirectory : devices) {
-                s += "    " + deviceDirectory.getName() + ":\n";
-                File[] images = deviceDirectory.listFiles();
-                if (images == null) continue;
-                for (File image : images) {
-                    s += "      " + image.getName() + "\n";
-                }
+        for (BluetoothDevice device : mDeviceImages.keySet()) {
+            Map<String, Bitmap> images = mDeviceImages.get(device);
+            s += "  " + device.getAddress() + " (" + images.size() + "):";
+            for (String uuid : images.keySet()) {
+                s += "\n    " + uuid;
             }
+            s += "\n";
         }
         return s;
     }
diff --git a/src/com/android/bluetooth/avrcpcontroller/BluetoothMediaBrowserService.java b/src/com/android/bluetooth/avrcpcontroller/BluetoothMediaBrowserService.java
index ea9b256..26bec40 100644
--- a/src/com/android/bluetooth/avrcpcontroller/BluetoothMediaBrowserService.java
+++ b/src/com/android/bluetooth/avrcpcontroller/BluetoothMediaBrowserService.java
@@ -112,8 +112,9 @@
         Intent launchIntent = new Intent();
         launchIntent.setAction(BluetoothPrefs.BLUETOOTH_SETTING_ACTION);
         launchIntent.addCategory(BluetoothPrefs.BLUETOOTH_SETTING_CATEGORY);
+        int flags = PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE;
         PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0,
-                launchIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+                launchIntent, flags);
         extras.putParcelable(ERROR_RESOLUTION_ACTION_INTENT, pendingIntent);
         PlaybackStateCompat errorState = new PlaybackStateCompat.Builder()
                 .setErrorMessage(getString(R.string.bluetooth_disconnected))
diff --git a/src/com/android/bluetooth/btservice/AdapterService.java b/src/com/android/bluetooth/btservice/AdapterService.java
index cb64b87..1bd0f9d 100644
--- a/src/com/android/bluetooth/btservice/AdapterService.java
+++ b/src/com/android/bluetooth/btservice/AdapterService.java
@@ -167,6 +167,8 @@
 
     private final ArrayList<DiscoveringPackage> mDiscoveringPackages = new ArrayList<>();
 
+    private static final int TYPE_BREDR = 100;
+
     static {
         classInitNative();
     }
@@ -1086,6 +1088,22 @@
             BluetoothAdapter.getDefaultAdapter().disableBluetoothGetStateCache();
         }
 
+        // TODO(b/140404592): Either implement these custom methods, or remove them from IBluetooth.
+        @Override
+        public void setBondingInitiatedLocally(BluetoothDevice device, boolean localInitiated) {}
+        @Override
+        public boolean isTwsPlusDevice(BluetoothDevice device) { return false; }
+        @Override
+        public String getTwsPlusPeerAddress(BluetoothDevice device) { return null; }
+        @Override
+        public void updateQuietModeStatus(boolean quietMode) {}
+        @Override
+        public int setSocketOpt(int type, int port, int optionName, byte [] optionVal, int optionLen) { return -1; }
+        @Override
+        public int getSocketOpt(int type, int port, int optionName, byte [] optionVal) { return -1; }
+        @Override
+        public int getDeviceType(BluetoothDevice device) { return TYPE_BREDR; }
+
         public void cleanup() {
             mService = null;
         }
@@ -1586,6 +1604,11 @@
         }
 
         @Override
+        public boolean isBroadcastActive() {
+            return false;
+        }
+
+        @Override
         public int getRemoteType(BluetoothDevice device) {
             AdapterService service = getService();
             if (service == null || !callerIsSystemOrActiveOrManagedUser(service, TAG, "getRemoteType")) {
diff --git a/src/com/android/bluetooth/btservice/BondStateMachine.java b/src/com/android/bluetooth/btservice/BondStateMachine.java
index 88bb197..8b42678 100644
--- a/src/com/android/bluetooth/btservice/BondStateMachine.java
+++ b/src/com/android/bluetooth/btservice/BondStateMachine.java
@@ -23,6 +23,7 @@
 import android.bluetooth.BluetoothProtoEnums;
 import android.bluetooth.OobData;
 import android.content.Intent;
+import android.os.Build;
 import android.os.Message;
 import android.os.UserHandle;
 import android.util.Log;
@@ -459,7 +460,7 @@
             mRemoteDevices.addDeviceProperties(address);
         }
         infoLog("sspRequestCallback: " + address + " name: " + name + " cod: " + cod
-                + " pairingVariant " + pairingVariant + " passkey: " + passkey);
+                + " pairingVariant " + pairingVariant + " passkey: " + (Build.IS_DEBUGGABLE ? passkey : "******"));
         int variant;
         boolean displayPasskey = false;
         switch (pairingVariant) {
diff --git a/src/com/android/bluetooth/gatt/GattService.java b/src/com/android/bluetooth/gatt/GattService.java
index 8a792fe..3da249d 100644
--- a/src/com/android/bluetooth/gatt/GattService.java
+++ b/src/com/android/bluetooth/gatt/GattService.java
@@ -440,12 +440,13 @@
         }
 
         @Override
-        public void registerClient(ParcelUuid uuid, IBluetoothGattCallback callback) {
+        public void registerClient(ParcelUuid uuid, IBluetoothGattCallback callback,
+                boolean eattSupport) {
             GattService service = getService();
             if (service == null) {
                 return;
             }
-            service.registerClient(uuid.getUuid(), callback);
+            service.registerClient(uuid.getUuid(), callback, eattSupport);
         }
 
         @Override
@@ -713,12 +714,13 @@
         }
 
         @Override
-        public void registerServer(ParcelUuid uuid, IBluetoothGattServerCallback callback) {
+        public void registerServer(ParcelUuid uuid, IBluetoothGattServerCallback callback,
+                boolean eattSupport) {
             GattService service = getService();
             if (service == null) {
                 return;
             }
-            service.registerServer(uuid.getUuid(), callback);
+            service.registerServer(uuid.getUuid(), callback, eattSupport);
         }
 
         @Override
@@ -923,6 +925,25 @@
         }
 
         @Override
+        public void transferSync(BluetoothDevice bda, int service_data , int sync_handle) {
+            GattService service = getService();
+            if (service == null) {
+                return;
+            }
+            service.transferSync(bda, service_data , sync_handle);
+        }
+
+        @Override
+        public void transferSetInfo(BluetoothDevice bda, int service_data , int adv_handle,
+                IPeriodicAdvertisingCallback callback) {
+            GattService service = getService();
+            if (service == null) {
+                return;
+            }
+            service.transferSetInfo(bda, service_data , adv_handle, callback);
+        }
+
+        @Override
         public void unregisterSync(IPeriodicAdvertisingCallback callback) {
             GattService service = getService();
             if (service == null) {
@@ -2288,6 +2309,16 @@
         mPeriodicScanManager.stopSync(callback);
     }
 
+    void transferSync(BluetoothDevice bda, int service_data, int sync_handle) {
+        enforceAdminPermission();
+        mPeriodicScanManager.transferSync(bda, service_data, sync_handle);
+    }
+
+    void transferSetInfo(BluetoothDevice bda, int service_data,
+                  int adv_handle, IPeriodicAdvertisingCallback callback) {
+        enforceAdminPermission();
+        mPeriodicScanManager.transferSetInfo(bda, service_data, adv_handle, callback);
+    }
     /**************************************************************************
      * ADVERTISING SET
      *************************************************************************/
@@ -2350,14 +2381,16 @@
      * GATT Service functions - CLIENT
      *************************************************************************/
 
-    void registerClient(UUID uuid, IBluetoothGattCallback callback) {
+    void registerClient(UUID uuid, IBluetoothGattCallback callback,
+            boolean eattSupport) {
         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
 
         if (DBG) {
             Log.d(TAG, "registerClient() - UUID=" + uuid);
         }
         mClientMap.add(uuid, null, callback, null, this);
-        gattClientRegisterAppNative(uuid.getLeastSignificantBits(), uuid.getMostSignificantBits());
+        gattClientRegisterAppNative(uuid.getLeastSignificantBits(), uuid.getMostSignificantBits(),
+                                    eattSupport);
     }
 
     void unregisterClient(int clientIf) {
@@ -3015,14 +3048,15 @@
      * GATT Service functions - SERVER
      *************************************************************************/
 
-    void registerServer(UUID uuid, IBluetoothGattServerCallback callback) {
+    void registerServer(UUID uuid, IBluetoothGattServerCallback callback, boolean eattSupport) {
         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
 
         if (DBG) {
             Log.d(TAG, "registerServer() - UUID=" + uuid);
         }
         mServerMap.add(uuid, null, callback, null, this);
-        gattServerRegisterAppNative(uuid.getLeastSignificantBits(), uuid.getMostSignificantBits());
+        gattServerRegisterAppNative(uuid.getLeastSignificantBits(), uuid.getMostSignificantBits(),
+                                    eattSupport);
     }
 
     void unregisterServer(int serverIf) {
@@ -3431,7 +3465,8 @@
 
     private native int gattClientGetDeviceTypeNative(String address);
 
-    private native void gattClientRegisterAppNative(long appUuidLsb, long appUuidMsb);
+    private native void gattClientRegisterAppNative(long appUuidLsb, long appUuidMsb,
+            boolean eattSupport);
 
     private native void gattClientUnregisterAppNative(int clientIf);
 
@@ -3481,7 +3516,8 @@
             int minInterval, int maxInterval, int latency, int timeout, int minConnectionEventLen,
             int maxConnectionEventLen);
 
-    private native void gattServerRegisterAppNative(long appUuidLsb, long appUuidMsb);
+    private native void gattServerRegisterAppNative(long appUuidLsb, long appUuidMsb,
+            boolean eattSupport);
 
     private native void gattServerUnregisterAppNative(int serverIf);
 
diff --git a/src/com/android/bluetooth/gatt/PeriodicScanManager.java b/src/com/android/bluetooth/gatt/PeriodicScanManager.java
index c39c6f0..0589b58 100644
--- a/src/com/android/bluetooth/gatt/PeriodicScanManager.java
+++ b/src/com/android/bluetooth/gatt/PeriodicScanManager.java
@@ -26,10 +26,12 @@
 import android.util.Log;
 
 import com.android.bluetooth.btservice.AdapterService;
-
+import android.bluetooth.BluetoothAdapter;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
+import android.bluetooth.BluetoothDevice;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * Manages Bluetooth LE Periodic scans
@@ -41,9 +43,12 @@
     private static final String TAG = GattServiceConfig.TAG_PREFIX + "SyncManager";
 
     private final AdapterService mAdapterService;
-    Map<IBinder, SyncInfo> mSyncs = Collections.synchronizedMap(new HashMap<>());
+    private final BluetoothAdapter mAdapter;
+    Map<IBinder, SyncInfo> mSyncs = new ConcurrentHashMap<>();
+    Map<IBinder, SyncTransferInfo> mSyncTransfers = Collections.synchronizedMap(new HashMap<>());
     static int sTempRegistrationId = -1;
-
+    private int PA_SOURCE_LOCAL = 1;
+    private int PA_SOURCE_REMOTE = 2;
     /**
      * Constructor of {@link SyncManager}.
      */
@@ -52,6 +57,7 @@
             Log.d(TAG, "advertise manager created");
         }
         mAdapterService = adapterService;
+        mAdapter = BluetoothAdapter.getDefaultAdapter();
     }
 
     void start() {
@@ -67,21 +73,49 @@
         sTempRegistrationId = -1;
     }
 
+    class SyncTransferInfo {
+        public String address;
+        public SyncDeathRecipient deathRecipient;
+        public IPeriodicAdvertisingCallback callback;
+
+        SyncTransferInfo(String address, IPeriodicAdvertisingCallback callback) {
+            this.address = address;
+            this.callback = callback;
+        }
+    }
     class SyncInfo {
         /* When id is negative, the registration is ongoing. When the registration finishes, id
          * becomes equal to sync_handle */
         public Integer id;
+        public Integer adv_sid;
+        public String address;
+        public Integer skip;
+        public Integer timeout;
         public SyncDeathRecipient deathRecipient;
         public IPeriodicAdvertisingCallback callback;
 
-        SyncInfo(Integer id, SyncDeathRecipient deathRecipient,
+        SyncInfo(Integer id, Integer adv_sid, String address, Integer skip, Integer timeout,
+                SyncDeathRecipient deathRecipient,
                 IPeriodicAdvertisingCallback callback) {
             this.id = id;
+            this.adv_sid = adv_sid;
+            this.address = address;
+            this.skip = skip;
+            this.timeout = timeout;
             this.deathRecipient = deathRecipient;
             this.callback = callback;
         }
     }
-
+    Map.Entry<IBinder, SyncTransferInfo> findSyncTransfer(String address) {
+        Map.Entry<IBinder, SyncTransferInfo> entry = null;
+        for (Map.Entry<IBinder, SyncTransferInfo> e : mSyncTransfers.entrySet()) {
+            if (e.getValue().address.equals(address)) {
+                entry = e;
+                break;
+            }
+        }
+        return entry;
+    }
     IBinder toBinder(IPeriodicAdvertisingCallback e) {
         return ((IInterface) e).asBinder();
     }
@@ -113,6 +147,25 @@
         return entry;
     }
 
+    Map.Entry<IBinder, SyncInfo> findMatchingSync(int adv_sid, String address) {
+        Map.Entry<IBinder, SyncInfo> entry = null;
+        for (Map.Entry<IBinder, SyncInfo> e : mSyncs.entrySet()) {
+            if (e.getValue().adv_sid == adv_sid && e.getValue().address.equals(address)) {
+                return entry = e;
+            }
+        }
+        return entry;
+    }
+    Map<IBinder, SyncInfo> findAllSync(int syncHandle) {
+        Map <IBinder, SyncInfo> syncMap = new HashMap<IBinder, SyncInfo>();
+        for (Map.Entry<IBinder, SyncInfo> e : mSyncs.entrySet()) {
+            if (e.getValue().id == syncHandle) {
+                syncMap.put(e.getKey(),new SyncInfo(e.getValue().id, e.getValue().adv_sid, e.getValue().address,
+                e.getValue().skip, e.getValue().timeout, e.getValue().deathRecipient, e.getValue().callback));
+            }
+        }
+        return syncMap;
+    }
     void onSyncStarted(int regId, int syncHandle, int sid, int addressType, String address, int phy,
             int interval, int status) throws Exception {
         if (DBG) {
@@ -120,61 +173,72 @@
                     "onSyncStarted() - regId=" + regId + ", syncHandle=" + syncHandle + ", status="
                             + status);
         }
-
-        Map.Entry<IBinder, SyncInfo> entry = findSync(regId);
-        if (entry == null) {
-            Log.i(TAG, "onSyncStarted() - no callback found for regId " + regId);
-            // Sync was stopped before it was properly registered.
+        Map<IBinder, SyncInfo> syncMap = findAllSync(regId);
+        if (syncMap.size() == 0) {
+            Log.d(TAG,"onSyncStarted() - no callback found for regId " + regId);
             stopSyncNative(syncHandle);
             return;
         }
 
-        IPeriodicAdvertisingCallback callback = entry.getValue().callback;
-        if (status == 0) {
-            entry.setValue(new SyncInfo(syncHandle, entry.getValue().deathRecipient, callback));
-        } else {
-            IBinder binder = entry.getKey();
-            binder.unlinkToDeath(entry.getValue().deathRecipient, 0);
-            mSyncs.remove(binder);
+        synchronized (mSyncs) {
+            for (Map.Entry<IBinder, SyncInfo> e : mSyncs.entrySet()) {
+                if (e.getValue().id == regId) {
+                    IPeriodicAdvertisingCallback callback = e.getValue().callback;
+                    if (status == 0) {
+                        Log.d(TAG,"onSyncStarted: updating id with syncHandle " + syncHandle);
+                        e.setValue(new SyncInfo(syncHandle, sid, address, e.getValue().skip,
+                            e.getValue().timeout, e.getValue().deathRecipient, callback));
+                        callback.onSyncEstablished(syncHandle, mAdapter.getRemoteDevice(address),
+                                           sid, e.getValue().skip, e.getValue().timeout, status);
+                    } else {
+                        callback.onSyncEstablished(syncHandle, mAdapter.getRemoteDevice(address),
+                                           sid, e.getValue().skip, e.getValue().timeout, status);
+                        IBinder binder = e.getKey();
+                        binder.unlinkToDeath(e.getValue().deathRecipient, 0);
+                        mSyncs.remove(binder);
+                    }
+                }
+            }
         }
-
-        // TODO: fix callback arguments
-        // callback.onSyncStarted(syncHandle, tx_power, status);
     }
-
     void onSyncReport(int syncHandle, int txPower, int rssi, int dataStatus, byte[] data)
             throws Exception {
         if (DBG) {
             Log.d(TAG, "onSyncReport() - syncHandle=" + syncHandle);
         }
 
-        Map.Entry<IBinder, SyncInfo> entry = findSync(syncHandle);
-        if (entry == null) {
+        Map<IBinder, SyncInfo> syncMap = findAllSync(syncHandle);
+        if (syncMap.size() == 0) {
             Log.i(TAG, "onSyncReport() - no callback found for syncHandle " + syncHandle);
             return;
         }
-
-        IPeriodicAdvertisingCallback callback = entry.getValue().callback;
-        PeriodicAdvertisingReport report =
-                new PeriodicAdvertisingReport(syncHandle, txPower, rssi, dataStatus,
-                        ScanRecord.parseFromBytes(data));
-        callback.onPeriodicAdvertisingReport(report);
+        for (Map.Entry<IBinder, SyncInfo> e :syncMap.entrySet()) {
+            IPeriodicAdvertisingCallback callback = e.getValue().callback;
+            PeriodicAdvertisingReport report =
+                    new PeriodicAdvertisingReport(syncHandle, txPower, rssi, dataStatus,
+                            ScanRecord.parseFromBytes(data));
+            callback.onPeriodicAdvertisingReport(report);
+        }
     }
 
     void onSyncLost(int syncHandle) throws Exception {
         if (DBG) {
             Log.d(TAG, "onSyncLost() - syncHandle=" + syncHandle);
         }
-
-        Map.Entry<IBinder, SyncInfo> entry = findSync(syncHandle);
-        if (entry == null) {
+        Map<IBinder, SyncInfo> syncMap = findAllSync(syncHandle);
+        if (syncMap.size() == 0) {
             Log.i(TAG, "onSyncLost() - no callback found for syncHandle " + syncHandle);
             return;
         }
+        for (Map.Entry<IBinder, SyncInfo> e :syncMap.entrySet()) {
+            IPeriodicAdvertisingCallback callback = e.getValue().callback;
+            IBinder binder = toBinder(callback);
+            synchronized(mSyncs) {
+                mSyncs.remove(binder);
+            }
+            callback.onSyncLost(syncHandle);
 
-        IPeriodicAdvertisingCallback callback = entry.getValue().callback;
-        mSyncs.remove(entry);
-        callback.onSyncLost(syncHandle);
+        }
     }
 
     void startSync(ScanResult scanResult, int skip, int timeout,
@@ -189,9 +253,34 @@
 
         String address = scanResult.getDevice().getAddress();
         int sid = scanResult.getAdvertisingSid();
+        if (DBG) {
+            Log.d(TAG,"startSync for Device: " + address + " sid: " + sid);
+        }
+        synchronized(mSyncs) {
+            Map.Entry<IBinder, SyncInfo> entry = findMatchingSync(sid, address);
+            if (entry != null) {
+                //Found matching sync. Copy sync handle
+                if (DBG) {
+                    Log.d(TAG,"startSync: Matching entry found");
+                }
+                mSyncs.put(binder, new SyncInfo(entry.getValue().id, sid, address, entry.getValue().skip,
+                           entry.getValue().timeout, deathRecipient, callback));
+                if (entry.getValue().id >= 0) {
+                    try {
+                        callback.onSyncEstablished(entry.getValue().id, mAdapter.getRemoteDevice(address),
+                                 sid, entry.getValue().skip, entry.getValue().timeout, 0 /*success*/);
+                    } catch (RemoteException e) {
+                        throw new IllegalArgumentException("Can't invoke callback");
+                    }
+                } else {
+                   Log.d(TAG, "startSync(): sync pending for same remote");
+                }
+                return;
+            }
+        }
 
         int cbId = --sTempRegistrationId;
-        mSyncs.put(binder, new SyncInfo(cbId, deathRecipient, callback));
+        mSyncs.put(binder, new SyncInfo(cbId, sid, address, skip, timeout, deathRecipient, callback));
 
         if (DBG) {
             Log.d(TAG, "startSync() - reg_id=" + cbId + ", callback: " + binder);
@@ -204,8 +293,10 @@
         if (DBG) {
             Log.d(TAG, "stopSync() " + binder);
         }
-
-        SyncInfo sync = mSyncs.remove(binder);
+        SyncInfo sync = null;
+        synchronized(mSyncs) {
+            sync = mSyncs.remove(binder);
+        }
         if (sync == null) {
             Log.e(TAG, "stopSync() - no client found for callback");
             return;
@@ -213,14 +304,62 @@
 
         Integer syncHandle = sync.id;
         binder.unlinkToDeath(sync.deathRecipient, 0);
+        Log.d(TAG,"stopSync: " + syncHandle);
 
-        if (syncHandle < 0) {
-            Log.i(TAG, "stopSync() - not finished registration yet");
-            // Sync will be freed once initiated in onSyncStarted()
-            return;
+        synchronized(mSyncs) {
+            Map.Entry<IBinder, SyncInfo> entry = findSync(syncHandle);
+            if (entry != null) {
+                Log.d(TAG,"stopSync() - another app synced to same PA, not stopping sync");
+                return;
+            }
         }
+        Log.d(TAG,"calling stopSyncNative: " + syncHandle.intValue());
+        if (syncHandle < 0) {
+            Log.i(TAG, "cancelSync() - sync not established yet");
+            cancelSyncNative(sync.adv_sid, sync.address);
+        } else {
+            stopSyncNative(syncHandle.intValue());
+        }
+    }
 
-        stopSyncNative(syncHandle);
+    void onSyncTransferedCallback(int pa_source, int status, String bda) {
+        Log.d(TAG, "onSyncTransferedCallback()");
+        Map.Entry<IBinder, SyncTransferInfo>entry = findSyncTransfer(bda);
+        if (entry != null) {
+            mSyncTransfers.remove(entry);
+            IPeriodicAdvertisingCallback callback = entry.getValue().callback;
+            try {
+                callback.onSyncTransfered(mAdapter.getRemoteDevice(bda), status);
+            } catch (RemoteException e) {
+                throw new IllegalArgumentException("Can't find callback for sync transfer");
+            }
+        }
+    }
+    void transferSync(BluetoothDevice bda, int service_data, int sync_handle) {
+        Log.d(TAG, "transferSync()");
+        Map.Entry<IBinder, SyncInfo> entry = findSync(sync_handle);
+        if (entry == null) {
+            Log.d(TAG,"transferSync: callback not registered");
+        }
+        //check for duplicate transfers
+        mSyncTransfers.put(entry.getKey(), new SyncTransferInfo(bda.getAddress(), entry.getValue().callback));
+        syncTransferNative(PA_SOURCE_REMOTE, bda.getAddress(), service_data, sync_handle);
+    }
+
+    void transferSetInfo(BluetoothDevice bda, int service_data,
+                  int adv_handle, IPeriodicAdvertisingCallback callback) {
+        SyncDeathRecipient deathRecipient = new SyncDeathRecipient(callback);
+        IBinder binder = toBinder(callback);
+        if (DBG) {
+            Log.d(TAG, "transferSetInfo() " + binder);
+        }
+        try {
+            binder.linkToDeath(deathRecipient, 0);
+        } catch (RemoteException e) {
+            throw new IllegalArgumentException("Can't link to periodic scanner death");
+        }
+        mSyncTransfers.put(binder, new SyncTransferInfo(bda.getAddress(), callback));
+        TransferSetInfoNative(PA_SOURCE_LOCAL, bda.getAddress(), service_data, adv_handle);
     }
 
     static {
@@ -236,4 +375,10 @@
     private native void startSyncNative(int sid, String address, int skip, int timeout, int regId);
 
     private native void stopSyncNative(int syncHandle);
+
+    private native void cancelSyncNative(int sid, String address);
+
+    private native void syncTransferNative(int pa_source, String address, int service_data, int sync_handle);
+
+    private native void TransferSetInfoNative(int pa_source, String address, int service_data, int adv_handle);
 }
diff --git a/src/com/android/bluetooth/map/BluetoothMapContentObserver.java b/src/com/android/bluetooth/map/BluetoothMapContentObserver.java
index d09443e..2c900af 100644
--- a/src/com/android/bluetooth/map/BluetoothMapContentObserver.java
+++ b/src/com/android/bluetooth/map/BluetoothMapContentObserver.java
@@ -1412,7 +1412,8 @@
                     do {
                         int idIndex = c.getColumnIndexOrThrow(Sms._ID);
                         if (c.isNull(idIndex)) {
-                            throw new IllegalStateException("ID is null");
+                            Log.w(TAG, "handleMsgListChangesSms, ID is null");
+                            continue;
                         }
                         long id = c.getLong(idIndex);
                         int type = c.getInt(c.getColumnIndex(Sms.TYPE));
@@ -1572,7 +1573,8 @@
                     do {
                         int idIndex = c.getColumnIndexOrThrow(Mms._ID);
                         if (c.isNull(idIndex)) {
-                            throw new IllegalStateException("ID is null");
+                            Log.w(TAG, "handleMsgListChangesMms, ID is null");
+                            continue;
                         }
                         long id = c.getLong(idIndex);
                         int type = c.getInt(c.getColumnIndex(Mms.MESSAGE_BOX));
diff --git a/src/com/android/bluetooth/opp/BluetoothOppBtEnableActivity.java b/src/com/android/bluetooth/opp/BluetoothOppBtEnableActivity.java
index 8a4d149..6c598dc 100644
--- a/src/com/android/bluetooth/opp/BluetoothOppBtEnableActivity.java
+++ b/src/com/android/bluetooth/opp/BluetoothOppBtEnableActivity.java
@@ -32,6 +32,8 @@
 
 package com.android.bluetooth.opp;
 
+import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+
 import android.bluetooth.AlertActivity;
 import android.content.DialogInterface;
 import android.content.Intent;
@@ -53,6 +55,7 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
+        getWindow().addPrivateFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
         // Set up the "dialog"
         mOppManager = BluetoothOppManager.getInstance(this);
         mOppManager.mSendingFlag = false;
diff --git a/src/com/android/bluetooth/opp/BluetoothOppBtEnablingActivity.java b/src/com/android/bluetooth/opp/BluetoothOppBtEnablingActivity.java
index cde530c..9d8cf32 100644
--- a/src/com/android/bluetooth/opp/BluetoothOppBtEnablingActivity.java
+++ b/src/com/android/bluetooth/opp/BluetoothOppBtEnablingActivity.java
@@ -32,6 +32,8 @@
 
 package com.android.bluetooth.opp;
 
+import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+
 import android.bluetooth.AlertActivity;
 import android.bluetooth.BluetoothAdapter;
 import android.content.BroadcastReceiver;
@@ -68,6 +70,7 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
+        getWindow().addPrivateFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
         // If BT is already enabled jus return.
         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
         if (adapter.isEnabled()) {
diff --git a/src/com/android/bluetooth/opp/BluetoothOppBtErrorActivity.java b/src/com/android/bluetooth/opp/BluetoothOppBtErrorActivity.java
index f78e32d..2d60b5f 100644
--- a/src/com/android/bluetooth/opp/BluetoothOppBtErrorActivity.java
+++ b/src/com/android/bluetooth/opp/BluetoothOppBtErrorActivity.java
@@ -32,6 +32,8 @@
 
 package com.android.bluetooth.opp;
 
+import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+
 import android.bluetooth.AlertActivity;
 import android.content.DialogInterface;
 import android.content.Intent;
@@ -51,6 +53,7 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
+        getWindow().addPrivateFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
         Intent intent = getIntent();
         String errorTitle = intent.getStringExtra("title");
         String errorContent = intent.getStringExtra("content");
diff --git a/src/com/android/bluetooth/opp/BluetoothOppIncomingFileConfirmActivity.java b/src/com/android/bluetooth/opp/BluetoothOppIncomingFileConfirmActivity.java
index 8a887ee..28e6b99 100644
--- a/src/com/android/bluetooth/opp/BluetoothOppIncomingFileConfirmActivity.java
+++ b/src/com/android/bluetooth/opp/BluetoothOppIncomingFileConfirmActivity.java
@@ -32,6 +32,8 @@
 
 package com.android.bluetooth.opp;
 
+import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+
 import android.bluetooth.AlertActivity;
 import android.content.BroadcastReceiver;
 import android.content.ContentValues;
@@ -93,6 +95,7 @@
         }
         super.onCreate(savedInstanceState);
 
+        getWindow().addPrivateFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
         Intent intent = getIntent();
         mUri = intent.getData();
         mTransInfo = new BluetoothOppTransferInfo();
diff --git a/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java b/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java
index 1a15adb..b63bc0c 100644
--- a/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java
+++ b/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java
@@ -32,6 +32,8 @@
 
 package com.android.bluetooth.opp;
 
+import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+
 import android.app.Activity;
 import android.bluetooth.BluetoothDevicePicker;
 import android.content.ContentResolver;
@@ -73,6 +75,7 @@
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
+        getWindow().addPrivateFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
         Intent intent = getIntent();
         String action = intent.getAction();
         if (action == null) {
diff --git a/src/com/android/bluetooth/opp/BluetoothOppNotification.java b/src/com/android/bluetooth/opp/BluetoothOppNotification.java
index 1e92996..5e4ec49 100644
--- a/src/com/android/bluetooth/opp/BluetoothOppNotification.java
+++ b/src/com/android/bluetooth/opp/BluetoothOppNotification.java
@@ -569,7 +569,7 @@
                     mContext.getText(R.string.incoming_file_confirm_ok),
                     PendingIntent.getBroadcast(mContext, 0,
                             new Intent(baseIntent).setAction(Constants.ACTION_ACCEPT), 0)).build();
-            Notification n =
+            Notification public_n =
                     new Notification.Builder(mContext, OPP_NOTIFICATION_CHANNEL).setOnlyAlertOnce(
                             true)
                             .setOngoing(true)
@@ -596,6 +596,33 @@
                             .setSmallIcon(R.drawable.bt_incomming_file_notification)
                             .setLocalOnly(true)
                             .build();
+            Notification n =
+                    new Notification.Builder(mContext, OPP_NOTIFICATION_CHANNEL).setOnlyAlertOnce(
+                            true)
+                            .setOngoing(true)
+                            .setWhen(info.mTimeStamp)
+                            .setContentIntent(PendingIntent.getBroadcast(mContext, 0,
+                                    new Intent(baseIntent).setAction(
+                                            Constants.ACTION_INCOMING_FILE_CONFIRM), 0))
+                            .setDeleteIntent(PendingIntent.getBroadcast(mContext, 0,
+                                    new Intent(baseIntent).setAction(Constants.ACTION_HIDE), 0))
+                            .setColor(mContext.getResources()
+                                    .getColor(
+                                            com.android.internal.R.color
+                                                    .system_notification_accent_color,
+                                            mContext.getTheme()))
+                            .setContentTitle(mContext.getText(
+                                    R.string.incoming_file_confirm_Notification_title))
+                            .setContentText(info.mFileName)
+                            .setStyle(new Notification.BigTextStyle().bigText(mContext.getString(
+                                    R.string.incoming_file_confirm_Notification_content,
+                                    info.mDeviceName, info.mFileName)))
+                            .setSubText(Formatter.formatFileSize(mContext, info.mTotalBytes))
+                            .setSmallIcon(R.drawable.bt_incomming_file_notification)
+                            .setLocalOnly(true)
+                            .setVisibility(Notification.VISIBILITY_PRIVATE)
+                            .setPublicVersion(public_n)
+                            .build();
             mNotificationMgr.notify(NOTIFICATION_ID_PROGRESS, n);
         }
         cursor.close();
diff --git a/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfo.java b/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfo.java
index dfd5b4d..1589988 100644
--- a/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfo.java
+++ b/src/com/android/bluetooth/opp/BluetoothOppReceiveFileInfo.java
@@ -42,6 +42,9 @@
 import android.util.Log;
 
 import java.io.UnsupportedEncodingException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
 
 /**
  * This class stores information about a single receiving file. It will only be
@@ -53,8 +56,8 @@
     private static final boolean V = Constants.VERBOSE;
     private static String sDesiredStoragePath = null;
 
-    /* To truncate the name of the received file if the length exceeds 245 */
-    private static final int OPP_LENGTH_OF_FILE_NAME = 244;
+    /* To truncate the name of the received file if the length exceeds 237 */
+    private static final int OPP_LENGTH_OF_FILE_NAME = 237;
 
 
     /** absolute store file name */
@@ -160,7 +163,9 @@
             }
         }
 
-        String fullfilename = filename + extension;
+        DateFormat dateFormat = new SimpleDateFormat("_hhmmss");
+        String currentTime = dateFormat.format(Calendar.getInstance().getTime());
+        String fullfilename = filename + currentTime + extension;
 
         if (V) {
             Log.v(Constants.TAG, "Generated received filename " + fullfilename);
diff --git a/src/com/android/bluetooth/opp/BluetoothOppTransferActivity.java b/src/com/android/bluetooth/opp/BluetoothOppTransferActivity.java
index 2272936..73a7a61 100644
--- a/src/com/android/bluetooth/opp/BluetoothOppTransferActivity.java
+++ b/src/com/android/bluetooth/opp/BluetoothOppTransferActivity.java
@@ -32,6 +32,8 @@
 
 package com.android.bluetooth.opp;
 
+import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+
 import android.app.NotificationManager;
 import android.bluetooth.AlertActivity;
 import android.bluetooth.BluetoothAdapter;
@@ -129,6 +131,8 @@
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+
+        getWindow().addPrivateFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
         Intent intent = getIntent();
         mUri = intent.getData();
 
diff --git a/src/com/android/bluetooth/pan/PanService.java b/src/com/android/bluetooth/pan/PanService.java
index 11c2abb..ffaf1ce 100644
--- a/src/com/android/bluetooth/pan/PanService.java
+++ b/src/com/android/bluetooth/pan/PanService.java
@@ -61,6 +61,13 @@
     private static final boolean DBG = false;
     private static PanService sPanService;
 
+    private static final String ACTION_TETHERING_STATE_CHANGED =
+            "android.bluetooth.pan.profile.action.TETHERING_STATE_CHANGED";
+    private static final String EXTRA_TETHERING_STATE =
+            "android.bluetooth.pan.extra.TETHERING_STATE";
+    private static final int TETHERING_STATE_OFF = 1;
+    private static final int TETHERING_STATE_ON = 2;
+
     private static final String BLUETOOTH_IFACE_ADDR_START = "192.168.44.1";
     private static final int BLUETOOTH_MAX_PAN_CONNECTIONS = 5;
     private static final int BLUETOOTH_PREFIX_LENGTH = 24;
@@ -411,6 +418,10 @@
             for (BluetoothDevice dev : devList) {
                 disconnect(dev);
             }
+            Intent intent = new Intent(ACTION_TETHERING_STATE_CHANGED);
+            intent.putExtra(EXTRA_TETHERING_STATE,
+                    mTetherOn ? TETHERING_STATE_ON : TETHERING_STATE_OFF);
+            sendBroadcast(intent, BLUETOOTH_PERM);
         }
     }
 
diff --git a/src/com/android/bluetooth/pbap/BluetoothPbapActivity.java b/src/com/android/bluetooth/pbap/BluetoothPbapActivity.java
index 3da71e0..000dd00 100644
--- a/src/com/android/bluetooth/pbap/BluetoothPbapActivity.java
+++ b/src/com/android/bluetooth/pbap/BluetoothPbapActivity.java
@@ -32,6 +32,8 @@
 
 package com.android.bluetooth.pbap;
 
+import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+
 import android.bluetooth.AlertActivity;
 import android.bluetooth.BluetoothDevice;
 import android.content.BroadcastReceiver;
@@ -102,6 +104,8 @@
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+
+        getWindow().addPrivateFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
         Intent i = getIntent();
         String action = i.getAction();
         mDevice = i.getParcelableExtra(BluetoothPbapService.EXTRA_DEVICE);
diff --git a/tests/robotests/Android.mk b/tests/robotests/Android.mk
index 0cb6917..678ab4b 100644
--- a/tests/robotests/Android.mk
+++ b/tests/robotests/Android.mk
@@ -1,3 +1,5 @@
+ifneq ($(TARGET_USE_QTI_BT_STACK),true)
+
 #############################################################
 # Bluetooth Robolectric test target.                        #
 #############################################################
@@ -45,3 +47,5 @@
 LOCAL_INSTRUMENT_SOURCE_DIRS := $(dir $(LOCAL_PATH))../src
 
 include external/robolectric-shadows/run_robotests.mk
+
+endif
diff --git a/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtStorageTest.java b/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtStorageTest.java
index 370a40b..63be7c2 100644
--- a/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtStorageTest.java
+++ b/tests/unit/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtStorageTest.java
@@ -34,7 +34,6 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.io.File;
 import java.io.InputStream;
 
 /**
@@ -89,9 +88,8 @@
     }
 
     private void assertImageSame(Bitmap expected, BluetoothDevice device, String handle) {
-        File file = mAvrcpCoverArtStorage.getImageFile(device, handle);
-        Bitmap fromStorage = BitmapFactory.decodeFile(file.getPath());
-        Assert.assertTrue(expected.sameAs(fromStorage));
+        Bitmap image = mAvrcpCoverArtStorage.getImage(device, handle);
+        Assert.assertTrue(expected.sameAs(image));
     }
 
     @Test
@@ -203,29 +201,29 @@
     @Test
     public void getImageThatDoesntExist_returnsNull() {
         Assert.assertFalse(mAvrcpCoverArtStorage.doesImageExist(mDevice1, mHandle1));
-        File file = mAvrcpCoverArtStorage.getImageFile(mDevice1, mHandle1);
-        Assert.assertEquals(null, file);
+        Bitmap image = mAvrcpCoverArtStorage.getImage(mDevice1, mHandle1);
+        Assert.assertEquals(null, image);
     }
 
     @Test
     public void getImageNullDevice_returnsNull() {
         Assert.assertFalse(mAvrcpCoverArtStorage.doesImageExist(mDevice1, mHandle1));
-        File file = mAvrcpCoverArtStorage.getImageFile(null, mHandle1);
-        Assert.assertEquals(null, file);
+        Bitmap image = mAvrcpCoverArtStorage.getImage(null, mHandle1);
+        Assert.assertEquals(null, image);
     }
 
     @Test
     public void getImageNullHandle_returnsNull() {
         Assert.assertFalse(mAvrcpCoverArtStorage.doesImageExist(mDevice1, mHandle1));
-        File file = mAvrcpCoverArtStorage.getImageFile(mDevice1, null);
-        Assert.assertEquals(null, file);
+        Bitmap image = mAvrcpCoverArtStorage.getImage(mDevice1, null);
+        Assert.assertEquals(null, image);
     }
 
     @Test
     public void getImageEmptyHandle_returnsNull() {
         Assert.assertFalse(mAvrcpCoverArtStorage.doesImageExist(mDevice1, mHandle1));
-        File file = mAvrcpCoverArtStorage.getImageFile(mDevice1, "");
-        Assert.assertEquals(null, file);
+        Bitmap image = mAvrcpCoverArtStorage.getImage(mDevice1, "");
+        Assert.assertEquals(null, image);
     }
 
     @Test