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